diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..9fc41ea1c4 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +root = true + +[*] +end_of_line = lf +insert_final_newline = true + +[Makefile] +indent_style = tab + +[*.{html,js,json,md,sass,scss,yaml}] +indent_style = space +indent_size = 2 diff --git a/.gitignore b/.gitignore index 42b82280ec..ce06c280df 100644 --- a/.gitignore +++ b/.gitignore @@ -2,12 +2,25 @@ .jekyll-metadata rootfs/svc .sass-cache/ +.yarnclean _site/* _site/ +.hugo_build.lock +.ncurc.yml +.publish/* +.publish/ node_modules/ bower_components/ vendor/ -source/* -javascripts/*.min.js -docs.helm.sh/app -docs.helm.sh/source +rootfs/ +app/* +resources/ +helm.sh/ +docs.helm.sh/ + +# JetBrains IDEs (GoLand, IntelliJ, ...) config folder +.idea + +# Link checker artifacts +bin/ +tmp/ diff --git a/.htmltest.yml b/.htmltest.yml new file mode 100644 index 0000000000..5ce060cd81 --- /dev/null +++ b/.htmltest.yml @@ -0,0 +1,4 @@ +DirectoryPath: app +IgnoreDirectoryMissingTrailingSlash: true +CheckExternal: false +IgnoreAltMissing: true diff --git a/.markdownlint.json b/.markdownlint.json new file mode 100644 index 0000000000..315bbfc228 --- /dev/null +++ b/.markdownlint.json @@ -0,0 +1,11 @@ +{ + "default": true, + "MD013": { + "code_block_line_length": 999, + "tables": false + }, + "MD014": false, + "MD025": false, + "MD026": false, + "MD033": false +} diff --git a/.netlify/state.json b/.netlify/state.json new file mode 100644 index 0000000000..497da019af --- /dev/null +++ b/.netlify/state.json @@ -0,0 +1,3 @@ +{ + "siteId": "bbe72dce-fa74-4199-abb2-6bdfe2b4d08c" +} \ No newline at end of file diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000000..1047f69681 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +10.15.1 diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000000..6f3c990b6a --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,15 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "chrome", + "request": "launch", + "name": "Launch Chrome against localhost", + "url": "http://localhost:8080", + "webRoot": "${workspaceFolder}" + } + ] +} \ No newline at end of file diff --git a/CONTRIBUTING-ko.md b/CONTRIBUTING-ko.md new file mode 100644 index 0000000000..67bbd7003c --- /dev/null +++ b/CONTRIBUTING-ko.md @@ -0,0 +1,269 @@ +# 기여 가이드라인 + +helm.sh 웹사이트 및 문서에 대한 기여 가이드입니다. 헬름의 기본 프로젝트는 [helm/helm](https://github.com/helm/helm/blob/main/CONTRIBUTING.md)으로 이동하세요. + +--- + +헬름은 GitHub 풀 리퀘스트를 통해 기여를 받습니다. 이 문서는 기여하는 데 도움이 되는 프로세스를 간략히 설명합니다. + +## 보안 이슈 신고 + +대부분의 경우 헬름에서 버그를 발견하면 [GitHub 이슈](https://github.com/helm/helm/issues)를 +사용하여 신고해야 합니다. 그러나 _보안 취약성_ 을 신고하는 경우 +[cncf-kubernetes-helm-security@lists.cncf.io](mailto:cncf-kubernetes-helm-security@lists.cncf.io) +이메일로 신고해주세요. 이것은 이슈가 악용되기 전에 해결할 수 있는 +기회를 줄 것입니다. + +## 당신의 작업에 서명해주세요 + +서명(sign-off)은 커밋 메시지 끝에 있는 간단한 줄입니다. 모든 커밋은 서명이 +있어야 합니다. 귀하의 서명은 패치를 작성했거나 자료를 기여할 권한이 있음을 +증명합니다. 아래 개발자 증명서([developercertificate.org](https://developercertificate.org/)에서 발췌)에 +동의하는 경우, 규칙은 매우 간단합니다. + +``` +원본 개발자 증명서 +버전 1.1 + +Copyright (C) 2004, 2006 The Linux Foundation and its contributors. +1 Letterman Drive +Suite D4700 +San Francisco, CA, 94129 + +모든 사용자는 이 라이센스 문서의 사본을 복사하여 +배포할 수 있지만 변경할 수는 없습니다. + +원본 개발자 증명서 1.1 + +본 프로젝트에 기여함으로써 저는 다음 사항을 보증합니다: + +(a) 해당 기여의 전부 또는 일부를 제가 작성했으며, + 파일에 명시된 오픈 소스 라이센스에 따라 + 제출할 권리가 있습니다. 또는 + +(b) 해당 기여는 제가 아는 한 적합한 오픈 소스 + 라이센스에 따라 적용되었으며, 해당 라이센스에 + 따라 (다른 라이센스로 제출할 수 있는 권한이 + 없는 경우) 파일에 표시된 것과 동일한 오픈 + 소스 라이센스로 제가 작성한 전부 또는 일부의 + 수정 작업을 제출할 권리가 있습니다. + 또는 + +(c) 해당 기여는 (a), (b) 또는 (c)를 인증한 + 다른 사람이 직접 제공했으며, 제가 수정하지 + 않았습니다. + +(d) 저는 해당 프로젝트와 기여를 공개하고 기여 + 기록(본인의 서명과 함께 제출한 모든 개인 + 정보 포함)이 무기한 유지되며 해당 프로젝트 + 또는 관련 오픈 소스 라이센스와 일치하도록 + 재배포될 수 있음을 이해하고 동의합니다. +``` + +모든 git 커밋 메시지에 한 줄을 추가하기만 하면 됩니다. + + Signed-off-by: Joe Smith + +실명을 사용해주세요. (죄송하지만, 가명 또는 익명의 기여는 허용되지 않습니다.) + +`user.name` 과 `user.email` git config를 설정하면 `git commit -s` 로 +자동으로 커밋에 서명할 수 있습니다. + +참고: git 설정 정보가 올바르게 지정된 경우 `git log` 를 보면 +커밋 정보가 다음과 같습니다. + +``` +Author: Joe Smith +Date: Thu Feb 2 11:41:15 2018 -0800 + + Update README + + Signed-off-by: Joe Smith +``` + +`Author` 와 `Signed-off-by` 줄이 일치하는 것에 주목해주세요. 만약 일치하지 +않는다면 자동 DCO 검사에서 PR을 거부할 것입니다. + +## 지원 채널 + +당신이 사용자 혹은 기여자라면 공식 지원 채널은 다음과 같습니다. + +- [이슈](https://github.com/helm/helm/issues) +- 슬랙: + - 사용자: [#helm-users](https://kubernetes.slack.com/messages/C0NH30761/details/) + - 기여자: [#helm-dev](https://kubernetes.slack.com/messages/C51E88VDG/) + +새로운 이슈를 열거나 새로운 풀 리퀘스트를 보내기 전에 해당 프로젝트를 검색하는 것이 도움이 됩니다. 사용자가 겪은 이슈를 다른 사용자가 이미 보고했거나 저희가 이미 알고 있는 이슈일 수 있습니다. 슬랙 채널에서 물어보는 것도 도움이 될 수 있습니다. + +## 이슈 + +이슈는 헬름 프로젝트와 관련된 모든 항목을 추적하는 기본 방법으로 사용됩니다. + +### 이슈 유형 + +5가지 유형의 이슈가 있습니다(각 이슈마다 해당 [레이블](#labels)이 있음). + +- `question/support`: 향후 참조를 위해 기록하기를 원하는 지원 또는 기능 관련 +문의가 있습니다. 일반적으로 슬랙 채널에 저장하기에 너무 복잡한 또는 큰 질문이거나 +커뮤니티 전체에서 특별한 관심을 갖는 질문입니다. 논의에 따라 `feature` 또는 `bug` +이슈로 바뀔 수 있습니다. +- `proposal`: 대규모 커뮤니티 논의가 필요한 새로운 아이디어 또는 기능을 제안하는 +(이 글과 같은) 이슈에 사용됩니다. 이렇게 하면 기능이 실제로 개발되기 전에 +커뮤니티의 다른 사용자로부터 피드백을 받을 수 있습니다. 해당 레이블은 작은 이슈에 +필요하진 않습니다. 기능의 제안 필요 여부 결정은 핵심 관리자에게 달려 있습니다. +모든 제안 이슈는 해당 레이블과 "Proposal: [제목의 나머지 부분]" 이라는 제목이 +있어야 합니다. 제안은 `feature` 가 될 수 있으며 마일스톤은 필요하지 않습니다. +- `feature`: 이 이슈는 완료될 때까지 특정 기능 요청 및 아이디어를 추적합니다. +`proposal` 에서 바뀔 수도 있고 이슈 사이즈에 따라 개별적으로 제출될 수 있습니다. +- `bug`: 코드와 함께 버그를 추적하는 이슈입니다. +- `docs`: 문서 관련 문제(예: 누락 또는 미완)를 추적합니다. + +### 이슈 생명 주기 + +이슈 생명 주기는 주로 핵심 관리자에 의해 관리되지만, 헬름에 기여하는 사람들에게도 좋은 정보입니다. +모든 유형의 이슈는 동일한 생명 주기를 따릅니다. 차이점은 아래에 설명되어 있습니다. + +1. 이슈 생성 +2. 분류 + - 분류를 담당하는 관리자가 해당 이슈에 대한 적절한 레이블을 적용합니다. + 여기에는 우선 순위, 유형, 메타데이터(예: `good first issue`) + 레이블이 포함됩니다. 저희가 추적할 유일한 이슈 우선 순위는 이 이슈가 + "중요한지" 여부입니다. 향후 추가 레이블이 필요하면 추가하겠습니다. + - (필요한 경우) 간결하고 명확하게 이슈를 설명하기 위해 제목을 정리하세요. + 또한 제안의 제목은 "Proposal: [제목의 나머지 부분]"으로 서두를 떼야 합니다. + - 이슈를 올바른 마일스톤에 추가합니다. 질문 이슈일 경우, 질문에 + 답변할 때까지 이슈를 마일스톤 추가하는 것에 대해 염려하지 마세요. + - 저희는 작업일에 적어도 한 번 이상 이 과정을 시도합니다. +3. 논의 + - `feature` 또는 `bug` 로 레이블이 지정된 이슈는 이를 해결하는 PR에 연결해야 합니다. + - `feature` 또는 `bug` 이슈를 작업하는 사람(관리자 또는 커뮤니티의 누군가)은 + 해당 이슈를 직접 자신에게 배정하거나 해당 이슈를 처리하고 있다는 내용의 코멘트를 + 작성해야 합니다. + - `proposal` 및 `support/question` 이슈는 해결될 때까지 또는 30일 이상 활발하지 않은 + 경우에도 계속 열려 있어야 합니다. 이렇게 하면 이슈 대기열을 관리 가능한 크기로 유지하고 잡음을 + 줄일 수 있습니다. 이슈가 계속 열려 있어야 하는 경우 `keep open` 레이블을 추가할 수 있습니다. +4. 이슈 종결 + +## 패치에 기여하는 방법 + +1. 아직 서명하지 않은 경우 기여자 라이센스 계약에 서명하세요(위 세부 정보 참조). +2. 원하는 저장소를 포크하여 코드 변경 사항을 개발하고 테스트하세요. +3. 풀 리퀘스트를 보내주세요. + +코딩 규약 및 표준은 [공식 개발자 문서](https://helm.sh/docs/community/developers/)에 설명되어 있습니다. + +## 풀 리퀘스트 + +모든 좋은 오픈 소스 프로젝트와 마찬가지로, 저희는 PR(풀 리퀘스트)을 사용하여 코드 수정을 추적합니다. + +### PR 생명 주기 + +1. PR 생성 + - PR은 일반적으로 이슈를 해결하기 위해 생성되거나 특정 이슈를 해결하는 다른 PR의 하위 집합이 됩니다. + - 저희는 현재 진행 중인 PR을 환영합니다. 아직 진행 중이지만 다른 사람들이 보기에 + 유용한 중요 작업을 추적할 수 있는 좋은 방법입니다. PR이 진행 중인 작업의 경우 + **반드시** "WIP: [제목]"으로 제목을 시작해야 합니다. PR을 리뷰할 준비가 되면 + 제목에서 "WIP"를 제거합니다. + - 특정 이슈와 관련된 PR을 보내는 것이 바람직하지만 필수 사항은 아닙니다. + 해당 PR이 급한 해결책이라면 이슈가 적절하지 않게 종결될 수 있는 상황이 있을 + 수 있습니다. 이 경우 PR 설명란에 세부 정보를 넣어주세요. +2. 분류 + - 분류를 담당하는 관리자가 해당 이슈에 대한 적절한 레이블을 적용합니다. 모든 레이블이 + 적용된 후에는 최소한 사이즈 레이블, `bug` 또는 `feature`, `awaiting review` 가 포함되어야 합니다. + 레이블 정의에 대한 자세한 내용은 [레이블 섹션](#레이블)을 참조합니다. + - PR을 올바른 마일스톤에 추가합니다. 이는 PR이 닫는 이슈와 동일해야 합니다. +3. 리뷰 배정 + - 리뷰에 `awaiting review` 라는 레이블이 표시되면 관리자는 스케줄이 허용하는 대로 리뷰합니다. + 이슈를 제기한 관리자는 리뷰에 대해 자체 요청(self-request)해야 합니다. + - `size/large` 레이블이 있는 PR은 병합하기 전에 관리자로부터 2개의 리뷰 승인이 필요합니다. + `size/medium` 또는 `size/small` 인 경우 관리자의 판단에 따릅니다. +4. 리뷰/논의 + - 모든 리뷰는 GitHub 리뷰 도구를 사용하여 완료됩니다. + - "Comment(주석)" 리뷰는 답변해야 하는 코드 관련 질문이 있을 때 사용해야 하지만 코드 변경은 + 포함되지 않습니다. 이러한 유형의 리뷰는 승인에 포함되지 않습니다. + - "Changes Requested(변경 요청)" 리뷰는 코드를 병합하기 전에 수정해야 함을 나타냅니다. + - 리뷰어는 필요에 따라 레이블을 갱신해야 합니다(예: `needs rebase`). +5. 질문에 답변하거나 코드를 수정하여 의견을 반영합니다. +6. LGTM (Looks good to me) + - 리뷰어가 리뷰를 완료하고 코드가 병합될 준비가 된 것으로 보이면 "Approve(승인)" + 리뷰는 기여자와 다른 관리자에게 코드를 리뷰한 후 병합 준비가 완료되었음을 알리는 데 + 사용됩니다. +7. 병합(merge) 또는 종결(close) + - PR은 병합될 때까지 또는 30일 이상 활발하지 않은 경우 열려 있어야 합니다. 이렇게 하면 + PR 대기열을 관리 가능한 크기로 유지하고 잡음을 줄일 수 있습니다. PR이 계속 열려 있어야 + 하는 경우 (WIP의 경우처럼), `keep open` 레이블을 추가할 수 있습니다. + - PR을 병합하기 전에 PR에 한 개 이상의 LGTM이 필요한지 여부를 결정하기 위해 + 아래 [사이즈 레이블](#사이즈-레이블) 항목을 참조하세요. + - PR 소유자가 `OWNERS` 파일에 포함되어 있는 경우 해당 사용자는 반드시 자신의 PR을 병합하거나 + 다른 OWNER에게 명시적으로 요청해야 합니다. + - PR의 소유자가 `OWNERS`에 포함되어 있지 않은 경우, 모든 핵심 관리자가 PR을 병합할 수 있습니다. + +#### 문서 PR + +문서 PR은 다른 PR과 동일한 수명 주기를 따릅니다. 또한 `docs` 레이블로 +레이블이 지정됩니다. 문서의 경우 철자, 문법, 명료성에 특히 주의를 기울여야 +합니다(코드의 주석*만큼* 중요하지 않음). + +## 분류자 (Triager) + +매주 목요일 공개 스탠드업 회의를 시작으로 핵심 관리자 중 한 명이 "분류자" +역할을 하게 됩니다. 이 담당자는 일주일 내내 새로운 PR 및 이슈에 대한 분류를 +담당하게 됩니다. + +## 레이블 + +다음 표에서는 헬름에 사용되는 모든 레이블 유형을 정의합니다. 카테고리별로 나뉩니다. + +### 공통 레이블 + +| 레이블 | 설명 | +| ----- | ----------- | +| `bug` | 이슈를 버그 또는 PR을 버그 수정으로 표시합니다. | +| `critical` | 이슈 또는 PR을 중요한 것으로 표시합니다. 이것은 PR이나 이슈를 다루는 것이 최우선이며 가능한 한 빨리 해결되어야 한다는 것을 의미합니다. | +| `docs` | 이슈 또는 PR이 문서 변경임을 나타냅니다. | +| `feature` | 이슈를 기능 요청으로 표시하거나 PR을 기능 구현으로 표시합니다. | +| `keep open` | 이슈 또는 PR을 30일간 사용되지 않는 상태로 열어 둬야 함을 나타냅니다. | +| `refactor` | 이슈가 코드 개선이며 버그를 고치거나 추가 기능을 추가하지 않음을 나타냅니다. | + +### 이슈용 레이블 + +| 레이블 | 설명 | +| ----- | ----------- | +| `help wanted` | 이슈를 해결하기 위해 커뮤니티의 도움이 필요하다고 표시합니다. | +| `proposal` | 이슈를 제안으로 표시합니다. | +| `question/support` | 이슈를 요청이나 질문으로 표시합니다. | +| `good first issue` | 이슈를 헬름을 처음 접하는 사용자에게 좋은 첫 이슈로 표시합니다. | +| `wont fix` | 이슈가 논의되었으며 구현되지 않을 것임(또는 제안의 경우 받았음)을 나타냅니다. | + +### PR용 레이블 + +| 레이블 | 설명 | +| ----- | ----------- | +| `awaiting review` | PR이 분류되었으며 다른 사용자가 리뷰할 준비가 되었음을 나타냅니다 | +| `breaking` | PR이 코드를 변경한다는 것을 나타냅니다 (예: API 변경) | +| `in progress` | 아직 리뷰되지 않았어도 관리자가 PR을 보고 있음을 나타냅니다 | +| `needs rebase` | PR이 병합되기 전 리베이스(rebase)할 필요가 있음을 나타냅니다 | +| `needs pick` | PR이 기능 브랜치(일반적으로 버그 수정 브랜치)로 체리픽(cherry-pick)할 필요가 있음을 나타냅니다. 체리픽했다면 `picked` 레이블을 적용하고 해당 레이블을 제거해야 합니다 | +| `picked` | 해당 PR은 기능 브랜치로 체리픽했다는 것을 나타냅니다 | + +#### 사이즈 레이블 + +사이즈 레이블은 PR이 얼마나 "위험"한지를 나타내는 데 사용됩니다. +아래 가이드라인은 레이블을 배정하는 데 사용되지만, 궁극적으로 관리자에 의해 변경 될 +수 있습니다. 예를 들어 PR이 한 파일에서 30 줄만 변경하더라도 주요 기능이 바뀐다면 +여러 명의 서명이 필요하므로 `size/L` 로 레이블이 지정될 가능성이 높습니다. +반대로 작은 기능을 추가하지만 모든 경우를 다루기 위해 150 줄의 테스트가 필요한 PR은 +줄 수가 아래에 정의된 것보다 많더라도 `size/S` 로 레이블을 지정할 수 있습니다. + +핵심 관리자에 의해 제출되는 PR은 사이즈에 상관없이 한 명의 추가 관리자 승인만 필요로 +합니다. 이렇게 하면 코드베이스(codebase)에 도입된 중요한 PR을 알고 있는 관리자가 +두 명 이상 있게 됩니다. + +| 레이블 | 설명 | +| ----- | ----------- | +| `size/XS` | 생성된 파일은 무시하고 0~9줄을 변경하는 PR을 나타냅니다. 변경 사항에 따라 테스트가 거의 필요하지 않을 수 있습니다. | +| `size/S` | 생성된 파일은 무시하고 10-29줄을 변경하는 PR을 나타냅니다. 소량의 수동 테스트만 필요할 수 있습니다. | +| `size/M` | 생성된 파일은 무시하고 30-99줄을 변경하는 PR을 나타냅니다. 수동 유효성 검사가 필요합니다. | +| `size/L` | 생성된 파일은 무시하고 100-499줄을 변경하는 PR을 나타냅니다. 이 작업은 병합하기 전에 철저히 테스트해야 하며 항상 2개의 승인이 필요합니다. | +| `size/XL` | 생성된 파일은 무시하고 500-999 줄을 변경하는 PR을 나타냅니다. 이 작업은 병합하기 전에 철저히 테스트해야 하며 항상 2개의 승인이 필요합니다. | +| `size/XXL` | 생성된 파일은 무시하고 1000개 이상의 행을 변경하는 PR을 나타냅니다. 이 작업은 병합하기 전에 철저히 테스트해야 하며 항상 2개의 승인이 필요합니다. | diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..1bc2d626de --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,269 @@ +# Contributing Guidelines + +This is the contribution guide for the helm.sh website and documentation. Go to [helm/helm](https://github.com/helm/helm/blob/main/CONTRIBUTING.md) for the core project. + +--- + +Helm accepts contributions via GitHub pull requests. This document outlines the process to help get your contribution accepted. + +## Reporting a Security Issue + +Most of the time, when you find a bug in Helm, it should be reported +using [GitHub issues](https://github.com/helm/helm/issues). However, if +you are reporting a _security vulnerability_, please email a report to +[cncf-kubernetes-helm-security@lists.cncf.io](mailto:cncf-kubernetes-helm-security@lists.cncf.io). This will give +us a chance to try to fix the issue before it is exploited in the wild. + +## Sign Your Work + +The sign-off is a simple line at the end of the explanation for a commit. All +commits needs to be signed. Your signature certifies that you wrote the patch or +otherwise have the right to contribute the material. The rules are pretty simple, +if you can certify the below (from [developercertificate.org](https://developercertificate.org/)): + +``` +Developer Certificate of Origin +Version 1.1 + +Copyright (C) 2004, 2006 The Linux Foundation and its contributors. +1 Letterman Drive +Suite D4700 +San Francisco, CA, 94129 + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + +Developer's Certificate of Origin 1.1 + +By making a contribution to this project, I certify that: + +(a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + +(b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + +(c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + +(d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. +``` + +Then you just add a line to every git commit message: + + Signed-off-by: Joe Smith + +Use your real name (sorry, no pseudonyms or anonymous contributions.) + +If you set your `user.name` and `user.email` git configs, you can sign your +commit automatically with `git commit -s`. + +Note: If your git config information is set properly then viewing the + `git log` information for your commit will look something like this: + +``` +Author: Joe Smith +Date: Thu Feb 2 11:41:15 2018 -0800 + + Update README + + Signed-off-by: Joe Smith +``` + +Notice the `Author` and `Signed-off-by` lines match. If they don't +your PR will be rejected by the automated DCO check. + +## Support Channels + +Whether you are a user or contributor, official support channels include: + +- [Issues](https://github.com/helm/helm/issues) +- Slack: + - User: [#helm-users](https://kubernetes.slack.com/messages/C0NH30761/details/) + - Contributor: [#helm-dev](https://kubernetes.slack.com/messages/C51E88VDG/) + +Before opening a new issue or submitting a new pull request, it's helpful to search the project - it's likely that another user has already reported the issue you're facing, or it's a known issue that we're already aware of. It is also worth asking on the Slack channels. + +## Issues + +Issues are used as the primary method for tracking anything to do with the Helm project. + +### Issue Types + +There are 5 types of issues (each with their own corresponding [label](#labels)): + +- `question/support`: These are support or functionality inquiries that we want to have a record of for +future reference. Generally these are questions that are too complex or large to store in the +Slack channel or have particular interest to the community as a whole. Depending on the discussion, +these can turn into `feature` or `bug` issues. +- `proposal`: Used for items (like this one) that propose a new ideas or functionality that require +a larger community discussion. This allows for feedback from others in the community before a +feature is actually developed. This is not needed for small additions. Final word on whether or +not a feature needs a proposal is up to the core maintainers. All issues that are proposals should +both have a label and an issue title of "Proposal: [the rest of the title]." A proposal can become +a `feature` and does not require a milestone. +- `feature`: These track specific feature requests and ideas until they are complete. They can evolve +from a `proposal` or can be submitted individually depending on the size. +- `bug`: These track bugs with the code +- `docs`: These track problems with the documentation (i.e. missing or incomplete) + +### Issue Lifecycle + +The issue lifecycle is mainly driven by the core maintainers, but is good information for those +contributing to Helm. All issue types follow the same general lifecycle. Differences are noted below. + +1. Issue creation +2. Triage + - The maintainer in charge of triaging will apply the proper labels for the issue. This + includes labels for priority, type, and metadata (such as `good first issue`). The only issue + priority we will be tracking is whether or not the issue is "critical." If additional + levels are needed in the future, we will add them. + - (If needed) Clean up the title to succinctly and clearly state the issue. Also ensure + that proposals are prefaced with "Proposal: [the rest of the title]". + - Add the issue to the correct milestone. If any questions come up, don't worry about + adding the issue to a milestone until the questions are answered. + - We attempt to do this process at least once per work day. +3. Discussion + - issues that are labeled as `feature` or `bug` should be connected to the PR that resolves it. + - Whoever is working on a `feature` or `bug` issue (whether a maintainer or someone from + the community), should either assign the issue to themself or make a comment in the issue + saying that they are taking it. + - `proposal` and `support/question` issues should stay open until resolved or if they have not been + active for more than 30 days. This will help keep the issue queue to a manageable size and + reduce noise. Should the issue need to stay open, the `keep open` label can be added. +4. Issue closure + +## How to Contribute a Patch + +1. If you haven't already done so, sign a Contributor License Agreement (see details above). +2. Fork the desired repo, develop and test your code changes. +3. Submit a pull request. + +Coding conventions and standards are explained in the [official developer docs](https://helm.sh/docs/developers/). + +## Pull Requests + +Like any good open source project, we use Pull Requests (PRs) to track code changes. + +### PR Lifecycle + +1. PR creation + - PRs are usually created to fix or else be a subset of other PRs that fix a particular issue. + - We more than welcome PRs that are currently in progress. They are a great way to keep track of + important work that is in-flight, but useful for others to see. If a PR is a work in progress, + it **must** be prefaced with "WIP: [title]". Once the PR is ready for review, remove "WIP" from + the title. + - It is preferred, but not required, to have a PR tied to a specific issue. There can be + circumstances where if it is a quick fix then an issue might be overkill. The details provided + in the PR description would suffice in this case. +2. Triage + - The maintainer in charge of triaging will apply the proper labels for the issue. This should + include at least a size label, `bug` or `feature`, and `awaiting review` once all labels are applied. + See the [Labels section](#labels) for full details on the definitions of labels. + - Add the PR to the correct milestone. This should be the same as the issue the PR closes. +3. Assigning reviews + - Once a review has the `awaiting review` label, maintainers will review them as schedule permits. + The maintainer who takes the issue should self-request a review. + - Any PR with the `size/large` label requires 2 review approvals from maintainers before it can be + merged. Those with `size/medium` or `size/small` are per the judgement of the maintainers. +4. Reviewing/Discussion + - All reviews will be completed using GitHub review tool. + - A "Comment" review should be used when there are questions about the code that should be + answered, but that don't involve code changes. This type of review does not count as approval. + - A "Changes Requested" review indicates that changes to the code need to be made before they will be merged. + - Reviewers should update labels as needed (such as `needs rebase`) +5. Address comments by answering questions or changing code +6. LGTM (Looks good to me) + - Once a Reviewer has completed a review and the code looks ready to merge, an "Approve" review is used + to signal to the contributor and to other maintainers that you have reviewed the code and feel that it is + ready to be merged. +7. Merge or close + - PRs should stay open until merged or if they have not been active for more than 30 days. + This will help keep the PR queue to a manageable size and reduce noise. Should the PR need + to stay open (like in the case of a WIP), the `keep open` label can be added. + - Before merging a PR, refer to the topic on [Size Labels](#size-labels) below to determine if + the PR requires more than one LGTM to merge. + - If the owner of the PR is listed in the `OWNERS` file, that user **must** merge their own PRs + or explicitly request another OWNER do that for them. + - If the owner of a PR is _not_ listed in `OWNERS`, any core maintainer may merge the PR. + +#### Documentation PRs + +Documentation PRs will follow the same lifecycle as other PRs. They will also be labeled with the +`docs` label. For documentation, special attention will be paid to spelling, grammar, and clarity +(whereas those things don't matter *as* much for comments in code). + +## The Triager + +Each week, one of the core maintainers will serve as the designated "triager" starting after the +public stand-up meetings on Thursday. This person will be in charge triaging new PRs and issues +throughout the work week. + +## Labels + +The following tables define all label types used for Helm. It is split up by category. + +### Common + +| Label | Description | +| ----- | ----------- | +| `bug` | Marks an issue as a bug or a PR as a bugfix | +| `critical` | Marks an issue or PR as critical. This means that addressing the PR or issue is top priority and must be addressed as soon as possible | +| `docs` | Indicates the issue or PR is a documentation change | +| `feature` | Marks the issue as a feature request or a PR as a feature implementation | +| `keep open` | Denotes that the issue or PR should be kept open past 30 days of inactivity | +| `refactor` | Indicates that the issue is a code refactor and is not fixing a bug or adding additional functionality | + +### Issue Specific + +| Label | Description | +| ----- | ----------- | +| `help wanted` | Marks an issue needs help from the community to solve | +| `proposal` | Marks an issue as a proposal | +| `question/support` | Marks an issue as a support request or question | +| `good first issue` | Marks an issue as a good starter issue for someone new to Helm | +| `wont fix` | Marks an issue as discussed and will not be implemented (or accepted in the case of a proposal) | + +### PR Specific + +| Label | Description | +| ----- | ----------- | +| `awaiting review` | Indicates a PR has been triaged and is ready for someone to review | +| `breaking` | Indicates a PR has breaking changes (such as API changes) | +| `in progress` | Indicates that a maintainer is looking at the PR, even if no review has been posted yet | +| `needs rebase` | Indicates a PR needs to be rebased before it can be merged | +| `needs pick` | Indicates a PR needs to be cherry-picked into a feature branch (generally bugfix branches). Once it has been, the `picked` label should be applied and this one removed | +| `picked` | This PR has been cherry-picked into a feature branch | + +#### Size labels + +Size labels are used to indicate how "dangerous" a PR is. The guidelines below are used to assign the +labels, but ultimately this can be changed by the maintainers. For example, even if a PR only makes +30 lines of changes in 1 file, but it changes key functionality, it will likely be labeled as `size/L` +because it requires sign off from multiple people. Conversely, a PR that adds a small feature, but requires +another 150 lines of tests to cover all cases, could be labeled as `size/S` even though the number of +lines is greater than defined below. + +PRs submitted by a core maintainer, regardless of size, only requires approval from one additional +maintainer. This ensures there are at least two maintainers who are aware of any significant PRs +introduced to the codebase. + +| Label | Description | +| ----- | ----------- | +| `size/XS` | Denotes a PR that changes 0-9 lines, ignoring generated files. Very little testing may be required depending on the change. | +| `size/S` | Denotes a PR that changes 10-29 lines, ignoring generated files. Only small amounts of manual testing may be required. | +| `size/M` | Denotes a PR that changes 30-99 lines, ignoring generated files. Manual validation should be required. | +| `size/L` | Denotes a PR that changes 100-499 lines, ignoring generated files. This should be thoroughly tested before merging and always requires 2 approvals. | +| `size/XL` | Denotes a PR that changes 500-999 lines, ignoring generated files. This should be thoroughly tested before merging and always requires 2 approvals. | +| `size/XXL` | Denotes a PR that changes 1000+ lines, ignoring generated files. This should be thoroughly tested before merging and always requires 2 approvals. | diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000..73f9e16ad4 --- /dev/null +++ b/Makefile @@ -0,0 +1,24 @@ +clean: + rm -rf app resources + +build: clean + hugo --minify + + make check-links-ci + +build-preview: clean + hugo \ + --baseURL $(DEPLOY_PRIME_URL) \ + --buildDrafts \ + --buildFuture \ + --minify + + make check-links-ci + +set-up-link-checker: + curl https://raw.githubusercontent.com/wjdp/htmltest/master/godownloader.sh | bash + +run-link-checker: + bin/htmltest + +check-links-ci: set-up-link-checker run-link-checker diff --git a/OWNERS b/OWNERS new file mode 100644 index 0000000000..649c3c9bb2 --- /dev/null +++ b/OWNERS @@ -0,0 +1,13 @@ +maintainers: + - yxxhero + - angellk + - bacongobbler + - bridgetkromhout + - flynnduism + - hickeyma + - jdolitsky + - karenhchu + - mattfarina + - technosophos +emeritus: + - thomastaylor312 diff --git a/README-ko.md b/README-ko.md new file mode 100755 index 0000000000..4e64e28983 --- /dev/null +++ b/README-ko.md @@ -0,0 +1,94 @@ +![github-banner-helm-helmwww](https://user-images.githubusercontent.com/686194/68531441-f4ad4e00-02c6-11ea-982b-74d7c3ff0071.png) + + +여기서 [헬름](https://github.com/helm/helm) 프로젝트의 웹 사이트 [helm.sh](https://helm.sh/)를 구성하는 모든 것을 확인할 수 있습니다. 문서를 편집하거나 웹 사이트 버그를 보고하거나 새 블로그 게시물을 작성하려는 경우 잘 찾아오셨습니다! + + +## 개발 + +Helm.sh는 사용자 지정 테마를 사용하여 구축된 간단한 [휴고(Hugo)](https://gohugo.io/) 정적 사이트입니다. 웹 사이트를 로컬에서 실행하려면 먼저 휴고와 이와 관련된 모듈(dependencies)을 [설치](https://gohugo.io/getting-started)해야 합니다. + +``` +brew install hugo +yarn install +``` + +설치 후에 사이트를 로컬에서 컴파일하고 실행할 수 있습니다. + +``` +hugo serve +``` + +## 배포 [![Netlify Status](https://api.netlify.com/api/v1/badges/8ffabb30-f2f4-45cc-b0fa-1b4adda00b5e/deploy-status)](https://app.netlify.com/sites/helm-merge/deploys) + +변경 사항을 `main` 브랜치에 병합하면 [넷틀리파이(Netlify)](https://app.netlify.com/sites/helm-merge/deploys)에 자동으로 배포됩니다. 빌드 로그는 [여기](https://app.netlify.com/sites/helm-merge/deploys)에서 확인할 수 있습니다. + + +--- + +## 기여 + +누구나 풀 리퀘스트(PR)를 제출하여 Helm.sh을 편집할 수 있습니다. 커밋을 위해서는 서명이 필요합니다. [기여 가이드](https://github.com/helm/helm/blob/main/CONTRIBUTING.md#sign-your-work)를 참조하세요. + +풀 리퀘스트는 병합되기 전에 [관리자](https://github.com/helm/helm-www/blob/main/OWNERS)의 승인이 필요합니다. + + +### 헬름 문서를 편집하는 방법 + +헬름 3 릴리스 이후 모든 프로젝트 문서는 이 저장소 `/content/en/docs/` 에 있습니다. + +이전 버전의 경우, [기본 헬름 저장소](https://github.com/helm/helm/tree/dev-v2/docs)의 dev-v2 브랜치를 참조합니다. + + +### 헬름 CLI 레퍼런스 문서 업데이트 + +헬름 CLI 명령어 목록에 대한 문서는 기본 헬름 프로젝트 저장소에서 [내보내지고](https://github.com/helm/helm/blob/a6b2c9e2126753f6f94df231e89b2153c2862764/cmd/helm/root.go#L169), [여기](https://helm.sh/docs/helm)에서 레퍼런스로 제공됩니다. + +문서를 업데이트하려면 다음을 수행해야 합니다. + +1. `helm plugin uninstall` 을 실행하여 현재 설치된 모든 플러그인을 제거합니다. +2. `content/en/docs/helm/` 으로 이동합니다. +3. 기존 마크다운 파일을 대체하여 새로운 마크다운 문서 파일을 생성하기 위해 `helm docs --type markdown`을 실행합니다. +4. 변경된 각 파일에 YAML 프런트 매터(front-matter)를 다시 추가합니다. +5. 변경 내용을 커밋하고 PR을 만들어 웹 사이트를 업데이트합니다. + + +### 블로그 게시물을 작성하는 방법 + +블로그 게시물은 풀 리퀘스트를 통해 만들어집니다. 다음 단계를 사용하여 추가합니다. + +1) 새 파일을 `content/en/blog/` 디렉터리에 추가합니다. 디렉터리의 이름은 게시 날짜 및 제목입니다. 파일은 마크다운 형식이어야 합니다. 형식 예시는 기존 제목을 참조합니다. +2) 아래 형식을 사용하여 헤더 메타데이터를 파일에 추가합니다(퍼머링크 구조 참고). 이름(들)이어야 하는 `authorname` 은 권장되지만 필수는 아닌 필드이며, 게시물에 그대로 표시됩니다. 또한 `authorlink` 는 `authorname` 이 사용하는 링크입니다. + +```yaml +--- +title: "A Fancy Title" +slug: "fancy-title" +authorname: "Captain Awesome" +authorlink: "https://example.com" +date: "yyyy-mm-dd" +--- +``` + +3) 게시물 내용을 `---` 아래에 마크다운 형식으로 추가합니다. 제목은 여기에 포함되지 않아도 됩니다. +4) 모든 이미지는 `/content/en/blog/images/` 디렉토리에 두어야 합니다. 이미지 크기를 줄이려면 무손실 압축되어야 합니다. [ImageOptim](https://imageoptim.com/)와 같은 도구를 사용할 수 있습니다. +5) 블로그 인덱스 페이지의 내용을 요약하려면 마크다운 파일에 `` 구분자를 넣습니다. 이렇게 하면 더 읽기(Read More) 링크로 내용 끝을 자릅니다. + +블로그 PR은 병합되기 전에 주요 헬름 [관리자](https://github.com/helm/helm/blob/main/OWNERS)들의 승인이 필요합니다. + + +### 국제화 & 번역 + +전세계에서 헬름을 더 쉽게 사용할 수 있도록 헬름 사이트 및 문서 **컨텐츠 번역을 환영합니다**. + +Helm.sh은 여러 언어를 지원합니다. 해외 사용자를 위한 컨텐츠 번역과 구성 가이드는 [헬름 문서 현지화](https://helm.sh/docs/community/localization/)를 참조하세요. + +--- + +### 행동 강령 + +헬름 커뮤니티 참여는 헬름 [행동 강령](https://github.com/helm/helm/blob/main/code-of-conduct.md)을 따릅니다. + +### 감사합니다! + +웹 사이트 및 문서 기여에 감사드립니다! :clap: diff --git a/README.md b/README.md old mode 100644 new mode 100755 index e922063064..7e44082b53 --- a/README.md +++ b/README.md @@ -1,10 +1,93 @@ -![https://helm.sh/assets/images/apple-touch-icon.png](https://helm.sh/assets/images/apple-touch-icon.png) +![github-banner-helm-helmwww](https://user-images.githubusercontent.com/686194/68531441-f4ad4e00-02c6-11ea-982b-74d7c3ff0071.png) + + +This is where you'll find all of the assets that make up [helm.sh](https://helm.sh/), the website for the [Helm](https://github.com/helm/helm) project. If you'll looking to edit docs, report a website bug or write a new blog post, you've come to the right place! + + +## Development + +Helm.sh is a simple [Hugo](https://gohugo.io/) static site, built with a custom theme. To run the website locally, you'll need to first [install](https://gohugo.io/getting-started) Hugo and any dependencies. + +``` +brew install hugo +yarn install +``` + +You can then compile and run the site locally: + +``` +hugo serve +``` + +## Deployment [![Netlify Status](https://api.netlify.com/api/v1/badges/8ffabb30-f2f4-45cc-b0fa-1b4adda00b5e/deploy-status)](https://app.netlify.com/sites/helm-merge/deploys) + +Changes are automatically deployed to [Netlify](https://app.netlify.com/sites/helm-merge/deploys) when merged to `main`. Build logs can be found [here](https://app.netlify.com/sites/helm-merge/deploys). -[Helm](https://github.com/kubernetes/helm) is a tool that streamlines installing and managing Kubernetes applications. --- -There are two sides to the helm website: +## Contributing + +Anyone can submit a PR to edit Helm.sh. We require commits be signed - please refer to the [contributing guide](https://github.com/helm/helm/blob/main/CONTRIBUTING.md#sign-your-work). + +Pull requests require [maintainer](https://github.com/helm/helm-www/blob/main/OWNERS) approval before merge. + + +### How to Edit The Helm Docs + +Since the release of Helm 3, all project documentation is located in this repo under `/content/en/docs/`. + +For earlier versions, see the dev-v2 branch of the main Helm repo [here](https://github.com/helm/helm/tree/dev-v2/docs). + + +### Updating the Helm CLI Reference Docs + +The documentation for the list of Helm CLI Commands are [exported](https://github.com/helm/helm/blob/a6b2c9e2126753f6f94df231e89b2153c2862764/cmd/helm/root.go#L169) from the main helm project repo and rendered [here on the website](https://helm.sh/docs/helm) as a reference. + +To update these docs, you'll need to: + +1. Delete all plugins currently installed with `helm plugin uninstall` +2. Navigate to `content/en/docs/helm/` +3. Run `HOME='~' helm docs --type markdown --generate-headers` to generate the markdown docs files, replacing any prior markdown files. **Note:** Make sure you run the version of helm you want to build the docs for (for example, by checking out the correct tag and building it) +4. Commit the changes and create a PR to update the website. + + +### How to Write a Blog Post + +Blog posts are created via pull requests. The following steps are used to add them: + +1) Add a new file to the `content/en/blog/` directory whose name is the published date and the title. The files must be markdown formatted. See the existing titles for examples of the format +2) Add the header meta-data to the file using this format (note the permalink structure). Recommended but optional fields are `authorname` which should be name(s); these are displayed verbatim. `authorlink` is the link used by `authorname`. + +```yaml +--- +title: "A Fancy Title" +slug: "fancy-title" +authorname: "Captain Awesome" +authorlink: "https://example.com" +date: "yyyy-mm-dd" +--- +``` + +3) Add the content below the `---` as Markdown. The title does not need to be included in this section +4) Any images should be placed in the `/content/en/blog/images/` directory. Images should be losslessly compressed to reduce their size. Tools, such as [ImageOptim](https://imageoptim.com/), can be used. +5) To summarize the content on the blog index page, insert a `` break in your markdown. This will truncate the content with a _Read More_ link. + +Blog PRs require approval from the core Helm [maintainers](https://github.com/helm/helm/blob/main/OWNERS) before merge. + + +### Internationalization & Translation + +**We welcome content translations** to our site and our docs, to help expand access to Helm around the world. + +Helm.sh supports multiple languages. Please refer to the [Localizing Helm Documentation](https://helm.sh/docs/community/localization/) for a guide on translating and configuring content for international users. + +--- + +### Code of Conduct + +Participation in the Helm community is governed by the Helm [Code of Conduct](https://github.com/helm/helm/blob/main/code-of-conduct.md). + +### Thank You! -* [/helm.sh](https://github.com/helm/helm-www/blob/master/helm.sh/) -* [/docs.helm.sh](https://github.com/helm/helm-www/blob/master/docs.helm.sh/) \ No newline at end of file +We appreciate your contributions to our website and our documentation! :clap: diff --git a/code-of-conduct.md b/code-of-conduct.md new file mode 100644 index 0000000000..91ccaf0353 --- /dev/null +++ b/code-of-conduct.md @@ -0,0 +1,3 @@ +# Community Code of Conduct + +Helm follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md). diff --git a/config.toml b/config.toml new file mode 100644 index 0000000000..ad10150139 --- /dev/null +++ b/config.toml @@ -0,0 +1,438 @@ +baseurl = "https://helm.sh/" +languageCode = "en-us" +theme = "helm" + +contentDir = "content" +publishdir = "app" +enableEmoji = true + +canonifyURLs = "false" +pluralizeListTitles = "false" +plainIdAnchors = "true" +disableKinds = ["taxonomy", "taxonomyTerm"] + +[markup] +[markup.goldmark] +[markup.goldmark.extensions] +typographer = false +[markup.highlight] +style = "manni" +guessSyntax = true + +[Permalinks] +code = "/:filename/" + +[params] +title = "Helm" +description = "Helm - The Kubernetes Package Manager." +googleAnalyticsId = "UA-42867143-2" +googleSiteVerification = "dCa3wS47cErhx0IpaxbB85NfcOP-vFxevknVk6fzf5I" +twittersite = "helmpack" +twittertype = "summary" +twitterimage = "img/og-image.png" +jsFiles = [ + "foundation", + "foundation.accordion", + "foundation.dropdown", + "foundation.offcanvas", + "foundation.slider", + "foundation.tooltip", + "modernizr", + "clipboard.min", + "app" +] + +[[params.versions]] +version = "v3.11.1" +patch = "stable" +url = "https://helm.sh/docs" +primary = true + +[[params.versions]] +version = "v2.17.0" +url = "https://v2.helm.sh/docs" + +[params.nextversion] +version = "v3.12.0" +date = "May 10, 2023" + +[[params.quicklinks]] +title = "Quickstart Guide" +description = "How to install and get started with Helm including instructions for distros, FAQs, and plugins." +url = "/docs/intro/quickstart" + +[[params.quicklinks]] +title = "Chart Guide" +description = "Practical steps for building Helm charts—how to structure, sign, and sync your charts." +url = "/docs/topics/charts" + +[[params.quicklinks]] +title = "Video: Intro to Helm" +description = "Watch Matt Farina and Josh Dolitsky present an introduction to Helm at KubeCon 2019." +url = "https://www.youtube.com/watch?v=Zzwq9FmZdsU" + +[[params.quicklinks]] +title = "Migrating from v2 to v3" +description = "Read our blog post on how to migrate from Helm v2 to Helm v3." +url = "/blog/migrate-from-helm-v2-to-helm-v3/" + +[[params.quicklinks]] +title = "Helm Security Audit" +description = "Helm has been audited and deemed as recommended for public deployment during a third-party security audit funded by the CNCF." +url = "/blog/2019-11-04-helm-security-audit-results/" + +# Multilingual configuration +defaultContentLanguage = "en" +disableLanguages = ["zh"] + +# English +[languages.en] +title = "Helm" +description = "Helm - The Kubernetes Package Manager." +contentDir = "content/en" +languageName = "English" +weight = 1 + +[[languages.en.menus.main]] +name = "Home" +url = "/" +weight = 1 + +[[languages.en.menus.main]] +name = "Docs" +url = "/docs" +weight = 2 + +[[languages.en.menus.main]] +name = "Charts" +url = "https://hub.helm.sh/" +weight = 3 + +[[languages.en.menus.main]] +name = "Blog" +url = "/blog" +weight = 4 + +[[languages.en.menus.main]] +name = "Community" +url = "https://github.com/helm/community" +weight = 5 + +# German +[languages.de] +title = "Helm" +description = "Helm - Der Kubernetes Paket Manager." +contentDir = "content/de" +languageName = "Deutsch" +weight = 2 + +[[languages.de.menus.main]] +name = "Start" +url = "/" +weight = 1 + +[[languages.de.menus.main]] +name = "Dokumentation" +url = "/docs" +weight = 2 + +[[languages.de.menus.main]] +name = "Charts" +url = "https://hub.helm.sh/" +weight = 3 + +[[languages.de.menus.main]] +name = "Blog" +url = "https://helm.sh/blog" +weight = 4 + +[[languages.de.menus.main]] +name = "Gemeinschaft" +url = "https://github.com/helm/community" +weight = 5 + +[languages.de.params] +language_alternatives = ["en"] + +# Spanish +[languages.es] +title = "Helm" +description = "Helm - El Administrador de Paquetes de Kubernetes." +contentDir = "content/es" +languageName = "Español" +weight = 3 + +[[languages.es.menus.main]] +name = "Inicio" +url = "/" +weight = 1 + +[[languages.es.menus.main]] +name = "Docs" +url = "/docs" +weight = 2 + +[[languages.es.menus.main]] +name = "Charts" +url = "https://hub.helm.sh/" +weight = 3 + +[[languages.es.menus.main]] +name = "Blog" +url = "https://helm.sh/blog" +weight = 4 + +[[languages.es.menus.main]] +name = "Comunidad" +url = "https://github.com/helm/community" +weight = 5 + +# French +[languages.fr] +title = "Helm" +description = "Helm - Le manageur de paquets de Kubernetes." +contentDir = "content/fr" +languageName = "Français" +weight = 4 + +[[languages.fr.menus.main]] +name = "Accueil" +url = "/" +weight = 1 + +[[languages.fr.menus.main]] +name = "Docs" +url = "/docs" +weight = 2 + +[[languages.fr.menus.main]] +name = "Charts" +url = "https://hub.helm.sh/" +weight = 3 + +[[languages.fr.menus.main]] +name = "Blog" +url = "https://helm.sh/blog" +weight = 4 + +[[languages.fr.menus.main]] +name = "Communauté" +url = "https://github.com/helm/community" +weight = 5 + +# Ελληνικά +[languages.gr] +title = "Helm" +description = "Helm - Ο package manager του Kubernetes." +contentDir = "content/gr" +languageName = "Ελληνικά" +weight = 5 + +[[languages.gr.menus.main]] +name = "Αρχική" +url = "/" +weight = 1 + +[[languages.gr.menus.main]] +name = "Έγγραφα" +url = "/docs" +weight = 2 + +[[languages.gr.menus.main]] +name = "Charts" +url = "https://hub.helm.sh/" +weight = 3 + +[[languages.gr.menus.main]] +name = "Άρθρα" +url = "https://helm.sh/blog" +weight = 4 + +[[languages.gr.menus.main]] +name = "Επικοινωνία" +url = "https://github.com/helm/community" +weight = 5 + +# Japanese +[languages.ja] +title = "Helm" +description = "Helm - Kubernetes パッケージマネージャー" +contentDir = "content/ja" +languageName = "日本語" +weight = 6 + +[[languages.ja.menus.main]] +name = "ホーム" +url = "/" +weight = 1 + +[[languages.ja.menus.main]] +name = "ドキュメント" +url = "/docs" +weight = 2 + +[[languages.ja.menus.main]] +name = "チャート" +url = "https://hub.helm.sh/" +weight = 3 + +[[languages.ja.menus.main]] +name = "ブログ" +url = "https://helm.sh/blog" +weight = 4 + +[[languages.ja.menus.main]] +name = "コミュニティ" +url = "https://github.com/helm/community" +weight = 5 + +[languages.ja.params] +language_alternatives = ["en"] + + +# Korean +[languages.ko] +title = "헬름" +description = "헬름 - 쿠버네티스 패키지 매니저" +contentDir = "content/ko" +languageName = "한국어" +weight = 7 + +[[languages.ko.menus.main]] +name = "홈" +url = "/" +weight = 1 + +[[languages.ko.menus.main]] +name = "문서" +url = "/docs" +weight = 2 + +[[languages.ko.menus.main]] +name = "차트" +url = "https://hub.helm.sh/" +weight = 3 +external = "yes" + +[[languages.ko.menus.main]] +name = "블로그" +url = "https://helm.sh/blog" +weight = 4 + +[[languages.ko.menus.main]] +name = "커뮤니티" +url = "https://github.com/helm/community" +weight = 5 + +[languages.ko.params] +language_alternatives = ["en"] + +# Portuguese +[languages.pt] +title = "Helm" +description = "Helm - O Gerenciador de Pacotes do Kubernetes." +contentDir = "content/pt" +languageName = "Português" +weight = 8 + +[[languages.pt.menus.main]] +name = "Início" +url = "/" +weight = 1 + +[[languages.pt.menus.main]] +name = "Docs" +url = "/docs" +weight = 2 + +[[languages.pt.menus.main]] +name = "Charts" +url = "https://hub.helm.sh/" +weight = 3 + +[[languages.pt.menus.main]] +name = "Blog" +url = "https://helm.sh/blog" +weight = 4 + +[[languages.pt.menus.main]] +name = "Communidade" +url = "https://github.com/helm/community" +weight = 5 + +[languages.pt.params] +language_alternatives = ["en"] + +# Russian +[languages.ru] +title = "Helm" +description = "Helm – Менеджер Пакетов Kubernetes." +contentDir = "content/ru" +languageName = "Русский" +weight = 9 + +[[languages.ru.menus.main]] +name = "Главная" +url = "/" +weight = 1 + +[[languages.ru.menus.main]] +name = "Документация" +url = "/docs" +weight = 2 + +[[languages.ru.menus.main]] +name = "Chart-ы" +url = "https://hub.helm.sh/" +weight = 3 +external = "yes" + +[[languages.ru.menus.main]] +name = "Блог" +url = "https://helm.sh/blog" +weight = 4 + +[[languages.ru.menus.main]] +name = "Сообщество" +url = "https://github.com/helm/community" +weight = 5 + +[languages.ru.params] +language_alternatives = ["en"] + +# Chinese +[languages.zh] +title = "Helm" +description = "Helm - Kubernetes 包管理器" +contentDir = "content/zh" +languageName = "中文" +weight = 10 + +[[languages.zh.menus.main]] +name = "首页" +url = "/" +weight = 1 + +[[languages.zh.menus.main]] +name = "文档" +url = "/docs" +weight = 2 + +[[languages.zh.menus.main]] +name = "应用中心" +url = "https://hub.helm.sh/" +weight = 3 +external = "yes" + +[[languages.zh.menus.main]] +name = "博客" +url = "https://helm.sh/blog" +weight = 4 + +[[languages.zh.menus.main]] +name = "社区" +url = "https://github.com/helm/community" +weight = 5 + +[languages.zh.params] +language_alternatives = ["en"] diff --git a/content/code/chartmuseum.md b/content/code/chartmuseum.md new file mode 100644 index 0000000000..827723b175 --- /dev/null +++ b/content/code/chartmuseum.md @@ -0,0 +1,5 @@ +--- +name: "chartmuseum" +repoURL: "https://github.com/helm/chartmuseum" +branch: "main" +--- diff --git a/content/code/helm-v2.md b/content/code/helm-v2.md new file mode 100644 index 0000000000..4c825d4149 --- /dev/null +++ b/content/code/helm-v2.md @@ -0,0 +1,6 @@ +--- +url: "helm/v2" +name: "helm/v2" +repoURL: "https://github.com/helm/helm" +branch: "dev-v2" +--- diff --git a/content/code/helm-v3.md b/content/code/helm-v3.md new file mode 100644 index 0000000000..67185526df --- /dev/null +++ b/content/code/helm-v3.md @@ -0,0 +1,6 @@ +--- +url: "helm/v3" +name: "helm/v3" +repoURL: "https://github.com/helm/helm" +branch: "main" +--- diff --git a/content/code/helm.md b/content/code/helm.md new file mode 100644 index 0000000000..af5c8d5ce7 --- /dev/null +++ b/content/code/helm.md @@ -0,0 +1,5 @@ +--- +name: "helm" +repoURL: "https://github.com/helm/helm" +branch: "main" +--- diff --git a/content/de/docs/_index.md b/content/de/docs/_index.md new file mode 100644 index 0000000000..0729fd5f65 --- /dev/null +++ b/content/de/docs/_index.md @@ -0,0 +1,28 @@ +--- +title: "Dokumentation" +description: "Alles Wissenswerte zur Organisation der Dokumentation." +--- + +# Willkommen + +Willkommen zur [Helm](https://helm.sh/) Dokumentation. Helm ist der Paket +Manager für Kubernetes. Genauere Hintergrundinformationen gibt es im +[CNCF Helm Projekt Reisebericht](https://www.cncf.io/cncf-helm-project-journey/). + +# Wie die Dokumentation aufgebaut ist + +Helm hat eine Menge Dokumentation. Eine Hauptübersicht ist hilfreich, nach +bestimmten Dingen zu suchen: + +- [Lernprogramme](intro) sind eine gute Handhabe, um das erste Helm Chart zu + erstellen. Starten Sie hier, wenn Sie neu bei Helm sind. +- [Themenhandbücher]({{< relref path="/docs/topics" lang="en" >}}) diskutieren Hauptthemen und Konzepte auf einem + hohen Niveau und stellen nützliche Hintergrundinformationen und Erklärungen + zur Verfügung. +- [Gemeinschaftshandbücher]({{< relref path="/docs/community" lang="en" >}}) diskutieren Themen rund um die Helm Gemeinschaft. + Starten Sie hier, wenn Sie mehr über den Entwicklungsprozess von Helm lernen + möchten und wie Sie dazu beitragen können. +- [Anleitungen](howto) sind wie Rezepte. Sie werden durch die einzelnen Schritte + der Hauptprobleme und Anwendungsfälle geleitet. Anleitungen sind mehr + fortgeschritten als Themenhandbücher und setzen Wissen voraus, wie Helm + funktioniert. diff --git a/content/de/docs/faq/_index.md b/content/de/docs/faq/_index.md new file mode 100644 index 0000000000..f6c77199c6 --- /dev/null +++ b/content/de/docs/faq/_index.md @@ -0,0 +1,14 @@ +--- +title: "Fragen und Antworten" +weight: 8 +--- + +# Fragen und Antworten + +> Was sind die Kernunterschiede zwischen Helm 2 und Helm 3? +> Diese Seite bietet Antworten zu oft gestelten Fragen (FAQ) + +**Wir möchten Ihre Hilfe**, um dieses Dokument besser zu machen. Um Informationen +hinzuzufügen, korrigieren oder zu löschen, [füllen Sie ein Issue aus](https://github.com/helm/helm-www/issues) +oder senden Sie einne Pull Request. + diff --git a/content/de/docs/faq/changes_since_helm2.md b/content/de/docs/faq/changes_since_helm2.md new file mode 100644 index 0000000000..e55d6f0ac4 --- /dev/null +++ b/content/de/docs/faq/changes_since_helm2.md @@ -0,0 +1,426 @@ +--- +title: "Änderungen seit Helm 2" +weight: 1 +--- + +## Änderungen seit Helm 2 + +Hier ist eine Liste an grundlegenden Änderungen in Helm 3. + +### Löschung von Tiller + +Während des Helm 2 Entwicklungszyklus haben wir Tiller vorgestellt. Tiller +spielte eine wichtige Rolle für Teams in einem geteilten Cluster - es war +für mehrere unterschiedliche Operatoren möglich, mit demselben Set an Versionen +zu interagieren. + +Mit rollenbasierter Zugriffskontrolle (RBAC), standardmässig aktiviert in Kubernetes 1.6, +sperrte Tiller immer mehr in Produktionsumgebungen aus, da die Verwaltung schwieriger +wurde. Durch die riesigen Änderungen der Sicherheitsregeln, war es unser Fokus, +eine permissive Standardkonfiguration zu liefern. Das erlaubte es Neulingen in Helm +und Kubernetes, schnell zu starten, ohne sich allzuviuel über Sicherheitskontrollen den +Kopf zu zerbrechen. Unglücklicherweise konnte diese permissive Konfiguration ein +breites Spektrum an Berechtigungen öffnen, ohne dass der Nutzer dies erwartete. +DevOps und SREs hatten zusätzliche Betriebsschritte zu lernen, um Tiller in einer +multi-mandant Cluster zu betreiben. + +Nachdem wir von Gemeinschaftsmitgliedern gehört haben, wie sie Helm benutzen, fanden +wir, dass Tillers Versionsverwaltung nicht zum Clusterbetrieb oder als zentraler +Platz für Helm Versionsinformationen passte. Stattdessen können wir einfach die +Informationen von der Kubernetes-API abrufen, die Charts auf lokaler Seite rendern und +einen Eintrag der Installation in Kubernetes speichern. + +Tillers primäre Ziel konnte ohne Tiller erreicht werden, so war es eine der ersten +Entscheidungen, die für Helm 3 getroffen wurden, Tiller komplett zu entfernen. + +Ohne Tiller hat sich das Sicherheitsmodell von Helm radikal vereinfacht. Helm 3 +unterstützt jetzt moderne Funktionen von Kubernetes zu Sicherheits, Identität und Authorisierung. +Helms Zugriffsrechte werden durch Evaluierung der [kubeconfig +Datei](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/) getroffen. +Cluster Administratoren können Zugriffsrechte granular restriktieren. +Versionen werden weiter im Cluster gespeichert und die restliche Funktionalität +von Helm bleibt erhalten. + +### Verbesserte Aktualisierungsstrategie: 3-Wege Vereinigung + +Helm 2 hat eine 2-Wege Vereinigungsstrategie beutzt. Während der Aktualisierung +verglich es die letzten Chart Manifeste gegen das vorgeschlagene Chart Manifest +(welches zur Aktualisierung vorgeschlagen wurde). Es verglich die Unterschiede +zwischen den zwei Charts, um herauszufinden, welche Änderunen notwendig sind und +welche Resourcen im Kubernetescluster übertragen werden müssen. +Wenn Änderungen ausserhalb von Helm gemacht wurden (etwa mit `kubectl edit`), +waren diese Änderungen verloren. Das resultierte in Resourcen, die nicht zurückgerollt +werden konnten: weil Helm nur die letzte installierte Version kannte und wenn +es keine Änderungen im Chart Status gegeben hat, blieb der Livestatus unverändert. + +In Helm 3 benutzen wir jetzt eine 3-Wege Vereinigungsstrategie. Helm beachtet das +alte Manifest, den Livestatus und das neue Manifest, um einen Patch zu generieren. + +#### Beispiele + +Lassen Sie uns durch ein paar übliche Beispiele gehen, um die Auswirkungen zu +sehen. + +##### Zurückrollen wo sich der Livestatus geändert hat + +Ihr Team hat gerade mit Helm ihre Applikation in die Produktion auf Kubernetes gebracht. +Das Chart beinhaltet ein Deployment Objekt, in dem die Nummer der Replicas auf +drei gesetzt ist: + +```console +$ helm install myapp ./myapp +``` + +Ein neuer Entwickler tritt dem Team bei. An seinem ersten Arbeitstag tritt +beim Betrachten des Produktions-Clusters ein fürchterlicher Kaffee-auf-Tastatur-Unfall +ein und das Deployment wird von drei Replicas auf 0 skaliert. + +```console +$ kubectl scale --replicas=0 deployment/myapp +``` + +Ein anderer Entwickler Ihres Teams stellt fest, dass die Produktionsseite aus ist und +entscheidet ein Zurückrollen der Version zum vorherigen Status: + +```console +$ helm rollback myapp +``` + +Was passiert? + +In Helm 2 würde ein Patch generiert, der das alte gegen das neue +Manifest vergleicht. Weil es ein Zurückrollen ist, ist es dasselbe +Manifest. Helm würde feststellen, dass es nichts zu ändern gibt, weil es +keinen Unterschied zwischen dem alten und den neuen Manifest gibt. Der +Replica Zähler würde weiter auf 0 stehenbleiben. Panik bricht aus. + +In Helm 3 würde ein Patch generiert, der das alte Manifest, den Livestatus +und das neue Manifest vergleicht. Helm stellt fest, dass der alte Status +drei, der Livestatus 0 und das neue Manifest den Wunsch der Änderung zurück +zu drei hegt, sodass der Patch eine Änderung des Status zu drei generiert. + +##### Aktualisierungen wo sich der Livestatus geändert hat + +Viele Dienstenetze und andere kontroll-basierte Applikationen injizieren +Daten in Kubernetes Objekte. Das kann sowas sein wie ein Sidecar, Label oder +andere Informationen. Vorher haben Sie ein Manifest von einem Chart so +gerendert: + +```yaml +containers: +- name: server + image: nginx:2.0.0 +``` + +Und der Livestatus wurde von einer anderen Applikation geändert zu: + +```yaml +containers: +- name: server + image: nginx:2.0.0 +- name: my-injected-sidecar + image: my-cool-mesh:1.0.0 +``` + +Jetzt möchten Sie den `nginx` Image Tag aktualisieren zu `2.1.0`. Um das +zu erreichen, akualisieren Sie das Chart mit diesem Manifest: + +```yaml +containers: +- name: server + image: nginx:2.1.0 +``` + +Was passiert? + +In Helm 2 generiert Helm einen Patch für das `containers` Objekt zwischen dem +alten und dem neuen Manifest. Der Cluster Livestatus wird bei der Patchgenerierung +nicht beachtet. + +Der Cluster Livestatus wird in folgender Weise geändert: + +```yaml +containers: +- name: server + image: nginx:2.1.0 +``` + +Der Sidcar Pod ist vom Livestatus gelöscht. Mehr Panik bricht aus. + +In Helm 3 generiert Helm einen Patch des `containers` Objekts zwischen dem +alten Manifest, dem Livestatus und dem neuen Manifest. Es bemerkt, dass das +neue Manifest den Image Tag zu `2.1.0` ändern möchte, aber der Livestatus +einen Sidecar Container beinhaltet. + +Der Cluster Livestatus wird in folgender Weise geändert: + +```yaml +containers: +- name: server + image: nginx:2.1.0 +- name: my-injected-sidecar + image: my-cool-mesh:1.0.0 +``` + +### Versionsnamen sind jetzt im Umfang des Namespace geändert + +Nach der Löschung von Tiller müssen die Informationen über die Versionen +irgendwohin. In Helm 2 wurde das im selben Namespace wie Tiller gespeichert. +In der Praxis bedeutete das, dass ein Name von einer Version verwendet wurde, +keine andere Version konnte denselben Namen benutzen, auch wenn es in +unterschiedlichen Namespace installiert war. + +In Helm 3 werden die Informationen über eine Version im selben Namespace +gespeichert, in dem die Version selber installiert ist. Das bedeutet, dass +Benutzer jetzt `helm install wordpress stable/wordpress` in zwei Namespaces +benutzen könnnen und jedes wird bei `helm list` im Kontext des zugehörigen +Namespace angezeigt (z.B `helm list --namespace foo`). + +Mit der grösseren Ausrichtung auf nativen Cluster Namespaces, listet das Kommando +`helm list` nicht länger alle Versionen standardmässig auf. Stattdessen listet +es nur die Versionen im derzeitigen Kubernetes Kontext auf (z.B. den Namespace +wenn Sie `kubectl config view --minify` eingeben). Das bedeutet also, dass Sie +die Option `--all-namespaces` zu `helm list` eingeben müssen, wie bei Helm 2. + +### Secrets als der Standardspeichertreiber + +In Helm 3 werden jetzt Secrets als der [Standardspeichertreiber](/docs/topics/advanced/#storage-backends) +benutzt. Helm 2 benutzte ConfigMaps als Standard, um Versionsinformationen zu +speichern. In Helm 2.7.0 wurde ein neues Speicher-Backend implementiert, was +jetzt in Helm 3 der Standard ist. + +Die Änderung zu Secrets in Helm 3 als Standard erlaubt einen Schutz der Charts +in derselben Weise wie die Version der Secret Verschlüsselung in Kubernetes. + +[Verschlüsseung von Secrets mit Rest](https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/) +wurde Standard als Alpha-Funktion in Kubernetes 1.7 und wurde stabil in +Kubernetes 1.13. Dies erlaubt Benutzer Versions Metadaten zu verschlüsseln +und es ist ein guter Startpunkt, um später sowas wie Vault zu benutzen. + +### Go Import Pfadänderungen + +In Helm 3 schaltete Helm den Go Importpfad von `k8s.io/helm` zu +`helm.sh/helm/v3`. Wenn Sie 3 Go client Bibliotheken verwenden, stellen +Sie die Änderung des Importpfads sicher. + +### Capabilities + +Die Verfügbarkeit des eingebauten `.Capabilities` Objekts wurde im Stadium +des Renderns vereinfacht. + +[Eingebaute Objekte](/docs/chart_template_guide/builtin_objects/) + +### Validierung der Chart Values mit JSONSchema + +Ein JSON Schema kann jetzt den Chart Values auferlegt werden. Das stellt +sicher, dass die Werte, die der Nutzer eingegeben hat, dem Schemalayout +des Charts entsprechen, bessere Fehlermeldungen werden zur Verfügung +gestellt, wenn falsche Werte für das Chart eingegeben wurden. + +Eine Validierung erfolgt bei folgenden Kommandos: + +* `helm install` +* `helm upgrade` +* `helm template` +* `helm lint` + +Sehen Sie die Dokumentation zu [Schema Dateien](/docs/topics/charts#schema-files) für +mehr Informationen. + +### Konsolidierung von `requirements.yaml` in `Chart.yaml` + +Das Chart Abhängigkeitssystem schwenkte von requirements.yaml und +requirements.lock zu Chart.yaml und Chart.lock. Wir empfehlen, dass neue +Charts für Helm 3 dem neuen Format folgen. Trotzdem versteht Helm 3 +weiterhin die Chart APO Version 1 (`v1`) und wird vorhandene +`requirements.yaml` Dateien laden. + +In Helm 2 sah eine `requirements.yaml` so aus: + +```yaml +dependencies: +- name: mariadb + version: 5.x.x + repository: https://charts.helm.sh/stable + condition: mariadb.enabled + tags: + - database +``` + +In Helm 3 sehen die Abhängigkeiten genauso aus, stehen aber in +`Chart.yaml`: + +```yaml +dependencies: +- name: mariadb + version: 5.x.x + repository: https://charts.helm.sh/stable + condition: mariadb.enabled + tags: + - database +``` + +Charts werden weiterhin in das `charts/` Verzeichnis heruntergeladen, Subcharts +geliefert nach `charts/` werden ohne Anpassungen weiter funktionieren. + +### Name (oder --generate-name) ist jetzt zur Installation erforderlich + +Wenn in Helm 2 kein Name angeben wurde, wurde einer autogeneriert. In der +Produktion war das eher störend als hilfreich. In Helm 3 gibt es eine Fehlermeldung, +wenn bei `helm install` kein Name angegeben wird. + +Wer weiter einen autogenerierten Namen verwenden will, kann die Option +`--generate-name` für sich benutzen. + +### Charts in OCI Registries hochladen + +Dies ist eine experimentelle Funktion in Helm 3. Um sie zu benutzen, setzen Sie +die Umgebungsvariable `HELM_EXPERIMENTAL_OCI=1`. + +Auf einem hohen Level, ein Chart Repository ist ein Ort, an dem Charts gespeichert +und geteilt werden können. Ein Helm Programm packt und schickt Helm Charts zu +einem Chart Repository. Einfach ausgedrückt ist das ein simpler HTTP Server, +der eine index.yaml Datei hat und einige gepackte Charts. + +Während es für die meisten einfachen Speicheranforderungen nur Vorteile bringt, +gibt es aber auch ein paar Nachteile: + +- Chart Repositories fällt es sehr schwer, die Sicherheitsanforderungen an eine + Produktionsumgebung zu erfüllen. Es ist sehr wichtig, eine Authentifizierung + und Authorisierung für die Standard API zu haben. +- Helm Chart Herkunftswerkzeuge zum Signieren und Verifizieren der Integrität + sind optional für den Veröffentlichungsprozess. +- In einer Mehrbenutzerumgebung kann dasselbe Chart von unterschiedlichen Nutzern + hochgeladen werden, kostet doppelten Speicher für denselben Inhalt, aber + das ist nicht Teil der Spezifikation. +- Die Benutzung einer einzigen Indexdatei zum Suchen, Metadataeninformationen und + Herunterladen der Charts hat es kompliziert gemacht oder ist in einer sicheren + Mehrbenutzerumgebung unmöglich. + +Das Docker Distribution Projekt (auch bekannt als Docker Registry v2) ist der +Erfolgsfaktor des Docker Registry Projekts. Viele Cloud Lieferanten bieten +ein Produkt des Distribution Projekts an und da dies so viele sind, hat das +Distribution Projekt in vielen Jahren Vorteile bezüglich Hardening, empfohlene +Vorgehensweisen und Kampftests. + +Bitte schauen Sie nach `helm help chart` und `helm help registry` für mehr +wie ein Chart zu packen und in eine Docker Registry zu laden ist. + +Für mehr Informationen schauen Sie [diese Seite](/docs/topics/registries/). + +### Löschen von `helm serve` + +`helm serve` startete eine lokales Chart Repository auf Ihrem Computer für +Entwicklerzwecke. Nun, es wurde nicht viel angenommen und hatte zahlreiche +Probleme mit seinem Design. Am Ende entschieden wir uns es zu löschen und +als Plugin auszulagern. + +Für ähnliche Erfahrungen zu `helm serve` schauen Sie in die lokale +Dateisystemoption im +[ChartMuseum](https://chartmuseum.com/docs/#using-with-local-filesystem-storage) +und das [servecm plugin](https://github.com/jdolitsky/helm-servecm). + +### Unterstützung für Chart Bibliotheken + +Helm 3 unterstützt eine Klasse von Charts genannt "Chart Bibliotheken". Das ist +ein Chart, was von anderen Charts geteilt wird, aber keine eigenen Versionsartefakte +erstellt. +Eine Chart Bibliothek Vorlage kann nur `define` Elemente deklarieren. Global +nicht-`define` definierter Inhalt wird ignoriert. Das erlaubt Nutzern, Code oder +Codeschnippsel quer zwischen vielen Charts wiederzuverwenden und doppelten Code +zu vermeiden ([DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself)). + +Chart Bibliotheken sind in der Abhängigkeitsdirektive in der Chart.yaml deklariert +und werden installiert und verwaltet wie andere Charts. + +```yaml +dependencies: + - name: mylib + version: 1.x.x + repository: quay.io +``` + +Wir sind sehr stolz darauf, um Anwendungsfälle für diese Funktion von +Chartentwicklern und auch beste Beispiele der Nutzung zu sehen. + +### Chart.yaml apiVersion erhöht + +Mit der Vorstellung der Chartbibliotheken, der Konsilidierung der +requirements.yaml in Chart.yaml würden Programme in Helm 2 Format +nicht mehr funktionieren. So erhöhten wir die apiVersion in +Chart.yaml von `v1` zu `v2`. + +`helm create` erstellt Charts jetzt in diesem neuen Format, so wurde +die Standard apiVersion ebenfalls erhöht. + +Programme möchten beide Versionen unterstützen und sollten das Feld +`apiVersion` in Chart.yaml untersuchen, um zu verstehen, wie sie das +Paketformat parsen sollen. + +### XDG Basis Verzeichnissupport + +[Die Spezifikation zu XDG Basis Verzeichnissupport](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html) +ist ein portabler Standard, der Konfigurationen, Daten und Zwischenspeicherdateien +definiert und wie sie im Dateisystem gespeichert werden sollen. + +In Helm 2 speicherte Helm all diese Information in `~/.helm` (auch bekannt als +`helm home`), was mit der Umgebungsvariable `$HELM_HOME` geändert werden konnte, +oder auch durch die globale Funktion `--home`. + +In Helm 3 respektiert Helm jetzt die folgenden Umgebungsvariablen nach der +XDG Basnow respects the following environment variables as per the XDG +Basis Verzeichnissupport Spezifikation: + +- `$XDG_CACHE_HOME` +- `$XDG_CONFIG_HOME` +- `$XDG_DATA_HOME` + +Helm Plugins beachten weiterhin für Abwärtskompatibiltät`$HELM_HOME` als Alias +für `$XDG_DATA_HOME`. + +Verschiedene neue Umgebungsvariablen werden ebenfalls als Variablen des Plugins +eingeführt: + +- `$HELM_PATH_CACHE` für den Pfad zum Zwischenspeicher +- `$HELM_PATH_CONFIG` für den Pfad zur Konfiguration +- `$HELM_PATH_DATA` für den Pfad zu den Daten + +Helm Plugins, die Helm 3 unterstützen, sollten diese neuen Umgebungsvariablen +nutzen. + +### Umbenennung von Kommandozeilenbefehle + +Um sich in der Erwartungen zu anderen Paketmanagern anzupassen, wurde +`helm delete` umbenannt zu `helm uninstall`. `helm delete` funktioniert +weiterhin als ALias für `helm uninstall` und kann weiter verwendet werden. + +In Helm 2 wurde die Option `--purge` bereitgestellt, um den Overhead von +Versionsinformationen aufzuräumen. Diese Funktion ist jetzt standardmässig +eingeschaltet. Um sie zu deaktivieren, gibt es die Option +`helm uninstall --keep-history`. + +Zusätzlich wurden verschiedene andere Kommandos in ähnlicher Konvention +umbenannt: + +- `helm inspect` -> `helm show` +- `helm fetch` -> `helm pull` + +Diese Kommandos haben ihre alte Bedeutung als Alias beibehalten, sodass +sie die weiter benutzen können. + +### Automatisch erstellter Namespace + +Wenn eine Version in einem Namespace erstellt wird, der nicht existiert, +hat Helm2 diesen angelegt. Helm 3 folgt den Konventionen von anderen +Kubernetes Werkzeugen und gibt eine Fehlermeldung zurück, wenn der Namespace +nicht existiert. Helm 3 wird den Namespace mit der expliziten Option +`--create-namespace` anlegen. + +### Was passierte mit .Chart.ApiVersion? + +Helm folgt den typischen Konventionen des sogenannten `CamelCasing`, +also dem Grossschreiben von Akronymen. Wir hatten das irgendwo im Code, +wie mit `.Capabilities.APIVersions.Has`. In Helm v3 haben wir das +korrigiert zu `.Chart.ApiVersion`, um der Konvention zu folgen und +`.Chart.APIVersion` umzubenennen. + diff --git a/content/de/docs/faq/installing.md b/content/de/docs/faq/installing.md new file mode 100644 index 0000000000..74e59ccde6 --- /dev/null +++ b/content/de/docs/faq/installing.md @@ -0,0 +1,39 @@ +--- +title: "Installieren" +weight: 2 +--- + +## Installieren + +### Warum gibt es keine nativen Pakete von Helm für Fedora oder andere Linuxdistributionen? + +Das Helm Projekt verwaltet keine Pakete für Betriebssysteme oder Umgebungen. +Die Helm Gemeinschaft stellt möglicherweise native Pakete zur Verfügung +und wenn es genug Aufmerksamkeit in der Gemeinschaft für ein Paket gibt, +wird es vielleicht gelistet. So war es als Homebrew Formular startete und gelistet +wurde. Wenn Sie interessiert sind, ein Paket zu verwalten, würden wir das +sehr begrüssen. + +### Warum stellt Ihr ein `curl ...|bash` Script zur Verfügung? + +Es ist ein Script in unserem Verzeichnis (`scripts/get-helm-3`), was als +`curl ..|bash` ausgeführt werden kann. Die Übertragung ist durch HTTPS gesichert +und das Script macht einige Überprüfungen beim Abruf. Aber egal, dieses +Script hat alle Gefährlichkeiten eines Shellscripts. + +Wir stellen es zur Verfügung, weil es nützlich ist, aber empfehlen den Nutzern, +es vor der ersten Ausführung gründlich zu lesen. Was wir wirklich möchten, +ist eine besser gepackte Version von Helm. + +### Wie lege ich die Dateien vom Helm Programm woanders hin? + +Helm benutzt die XDG Struktur zum Abspeichern von Dateien. Es gibt +Umgebungsvariablen, die diese Lokation überschreiben kann: + +- `$XDG_CACHE_HOME`: Setzt eine alternative Lokation für Zwischenspeicherdateien. +- `$XDG_CONFIG_HOME`: Setzt eine alternative Lokation für Helm Konfiguration. +- `$XDG_DATA_HOME`: Setzt eine alternative Lokation für Helm Daten. + +Beachten Sie, dass Sie existierende Repositories mit dem Kommando +`helm repo add...` neu hinzufügen müssen. + diff --git a/content/de/docs/faq/troubleshooting.md b/content/de/docs/faq/troubleshooting.md new file mode 100644 index 0000000000..97ea1ea5ee --- /dev/null +++ b/content/de/docs/faq/troubleshooting.md @@ -0,0 +1,139 @@ +--- +title: "Fehlersuche" +weight: 4 +--- + +## Fehlersuche + +### Ich bekomme eine Warnung "Unable to get an update from the "stable" chart repository" + +Starten Sie `helm repo list`. Wenn Ihr `stable` Repository zu `storage.googleapis.com` zeigt, +benötigen Sie eine Aktualisierung. Am 13.11.2020 wurde das Helm Chart Verzeichnis +[unsupported](https://github.com/helm/charts#deprecation-timeline), nachdem es ein Jahr lang +als veraltet gekennzeichnet wurde. Ein Archiv ist verfügbar auf +`https://charts.helm.sh/stable`, aber es bekommt keine Aktualisierungen mehr. + +Sie können folgendes tun, um Ihr Repository zu reparieren: + +```console +$ helm repo add stable https://charts.helm.sh/stable --force-update +``` + +Dasselbe gilt für das `incubator` Repository, dessen Archiv verfügbar ist bei +https://charts.helm.sh/incubator. +Zur Reparatur können Sie folgendes Kommando verwenden: + +```console +$ helm repo add incubator https://charts.helm.sh/incubator --force-update +``` + +### Ich bekomme die Warnung 'WARNING: "kubernetes-charts.storage.googleapis.com" is deprecated for "stable" and will be deleted Nov. 13, 2020.' + +Das alte Google Helm Chart Repository wurde ersetzt durch ein neues. + +Starten Sie folgendes Kommando, um das dauerhaft zu beheben: + +```console +$ helm repo add stable https://charts.helm.sh/stable --force-update +``` + +Wenn Sie einen ähnlichen Fehler für `incubator` bekommen, machen Sie folgendes: + +```console +$ helm repo add incubator https://charts.helm.sh/incubator --force-update +``` + +### Wenn ich ein Helm Repo hinzufüge, bekomme ich den Fehler 'Error: Repo "https://kubernetes-charts.storage.googleapis.com" is no longer available' + +Das Helm Chart Repository wird nach [einem Jahr Abschaltperiode](https://github.com/helm/charts#deprecation-timeline) +nicht mehr unterstützt. +Archive für diese Verzeichnisse sind verfügbar unter `https://charts.helm.sh/stable` +und `https://charts.helm.sh/incubator`, aber es werden keine Aktualisierungen mehr +hinzugefügt. Das Kommando `helm repo add` wird das Hinzufügen der alten URLs nicht +erlauben, ausser man verwendet die Option `--use-deprecated-repos`. + +### Auf GKE (Google Container Engine) bekomme ich "No SSH tunnels currently open" + +``` +Error: Error forwarding ports: error upgrading connection: No SSH tunnels currently open. Were the targets able to accept an ssh-key for user "gke-[redacted]"? +``` + +Eine andere Variante des Fehler ist: + +``` +Unable to connect to the server: x509: certificate signed by unknown authority +``` + +Das Problem ist, dass Ihre lokale Kubernetes Konfigurationsdatei die richtigen +Anmeldeinformationen beinhalten muss. + +Wenn Sie in GKE einen Cluster erstellen, werden Sie die Anmeldeinformation incl. +SSL Zertifikate bekommen. Diese müssen in einer Kubernetes Konfigurationsdatei +gespeichert werden (Default: `~/.kube/config`), sodass `kubectl` und `helm` +darauf zugreifen können. + +### Nach der Migration von Helm 2 zeigt `helm list` nur sehr wenige oder gar keine Versionen an + +Es scheint so, dass Sie einige Fakten übersehen haben, dass Helm 3 +nur Versionen im Skope des Cluster Namespaces anzeigt. Das heisst, dass +Sie an allen Kommandos, die eine Version betreffen, diese Optionen +hinzufügen müssen: + +* im derzeitigen Namespace mit aktivem Kontext bleiben (wie beschrieben im + Kommando `kubectl config view --minify`), +* den richtigen Namespace angeben mit der Option `--namespace`/`-n` oder +* für das `helm list` Kommando die Option `--all-namespaces`/`-A` angeben + +Dies wird zu allen Kommandos wie `helm ls`, `helm uninstall` und allen anderen +`helm` Befehlen referenziert zu einer Version hinzugefügt. + +### In macOS kann man auf die Dateie `/etc/.mdns_debug` zugreifen. Warum? + +Wir wissen davon, dass Helm auf macOS versucht, auf eine Datei namens +`/etc/.mdns_debug` zuzugreifen. Wenn die Datei existiert, hält Helm +ein Dateihandle offen, während es ausgeführt wird. + +Das wird durch die macOS MDNS Bibliothek verursacht. Es erwartet, dass die +Datei zur Fehlersuche geladen wird (wenn verfügbar). Das Dateihandle sollte +nicht offen gehalten werden und der Fehler wurde bei Apple gemeldet. +Der Fehler liegt an macOS und nicht Helm. + +Wenn Sie nicht möchten, dass Helm die Datei lädt, könnten Sie Helm selber +übersetzen als statische Bibliothek, dass das Hostnetzwerk nicht benutzt. +Wenn Sie das tun, wird sich die Dateigrösse von Helm stark vergrössern, aber +Sie sind das Problem los. + +Der Fehler war ursächlich als Sicherheitsproblem gemeldet. Aber es hat sich +mittlerweile herausgestellt, dass es kein Problem darstellt. + +### helm repo add schlägt fehl, wenn es schon mal benutzt war + +In Helm 3.3.1 und davor gab das Kommando `helm repo add ` +keine Ausgabe, wenn Sie versucht haben, dass Verzeichnis hinzuzufügen, +wenn es schon vorhanden war. Die Option +`--no-update` würde eine Fehlermeldung ausgeben, wenn das Verzeichnis +schon registriert war. + +In Helm 3.3.2 und davor gibt es beim Versuch das Verzeichnis hinzuzufügen einen +Fehler: + +`Error: repository name (reponame) already exists, please specify a different name` + +Das Standardverhalten ist jetzt umgekehrt. `--no-update` wird jetzt ignoriert, +wenn Sie ein existierendes Verzeichnis ersetzen (überschreiben) wollen. +Sie können die Option `--force-update` verwenden. + +Das ist wegen einer unterbrochenden Änerung für ein Sicherheitsupdate wie +erklärt ist in [Helm 3.3.2 release notes](https://github.com/helm/helm/releases/tag/v3.3.2). + +### Kubernetes Programmprotokoll aktivieren + +Die Ausgabe von Protokollmeldungen zur Fehlersuche können durch die +[klog](https://pkg.go.dev/k8s.io/klog) Option aktiviert werden. +Verwenden Sie die Option `-v` zur Stärke der Ausgabe. + +Zum Beispiel: + +``` +helm list -v 6 +``` diff --git a/content/de/docs/faq/uninstalling.md b/content/de/docs/faq/uninstalling.md new file mode 100644 index 0000000000..ef2a22b394 --- /dev/null +++ b/content/de/docs/faq/uninstalling.md @@ -0,0 +1,24 @@ +--- +title: "Deinstallieren" +weight: 3 +--- + +## Deinstallieren + +### I möchte mein lokales Helm deinstallieren. Wo sind alle Dateien? + +Neben dem eigentlichen `helm` Programm speichert Helm Dateien an folgenden +Orten: + +- $XDG_CACHE_HOME +- $XDG_CONFIG_HOME +- $XDG_DATA_HOME + +Die folgende Tabelle gibt die Standardspeicherorte je Betriebssystem an: + +| Betriebssystem | Zwischenspeicherpfad | Konfigurationspfad | Datenpfad | +|------------------|-----------------------------|----------------------------------|---------------------------| +| Linux | `$HOME/.cache/helm ` | `$HOME/.config/helm ` | `$HOME/.local/share/helm` | +| macOS | `$HOME/Library/Caches/helm` | `$HOME/Library/Preferences/helm` | `$HOME/Library/helm ` | +| Windows | `%TEMP%\helm ` | `%APPDATA%\helm ` | `%APPDATA%\helm` | + diff --git a/content/de/docs/glossary/_index.md b/content/de/docs/glossary/_index.md new file mode 100644 index 0000000000..e754025ed8 --- /dev/null +++ b/content/de/docs/glossary/_index.md @@ -0,0 +1,167 @@ +--- +title: "Glossar" +description: "Benutzte Ausdrücke zur Beschreibung der Komponenten der Helm Architektur." +weight: 9 +--- + +# Glossar + +## Chart + +Ein Helm Paket was Informationen zum Installieren eines Sets von Kubernetes Resourcen +in einem Kubernetes Cluster beinhaltet. + +Charts enthalten eine `Chart.yaml` Datei als auch Vorlagen, Standardwerte +(`values.yaml`) und Abhängigkeiten. + +Charts werden in einer gut definierten Verzeichnisstruktur entwickelt und dann in ein +Archiv gepackt, was sich _Chart Archiv_ nennt. + +## Chart Archiv + +Ein _Chart Archiv_ ist ein mit tar und gzip gepacktes (und optimalerweise signiertes) Chart. + +## Chart Abhängigkeit (Subcharts) + +Charts können voneinander abgängen. Es gibt zwei Wege, diese Abhängigkeit herzustellen: + +- Weiche Abhängigkeit: Ein Chart funktioniert möglicherweise nicht ohne ein anderes Chart. + Helm stellt für diesen Fall kein Werkzeug zur Verfügung. Abhängigkeiten müssen separat + verwaltet werden. +- Harte Abhängigkeit: Ein Chart enthält (innerhalb des `charts/` Verzeichnis) ein + anderes Chart, von dem es abhängt. In diesem Fall wird die Installation des Charts + alle Abhängigkeiten mit installieren. Charts und seine Abhängigkeiten werden als + Kollektion verwaltet. + +Wenn ein Chart gepackt wird (mit `helm package`), werden alle harten Abhängigkeiten mit +gebündelt. + +## Chart Version + +Charts sind versioniert nach [SemVer 2 Spezifikation](https://semver.org). Eine Versionsnummer +ist für jedes Chart erforderlich. + +## Chart.yaml + +Informationen über ein Chart werden in einer speziellen Datei namens `Chart.yaml` gespeichert. +Jedes Chart muss diese Datei haben. + +## Helm (und helm) + +Helm ist der Paket Manager für Kubernetes. Wie ein Paket Manager für das +Betriebssystem das Installieren einfacher macht, kann man mit Helm einfacher +Applikationen und Resourcen in Kubernetes Cluster installieren. + +Da _Helm_ der Name des Projekts ist, trägt das Kommandozeilenprogramm denselben +Namen. Wenn wir vom Projekt sprechen, wird _Helm_ gross geschrieben. Sprechen +wir vom Kommandozeilenprogramm, schreiben wie _helm_ klein. + +## Helm Konfigurationsdateien (XDG) + +Helm speichert seine Konfigurationsdateien in XDG Verzeichnissen. Diese +Verzeichnisse werden erstellt, wenn helm zum ersten mal läuft. + +## Kube Config (KUBECONFIG) + +Das Helm Programm lernt Kubernetes Clusters durch die Benutzung des _Kube +config_ Dateiformats. Standardmässig erwartet Helm, diese Datei an einem Platz +zu finden, wo kubectl es erstellt hat (`$HOME/.kube/config`). + +## Lint (Linting) + +Ein Chart mit _lint_ zu validieren, ist die Überprüfung, ob es den Konventionen +und Anforderungen des Helm Chart Standards genügt. Helm stellt Werkzeuge zur +Verfügung, allen voran das `helm lint` Kommando. + +## Provenance (Provenance file) + +Helm charts können von einem _provenance file_ begleitet sein, welches +Informationen bereitstellt, wo das Chart herkommt und was es beinhaltet. + +Herkunftsdateien (Provenance files) sind ein Teil der Helm Sicherheit. Eine +_provenance_ beinhaltet einen kryptographischen Hash der Chart Archiv Datei, +der Chart.yaml Datei und eines Signaturblockes (ein OpenPGP "clearsign" Block). +Wenn dies an eine Schlüsselkette gekoppelt ist, können Benutzer: + +- validieren, von welchem vertrauenswürdigen Partner das Chart signiert wurde +- validieren, dass die Chart Datei nicht manipuliert wurde +- den Inhalt der Chart Metadaten validieren (`Chart.yaml`) +- schnell vergleichen, dass das Chart mit seinen Herkunftsdaten übereinstimmt + +Herkunftsdateien haben die Erweiterungen `.prov` und können von einem Chart +Verzeichnis Server oder einem anderen HTTP Server ausgeliefert werden. + +## Release (Version) + +Wenn ein Chart installiert ist, erstellt die Helmbibliothek ein Version (_release_), +um nachzuvollziehen, was installiert wurde. + +Ein einzelnes Chart wird möglicherweise mehrmals in denselben Cluster installiert +und erstellt unterschiedliche Versionen. Zum Beispiel, ein Chart kann drei +PostgreSQL Datenbanken mit demselben Kommando `helm install` dreimal mit +unterschiedlchen Versionsnamen installieren. + +## Release Number (Release Version) + +Eine eintelne Version kann mehrmals aktualisiert werden. Ein sequentieller Zähler +wird benutzt, um die Versionen nachzuvollziehen. Nach einem ersten `helm install` +hat eine Version die _release number_ 1. Nach jeder Aktualisierung oder jedem +Zurückrollen wird die Versionsnummer erhöht. + +## Rollback (Zurückrollen) + +Eine Version kann zu einem neuen Chart oder einer neuen Konfiguration +aktualisiert werden. Wenn die Versionshistorie gespeichert ist, +kann eine Version zu einer vorherigen auch zurückgerollt werden (_rolles back_). +Das passiert mit dem `helm rollback` Kommando. + +Wichtig zu wissen, dass eine zurückgerollte Version eine neue Versionsnummer +generiert. + +| Operation | Release Number | +|------------|------------------------------------------------------| +| install | release 1 | +| upgrade | release 2 | +| upgrade | release 3 | +| rollback 1 | release 4 (but running the same config as release 1) | + +Die obige Tabelle zeigt, wie Versionsnummern bei jeder Aktion wie Installieren, +Aktualisieren und Zurückrollen erhöht werden. + +## Helm Library (Helm Bibltiothek oder SDK) + +Die Helm Bibliothek (Library oder SDK) referenziert zum Go Code, der direkt +mit dem Kubernetes API Server zum Installieren, Aktualisieren, Abfragen und +Löschen von Kubernetes Resourcen interagiert. Sie kann zum Import in ein +Projekt benutzt werden, um Helm in einer Bibliothek anstatt des +Kommandozeilenwerkzeugs zu verwenden. + +## Repository (Verzeichnis, Repo, Chart Repository) + +Helm Charts sind gespeichert in dedizierten HTTP Servern namens +_chart repositories_ (_Verzeichnis_, _Repositories_ oder einfach _repos_). + +Ein Chart Repository Server ist ein einfacher HTTP Server, der eine index.yaml +Datei ausliefern kann, die eine Anzahl Charts beschreibt und Informationen +bereitstellt, wo das Chart herunterzuladen ist. +(Viele Chart Repositories liefern die Charts zusammen mit der `index.yam` Datei +aus.) + +Ein Helm Programm kann zu null oder mehreren Chart Verzeichnissen zeigen. +Standardmässig sind keine Verzeichnisse konfiguriert. Chart Verzeichnisse +können mit dem Kommando `helm repo add` hinzugefügt werden. + +## Values (Values/Werte Dateien, values.yaml) + +Values (Werte) stellen einen Weg zur Verfügung, um Standards aus den Vorlagen +zu überschreiben. + +Helm Charts sind "parametisiert", was bedeutet, dass die Chart Entwickler +Konfigurationen nach aussen führen, die zur Installationszeit überschrieben +werden können. Zum Beispiel, ein Chart führt ein `username` Feld nach aussen, +was das Setzen eines Benutzernamens für diesen Dienst erlaubt. + +Diese nach aussen geführten Variablen werden in Helm _values_ genannt. + +Values können während `helm install` und `helm upgrade` gesetzt werden, entweder +direkt beim Aufruf oder in einer `values.yaml` Datei. diff --git a/content/de/docs/howto/_index.md b/content/de/docs/howto/_index.md new file mode 100644 index 0000000000..2c230381f5 --- /dev/null +++ b/content/de/docs/howto/_index.md @@ -0,0 +1,11 @@ +--- +title: "Lernprogramme" +weight: 2 +--- + +# Wie-geht-Anleitungen (How-Tos) + +Hier finden Sie eine schnelle Antwort auf die Fragen “Wie kann ich…?”. Diese Wie-geht- +Anleitungen besprechen die Themen nicht in der Tiefe - dieses Material finden Sie +in den [Themenhandbüchern](/docs/topics). Diese Anleitungen helfen Ihnen zum schnellen +Erfüllen der üblichen Aufgaben. diff --git a/content/de/docs/howto/chart_repository_sync_example.md b/content/de/docs/howto/chart_repository_sync_example.md new file mode 100644 index 0000000000..538cc906db --- /dev/null +++ b/content/de/docs/howto/chart_repository_sync_example.md @@ -0,0 +1,89 @@ +--- +title: "Synchronisieren Ihres Chart Repository" +description: "Beschreibt wie Sie lokale und entfernte Chart Repositories synchronisieren." +weight: 2 +--- + +*Hinweis: Dieses Beispiel richtet sich an einen Google Cloud Storage (GCS) Bucket, +welcher ein Chart Repository bereitstellt.* + +## Vorbedingungen +* Installieren Sie das [gsutil](https://cloud.google.com/storage/docs/gsutil) Werkzeug. + *Wir lehnen uns stark an die gsutil rsync Funktionalität* +* Stellen Sie sicher, dass Sie Zugriff auf das Helm Programm haben +* _Optional: Wir empfehlen, dass Sie die [Objektversionierung](https://cloud.google.com/storage/docs/gsutil/addlhelp/ObjectVersioningandConcurrencyControl#top_of_page) in Ihrem GCS Bucket gesetzt haben, falls Sie etwas versehentlich löschen._ + +## Ein lokales Chart Repository Verzeichnis aufsetzen +Erstellen Sie ein lokales Verzeichnis wie wir es im [Chart Repository Handbuch]({{< relref +path="/docs/topics/chart_repository.md" lang="en">}}) gemacht haben und legen Sie Ihr Chart Paket +in das Verzeichnis. + +Zum Beispiel: +```console +$ mkdir fantastic-charts +$ mv alpine-0.1.0.tgz fantastic-charts/ +``` + +## Generieren einer aktualisierten index.yaml +Benutzen Sie Helm zum Generieren einer aktualisierten index.yaml Datei durch Aufruf des +Verzeichnisses und der URL des entfernten Repositorry durch das `helm repo index` Kommando wie: + +```console +$ helm repo index fantastic-charts/ --url https://fantastic-charts.storage.googleapis.com +``` +Dies wird eine aktualisierte index.yaml Datei erstellen und in das Verzeichnis +`fantastic-charts/` legen. + +## Synchronisieren Ihrer lokalen und entfernten Chart Repositories +Laden Sie den Inhalt des Verzeichnisses in Ihren GCS Bucket, indem Sie das Programm +`scripts/sync-repo.sh` aufrufen und im lokalen Verzeichnis den Verzeichnisnamen und den +Namen des GCS Bucket angeben. + +Zum Beispiel: +```console +$ pwd +/Users/me/code/go/src/helm.sh/helm +$ scripts/sync-repo.sh fantastic-charts/ fantastic-charts +Getting ready to sync your local directory (fantastic-charts/) to a remote repository at gs://fantastic-charts +Verifying Prerequisites.... +Thumbs up! Looks like you have gsutil. Let's continue. +Building synchronization state... +Starting synchronization +Would copy file://fantastic-charts/alpine-0.1.0.tgz to gs://fantastic-charts/alpine-0.1.0.tgz +Would copy file://fantastic-charts/index.yaml to gs://fantastic-charts/index.yaml +Are you sure you would like to continue with these changes?? [y/N]} y +Building synchronization state... +Starting synchronization +Copying file://fantastic-charts/alpine-0.1.0.tgz [Content-Type=application/x-tar]... +Uploading gs://fantastic-charts/alpine-0.1.0.tgz: 740 B/740 B +Copying file://fantastic-charts/index.yaml [Content-Type=application/octet-stream]... +Uploading gs://fantastic-charts/index.yaml: 347 B/347 B +Congratulations your remote chart repository now matches the contents of fantastic-charts/ +``` +## Aktualisieren Ihres Chart Repository +Sie möchten eine lokale Kopie des Inhalts Ihres Chart Repository behalten oder +`gsutil rsync` zum Kopieren des Inhalts Ihres entfernten Chart Repository zu Ihrem lokalen +Verzeichnis verwenden. + +Zum Beispiel: +```console +$ gsutil rsync -d -n gs://bucket-name local-dir/ # the -n flag does a dry run +Building synchronization state... +Starting synchronization +Would copy gs://bucket-name/alpine-0.1.0.tgz to file://local-dir/alpine-0.1.0.tgz +Would copy gs://bucket-name/index.yaml to file://local-dir/index.yaml + +$ gsutil rsync -d gs://bucket-name local-dir/ # performs the copy actions +Building synchronization state... +Starting synchronization +Copying gs://bucket-name/alpine-0.1.0.tgz... +Downloading file://local-dir/alpine-0.1.0.tgz: 740 B/740 B +Copying gs://bucket-name/index.yaml... +Downloading file://local-dir/index.yaml: 346 B/346 B +``` + +Hilfreiche Links: +* Dokumentation von [gsutil + rsync](https://cloud.google.com/storage/docs/gsutil/commands/rsync#description) +* [Das Chart Repository Handbuch]({{< relref path="/docs/topics/chart_repository.md" lang="en">}}) +* Documentation von [Objekt Versionierung und parallele Zugriffe](https://cloud.google.com/storage/docs/gsutil/addlhelp/ObjectVersioningandConcurrencyControl#overview) in Google Cloud Storage diff --git a/content/de/docs/howto/charts_tips_and_tricks.md b/content/de/docs/howto/charts_tips_and_tricks.md new file mode 100644 index 0000000000..1416143d8e --- /dev/null +++ b/content/de/docs/howto/charts_tips_and_tricks.md @@ -0,0 +1,314 @@ +--- +title: "Chart Entwicklung Tipps und Tricks" +description: "Bespricht Tipps und Tricks,die Helm Chart Entwickler bei der Entwicklung von produktionsreifer Charts gelernt haben." +weight: 1 +--- + +Dieses Handbuch bespricht Tipps und Tricks, die Helm Chart Entwickler bei der Entwicklung von produktionsreifen Charts gelernt haben. + +## Kenne Deine Vorlagenfunktionen + +Helm benutzt [Go Templates](https://godoc.org/text/template) für Vorlagen Ihrer +Resourcedateien. Wobei Go schon einige eingebauten Funktionen mitbringt, haben wir +noch viele andere hinzugefügt. + +Als erstes haben wir alle Funktionen in der [Sprig +Bibliothek](https://masterminds.github.io/sprig/) hinzugefügt. + +Wir haben auch zwei spezielle Vorlagenfunktionen hinzugefügt: `include` und `required`. Die +`include` Funktion erlaubt Ihnen das Hinzufügen anderer Vorlagen und das Zusammenfügen des +Ergebnisses in einer anderen Vorlagenfunktion. + +Zum Beispiel diese Vorlage inkludiert eine Vorlage namens `mytpl`, +dann wandelt es diese in Kleinschreibung um und quotet diese mit doppelten Anführungszeichen. + +```yaml +value: {{ include "mytpl" . | lower | quote }} +``` + +Die `required` Function erlaubt Ihnen die Deklaration eines Wertes als notwendig für das +Vorlagenrendering. Wenn der Wert leer ist, wird das Vorlagenrendern fehlschlagen und dem +Benutzer eine Fehlermeldung ausgeben. + +Das folgende Beispiel der `required` Funktion deklariert einen Eintrag für +`.Values.who`, der notwendig ist und gibt einen Fehler aus, wenn dieser fehlt: + +```yaml +value: {{ required "A valid .Values.who entry required!" .Values.who }} +``` + +## Strings quoten, Integers nicht quoten + +Wenn Sie mit Strings arbeiten, sind Sie mit Quoten immer auf der sicheren Seite: + +```yaml +name: {{ .Values.MyName | quote }} +``` + +Aber wenn Sie mit Integers arbeiten _quoten Sie nicht die Werte._ Das kann in vielen +Fällen zu Fehlern in Kubernetes führen. + +```yaml +port: {{ .Values.Port }} +``` + +Dieser Hinweis gilt nicht für Umgebungsvariablen, die immer als String erwartet werden, +auch wenn sie Integers repräsentieren: + +```yaml +env: + - name: HOST + value: "http://host" + - name: PORT + value: "1234" +``` + +## Benutzen der 'include' Funktion + +Go hat die Möglichkeit über eine eingebaute Funktion `template` zwei Vorlagen zu +verbinden. Leider kann diese eingebaute Funktion nicht in Go Vorlagen Pipelines +verwendet werden. + +Um das zu ermöglichen, eine Vorlage zu inkludieren und die Vorlagenausgabe weiter +zu bearbeiten, hat Helm eine spezielle `include` Funktion: + +``` +{{ include "toYaml" $value | indent 2 }} +``` + +Dies inkludiert eine Vorlage namens `toYaml`, gibt das `$value` mit und +gibt dann die Ausgabe der Vorlage an die `indent` Funktion weiter. + +Da YAML Einrückungen und Leerzeichen viel Bedeutung zumisst, ist das ein +grossartiger Weg um Codeschnippsel zu inkludieren, aber die Einrückungen +im relevaten Kontext zu halten. + +## Benutzung der 'required' Funktion + +Go stellt einen Weg zur Verfügung, um Vorlagenoptionen zu setzen und so das +Verhalten zu beeinflussen, wenn eine Map mit einem Schlüssel indiziert wird, +der in der Map nicht vorhanden ist. Das ist typischerweise gesetzt mit +`template.Options("missingkey=option")`, wobei `option` `default` sein kann, +`zero` oder `error`. Wenn diese Option zu error gesetzt ist, wird die Ausführung +gestoppt, wennimmer der Wert leer ist. Es gibt Situationen, wenn Chart Entwickler +dieses Verhalten für bestimmte Werte in der `values.yaml` Datei hervorrufen möchten. + +Die `required` Funktion gibt Entwicklern die Möglichkeit, einen Werteintrag zu +deklarieren, der für das Vorlagenrendern notwendig ist. Wenn der Wert in `values.yaml` +leer ist, wird die Vorlage nicht gerendert und eine Fehlermeldung wird vom Entwickler +bereitgestellt. + +Zum Beispiel: + +``` +{{ required "A valid foo is required!" .Values.foo }} +``` + +Das oben wird eine Vorlage rendern, wenn `.Values.foo` definiert ist, aber fehlschlagen, +wenn `.Values.foo` nicht definiert ist. + +## Benutzen der 'tpl' Funktion + +Die `tpl` Funktion erlaubt Entwicklern Strings als Vorlagen in Vorlagen zu evaluieren. +Das ist nützlich, um einen Vorlagenstring als Wert zu einem Chart oder zum Rendern +einer externen Konfigurationsdatei zu verwenden. Syntax: `{{ tpl TEMPLATE_STRING VALUES }}` + +Beispiele: + +```yaml +# values +template: "{{ .Values.name }}" +name: "Tom" + +# template +{{ tpl .Values.template . }} + +# output +Tom +``` + +Rendern einer externen Konfigurationsdatei: + +```yaml +# external configuration file conf/app.conf +firstName={{ .Values.firstName }} +lastName={{ .Values.lastName }} + +# values +firstName: Peter +lastName: Parker + +# template +{{ tpl (.Files.Get "conf/app.conf") . }} + +# output +firstName=Peter +lastName=Parker +``` + +## Erstellen eines Image Pull Secrets +Image Pull Secrets sind eine Kombination aus _registry_, _username_ und +_password_. Sie brauchen sie vielleicht in einer Applikation, die Sie +bereitstellen möchten, aber zum Erstellen brauchen Sie öfters `base64`. +Wir können eine Hilfsvorlage erstellen, um die Docker Konfigurationsdatei +mit einem Secret Payload zu erstellen. Hier kommt das Beispiel: + +Zuerst nehmen wir an, dass die Zugangsdaten in der `values.yaml` Datei definiert +sind, wie: + +```yaml +imageCredentials: + registry: quay.io + username: someone + password: sillyness + email: someone@host.com +``` + +Wir definieren dann unsere Hilfsvorlage wie folgt: + +``` +{{- define "imagePullSecret" }} +{{- with .Values.imageCredentials }} +{{- printf "{\"auths\":{\"%s\":{\"username\":\"%s\",\"password\":\"%s\",\"email\":\"%s\",\"auth\":\"%s\"}}}" .registry .username .password .email (printf "%s:%s" .username .password | b64enc) | b64enc }} +{{- end }} +{{- end }} +``` + +Zum Schluss verwenden wir die Hilfsvorlage in einer grösseren Vorlage, um +das Secret Manifest zu erstellen: + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: myregistrykey +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +``` + +## Automatisierte Bereitstellungen + +Sehr oft werden ConfigMaps oder Secrets als Konfigurationsdateien in Container injiziert +oder dort sind andere externe Abhängigkeiten, was einen Pod Restart erforderlich macht. +Abhängig von der Applikation sollte ein Restart eine Aktualsierung durch `helm upgrade` +auslösen, aber die Deployment-Spezifikation selber ändert sich nicht und lässt die alte +Konfiguration als Ergebnis inkonsistent in der Bereitstellung. + +Die `sha256sum` Funktion kann benutzt werden, um in der Annotation Sektion des Deployments +dieses zu aktualisieren, wenn sich die Datei geändert hat. + + +```yaml +kind: Deployment +spec: + template: + metadata: + annotations: + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} +[...] +``` + +In einem Ereignis, wenn Sie sowieso Ihr Deployment neu starten wollen, können +Sie einen ähnlichen Schritt mit der Annotation gehen wie oben, aber diese +mit einem zufälligen String ersetzen, sodass es immer eine Änderung gibt und +diese einen Restart der Bereitstellung hervorruft: + +```yaml +kind: Deployment +spec: + template: + metadata: + annotations: + rollme: {{ randAlphaNum 5 | quote }} +[...] +``` + +Jede Benutzung dieser Vorlagenfunktion wird einen einzigartigen zufälligen +String generieren. Das bedeutet, wenn dieser zufällige String mit mehreren +Resourcen synchronisiert werden soll, müssen sich alle relevanten Resourcen +in derselben Vorlagendatei befinden. + +Beide Methoden helfen Ihnen, Ihre Aktualisierungsstrategie zu planen und Ausfälle +zu verhindern. + +HINWEIS: In der Vergangenheit empfohlen wir die Benutzung der Option +`--recreate-pods`. Diese Option ist als veraltet markiert und in Helm 3 +favorisieren wir die Methoden oben. + +## Helm anweisen, keine Resourcen zu installieren + +Manchmal sollen Resourcen von Helm nicht deinstalliert werden, wenn Helm +läuft mit `helm uninstall`. Chart Entwickler können eine Annotation zu einer +Resource hinzufügen, um das zu verhindern. + +```yaml +kind: Secret +metadata: + annotations: + "helm.sh/resource-policy": keep +[...] +``` + +(Als notwendig markieren) + +Die Annotation `"helm.sh/resource-policy": keep` instruiert Helm, das Löschen +dieser Resource bei Kommandos wie `helm uninstall`, `helm upgrade` oder +`helm rollback` zu übergehen, was normalerweise zum Löschen führen würde. +Helm wird diese nicht länger verwalten. Das kann zu Problemen führen, +etwa bei `helm install --replace` bei einer Version, die schon deinstalliert +ist, aber diese Resourcen behalten hat. + +## Benutzung von "Partials" und inkludierten Vorlagen + +Manchmal möchten Sie Teile Ihres Charts wiederverwenden, in einem Block +oder Vorlagenteile. Oft ist es sauberer, die in einer eigenen Datei +vorzuhalten. + +Im `templates/` Verzeichnis werden Dateien, die mit einem Unterstrich +beginnen (`_`), nicht als Ausgabedateien für Kubernetes Manifeste betrachtet. +Mit dieser Konvention, werden Hilfsvorlagen und Teile in eine +`_helpers.tpl` Datei platziert. + +## Komplexe Charts mit vielen Abhängigkeiten + +Viele Charts im CNCF [Artifact +Hub](https://artifacthub.io/packages/search?kind=0) sind "building blocks" zum +Erstellen erweiterter Applikationen. Aber Charts werden verwendet, zum Aufbau +von Instanzen hochskalierbarer Anwendungen. In diesem Fall kann ein Schirm-Chart +viele Unter-Charts haben, jede mit einer Funktion als Teil des Ganzen. + +Die derzeitige Praxis zum Komponieren einer komplexten Applikation von +einzelnen Teilen ist ein Schirm-Chart auf höchster Stufe mit exponierten +globalen Konfigurationswerten und dann benutzen des `charts/` Unterverzeichnis +zum Einschluss aller Komponenten. + +## YAML als Überschreibung von JSON + +Entsprechend der Beschreibung der YAML Spezifikation ist YAML eine Überschreibung +von JSON. Das bedeutet, dass jede valide JSON Struktur auch valide in YAML ist. + +Dies hat Vorteile: Manchmal finden es Vorlagenentwickler einfacher eine +Datenstruktur in JSON-ähnlicher Syntax anzugeben, anstatt sich mit dem leerzeichensensitiven +YAML abzugeben. + +Als bewährte Methode sollten Vorlagen einer YAML-ähnlichen Syntax folgen, unabhängig vom JSON. +Die Syntax reduziert das Risiko eines Formatierungsproblems erheblich. + +## Vorsicht bei zufallsgenerierten Werten + +Es gibt Funktionen in Helm, die zufällige Daten generieren, kryptographische Schlüssel usw.. +Das ist gut so, aber achten Sie darauf, dass diese bem Aktualisieren und Rendern nochmal +ausgeführt werden. Wenn eine Vorage unterschiedliche Daten wie beim letzten Lauf generiert, +triggert das eine Aktualisierung der Resource. + +## Installieren oder Aktualisieren einer Version mit einem Kommando + +Helm stellt einen Weg zur Verfügung, um Installation und Aktualisierung in einem Kommando +aufzurufen. Benutzen Sie `helm upgrade` mit dem `--install` Kommando. Das veranlasst Helm +erst nachzuschauen, ob eine Version schon installiert ist, bevor es sie installiert. +Wenn sie vorhanden ist, wird Helm die existierende Version aktualisieren. + +```console +$ helm upgrade --install --values +``` diff --git a/content/de/docs/intro/_index.md b/content/de/docs/intro/_index.md new file mode 100644 index 0000000000..f4993cb733 --- /dev/null +++ b/content/de/docs/intro/_index.md @@ -0,0 +1,8 @@ +--- +title: "Einführung" +weight: 1 +--- + +# Einführung in Helm + +Neu in Helm? Hier ist der Weg zum Start! diff --git a/content/de/docs/intro/install.md b/content/de/docs/intro/install.md new file mode 100644 index 0000000000..897ec92a74 --- /dev/null +++ b/content/de/docs/intro/install.md @@ -0,0 +1,161 @@ +--- +title: "Helm installieren" +description: "Lernen Sie wie man Helm installiert und zum Laufen kriegt." +weight: 2 +--- + +Diese Anleitung zeigt, wie Helm CLI zu installieren ist. Helm kann sowohl +vom Quellcode als auch vorkompilierten Binaries installiert werden. + +## Vom Helm Projekt + +Das Helm Projekt stellt zwei Wege zum Beziehen und Installieren von Helm zur +Verfügung. Dies sind die offiziellen Methoden, um Helm Versionen zu bekommen. +Zusätzlich zu dem stellt die Helm Gemeinschaft Methoden zur Installation +mit verschiedenen Paketmanagern zur Verfügung. Die Installation mit diesen +Methoden können am Ende der Anleitung zu den offiziellen Methoden gelesen +werden. + +### Von Binary Versionen + +Jede [Version](https://github.com/helm/helm/releases) von Helm stellt Binary +Versionen für verschiedene Betriebssysteme zur Verfügung. Diese Binary Versionen +kann man herunterladen und installieren. + +1. Laden Sie die [gewünschte Version](https://github.com/helm/helm/releases) herunter +2. Entpacken Sie diese (`tar -zxvf helm-v3.0.0-linux-amd64.tar.gz`) +3. Finden Sie das Helm Binary im entpackten Verzeichnis und verschieben es zum + gewünschten Ziel (`mv linux-amd64/helm /usr/local/bin/helm`) + +Von dort aus sollten Sie in der Lage sein, das Programm aufzurufen und ein +[erstes Repo hinzuzufügen](https://helm.sh/docs/intro/quickstart/#initialize-a-helm-chart-repository): +`helm help`. + +**Hinweis:** In den automatisierten Tests von Helm wird nur die Version von +Linux AMD64 beim Bau durch CircleCi berücksichtig. Das Testen von anderen +Betriebssystemen liegt in der Zuständigkeit der Gemeinschaft. + +### Von einem Script + +Helm hat ein Installations-Script, mit der automatisch die neueste Version +bezogen und [lokal installiert wird](https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3). + +Sie können dieses Script aufrufen und lokal ausführen. Es ist gut dokumentiert, +so dass Sie es lesen und gut verstehen können, bevor Sie es ausführen. + +```console +$ curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 +$ chmod 700 get_helm.sh +$ ./get_helm.sh +``` + +Ja, Sie können auch `curl +https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash` if +aufrufen, wenn Sie am Rande des Abgrunds leben. + +## Durch einen Paket Manager + +Die Helm Gemeinschaft stellt auch die Möglichkeit der Installation durch einen +Paket Managers des Betriebssystems zur Verfügung. Diese werden vom Helm Projekt +nicht unterstützt und haben den Status einer dritten Partei (3rd party software). + +### Von Homebrew (macOS) + +Mitglieder der Helm Gemeinschaft haben eine Form des Baus durch Homebrew zur +Verfügung gestellt. Diese Form ist generell immer aktuell. + +```console +brew install helm +``` + +(Hinweis: Es gibt noch eine Form von emacs-helm, was ein anderes Projekt ist.) + +### Von Chocolatey (Windows) + +Mitglieder der Helm Gemeinschaft haben ein [Helm +Paket](https://chocolatey.org/packages/kubernetes-helm) gebaut mit +[Chocolatey](https://chocolatey.org/) beigetragen. Dieses Paket ist generell aktuell. + +```console +choco install kubernetes-helm +``` + +### Von Apt (Debian/Ubuntu) + +Mitglieder der Helm Gemeinschaft haben ein [Helm +Paket](https://helm.baltorepo.com/stable/debian/) for Apt beigetragen. Dieses Paket +ist generell aktuell. + +```console +curl https://baltocdn.com/helm/signing.asc | sudo apt-key add - +sudo apt-get install apt-transport-https --yes +echo "deb https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list +sudo apt-get update +sudo apt-get install helm +``` + +### Von Snap + +Die [Snapcrafters](https://github.com/snapcrafters) Gemeinschaft unterstützt die Snap +Version vom [Helm Paket](https://snapcraft.io/helm): + +```console +sudo snap install helm --classic +``` + +### Von pkg (FreeBSD) + +Mitglieder der Helm Gemeinschaft haben ein [Helm +Paket](https://www.freshports.org/sysutils/helm) gebaut für +[FreeBSD Ports Collection](https://man.freebsd.org/ports) beigetragen. +Dieses Paket ist generell aktuell. + +```console +pkg install helm +``` + +### Entwickler Builds + +Zusätzlich zu den Versionen können auch Entwicklerkopien von Helm installiert +werden. + +### Von Canary Builds + +"Canary" Builds sind Versionen der Helm Software gebaut vom letzten Master Zweig. +Das sind keine offizielle Versionen und sind möglichweise nicht stabil. Sie bieten +die Möglichkeit, die neuesten Funktionen zu testen. + +Canary Helm Binaries sind gespeichert auf [get.helm.sh](https://get.helm.sh). Hier +sind die Links zu den üblichen Builds: + +- [Linux AMD64](https://get.helm.sh/helm-canary-linux-amd64.tar.gz) +- [macOS AMD64](https://get.helm.sh/helm-canary-darwin-amd64.tar.gz) +- [Experimental Windows + AMD64](https://get.helm.sh/helm-canary-windows-amd64.zip) + +### Vom Quellcode (Linux, macOS) + +Das Bauen von Helm vom Quellcode ist ein bischen komplizierter, aber es ist +die beste Möglichkeit, die letzte (vor-veröffentlichte) Version von Helm +zu testen. + +Sie brauchen eine Go Arbeitsumgebung. + +```console +$ git clone https://github.com/helm/helm.git +$ cd helm +$ make +``` + +Wenn erforderlich, werden die Abhängigkeiten heruntergeladen und zwischengespeichert. +Die Konfuguration wird validiert und Helm kompiliert nach `bin/helm`. + +## Zusammenfassung + +In den meisten Fällen ist die Installation einfach durch das Beziehen der vorkompilierten +Helm Binaries. Dieses Dokument deckt zusätzliche Fälle ab für Leute, die anspruchsvolle +Dinge mit Helm bewerkstelligen wollen. + +Wenn Sie das Helm Programm erfolgreich installiert haben, können Sie zur Verwaltung +von Charts und [Hinzufügen des stabilen Repos](https://helm.sh/docs/intro/quickstart/#initialize-a-helm-chart-repository) +wechseln. diff --git a/content/de/docs/intro/quickstart.md b/content/de/docs/intro/quickstart.md new file mode 100644 index 0000000000..4773ecba02 --- /dev/null +++ b/content/de/docs/intro/quickstart.md @@ -0,0 +1,135 @@ +--- +title: "Schnellstartanleitung" +description: "Wie mit Helm anfangen, incl. Anleitungen für Distributionen, FAQs und Plugins." +weight: 1 +--- + +Mit dieser Anleitung können Sie schnell mit Helm starten. + +## Vorbedingungen + +Die folgenden Vorbedingungen sind erforderlich, um Helm erfolgreich und sicher +zu nutzen. + +1. Ein Kubernetes Cluster +2. Entscheiden, welche Sicherheitskonfigurationen zur Installation verwendet werden +3. Installieren und konfigurieren von Helm. + +### Installieren von Kubernetes oder Zugriff auf einen Cluster haben + +- Sie müssen Kubernetes installiert haben. Für die letzte Version von Helm + empfehlen wir die letzte stabile Version von Kubernetes, was in den meisten + Fällen die zweitletzte Unterversion ist. +- Sie sollten eine lokale Kopie eines konfigurierten kubectl haben. + +Sehen Sie die [Helm Version Support Policy](https://helm.sh/docs/topics/version_skew/) +für die maximal unterstützte Version zwischen Helm und Kubernetes. + +## Installieren von Helm + +Laden Sie eine Binary Version von Helm herunter. Sie können Werkzeuge verwenden wie homebrew +oder schauen Sie auf [die offizielle Versionsseite](https://github.com/helm/helm/releases). + +Für mehr Details oder weitere Optionen schauen Sie in die [Installationsanleitung]({{< ref +"install.md" >}}). + +## Initialisieren eines Helm Chart Repository + +Wenn Sie Helm installiert haben, können Sie ein Chart Repository hinzufügen. Schauen Sie nach +[Artifact Hub](https://artifacthub.io/packages/search?kind=0) für verfügbare Helm Chart +Repositories. + +```console +$ helm repo add bitnami https://charts.bitnami.com/bitnami +``` + +Einmal installiert können Sie die installierbaren Charts auflisten: + +```console +$ helm search repo bitnami +NAME CHART VERSION APP VERSION DESCRIPTION +bitnami/bitnami-common 0.0.9 0.0.9 DEPRECATED Chart with custom templates used in ... +bitnami/airflow 8.0.2 2.0.0 Apache Airflow is a platform to programmaticall... +bitnami/apache 8.2.3 2.4.46 Chart for Apache HTTP Server +bitnami/aspnet-core 1.2.3 3.1.9 ASP.NET Core is an open-source framework create... +# ... and many more +``` + +## Installieren eines Beispiel Chart + +Um ein Chart zu installieren, können Sie das `helm install` Kommando verwenden. +Helm kennt verschieden Wege, um ein Chart zu finden und zu installieren, aber +am einfachsten ist die Verwendung des `bitnami` Charts. + +```console +$ helm repo update # Make sure we get the latest list of charts +$ helm install bitnami/mysql --generate-name +NAME: mysql-1612624192 +LAST DEPLOYED: Sat Feb 6 16:09:56 2021 +NAMESPACE: default +STATUS: deployed +REVISION: 1 +TEST SUITE: None +NOTES: ... +``` + +Im Beispiel oben wurde das `bitnami/mysql` Chart versioniert und der Name +der neuen Version ist `mysql-1612624192`. + +Sie kriegen eine grobe Idee über die Funktionen dieses MySQL Charts mit dem +Kommando `helm show chart bitnami/mysql`. Oder dem Kommando `helm show all bitnami/mysql`, +um alle Informationen über das Chart zu bekommen. + +Wennimmer Sie ein Chart installieren, wird eine neue Version erstellt. So kann +ein Chart beliebig oft im selben Cluster installiert und unabhängig verwaltet und +aktualisiert werden. + +Das `helm install` Kommando ist ein sehr mächtiges Kommand mit vielen Möglichkeiten. +Um mehr darüber zu lernen, schauen Sie ins [Helm Benutzerhandbuch]({{< ref "using_helm.md" +>}}) + +## Mehr über Versionen lernen + +Es ist einfach zu sehen, was durch Helm versioniert wurde: + +```console +$ helm ls +NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION +mysql-1612624192 default 1 2021-02-06 16:09:56.283059 +0100 CET deployed mysql-8.3.0 8.0.23 +``` + +Die `helm list` Funktion wird Ihnen eine Liste auf alle installierten Versionen zeigen. + +## Eine Version deinstallieren + +Um eine Version zu deinstallieren, benutzen Sie das `helm uninstall` Kommando: + +```console +$ helm uninstall mysql-1612624192 +release "mysql-1612624192" uninstalled +``` + +Das wird `mysql-1612624192` von Kubernetes deinstallieren, was wiederum alle +Resourcen löscht, die mit dieser Version verbunden sind, genauso wie die Versionshistorie. + +Wenn die Option `--keep-history` verwendet wird, bleibt die Versionshistorie erhalten. +So können Sie Informationen über diese Version erhalten: + +```console +$ helm status mysql-1612624192 +Status: UNINSTALLED +... +``` + +Weil Helm Ihre Versionen nachverfolgt, nachdem Sie es deinstalliert hat, können Sie +die Historie des Clusters auditieren und immer eine gelöschte Version zurückholen +(mit `helm rollback`). + +## Die Hilfe lesen + +Um mehr über die verfügbaren Helm Kommandos zu lesen, benutzen Sie `helm help` oder +tippen das Kommando gefolgt von einem `-h` ein: + +```console +$ helm get -h +``` diff --git a/content/de/docs/intro/using_helm.md b/content/de/docs/intro/using_helm.md new file mode 100644 index 0000000000..3fee99680f --- /dev/null +++ b/content/de/docs/intro/using_helm.md @@ -0,0 +1,500 @@ +--- +title: "Helm benutzen" +description: "Erklärt die Grundsätze zu Helm." +weight: 3 +--- + +Diese Anleiting erklärt die Grundsätze zu Helm, um Pakete in Ihrem Kubernetes +Cluster zu verwalten. Es wird erwartet, dass Sie das Helm Programm bereits +[installiert]({{< ref "install.md" >}}) haben. + +Wenn Sie nur daran interessiert, ein paar einfache Kommandos schnell zu lernen, +beginnen Sie mit der [Schnellstartanleitung]({{< ref "quickstart.md" >}}). +Dieses Kapitel erklärt die speziellen Helm Kommandos und erklärt, wie +Helm zu benutzen ist. + +## Drei grosse Konzepte + +Ein *Chart* ist ein Helm Paket. Es beinhaltet alle Resourcedefinitionen, die zur +Ausführung einer Applikation, eines Werkzeugs oder Dienstes im Kubernetes +Cluster erforderlich sind. Denken Sie an etwas wie ein Homebrew Formular für +Kubernetes, ein Apt dpkg oder eine Yum RPM Datei. + +Ein *Repository* ist ein Platz, wo Charts gesammelt und gespeichert werden können. +Es ist wie Perl's [CPAN Archiv](https://www.cpan.org) oder die [Fedora Package +Database](https://src.fedoraproject.org/), aber für Kubernetes Pakete. + +Ein(e) *Release/Version* ist eine Instanz von einem Chart, welches in einem +Kubernetes Cluster läuft. Ein Chart kann beliebig oft im selben Cluster +installiert werden. Und immer wenn es neu installiert wird, wird ein neues +_release_ erstellt. Denken Sie an ein MySQL Chart. Wenn Sie zwei laufende +Datenbanken in Ihrem Cluster haben möchten, können Sie dieses Chart zweimal +installieren. Jedes bekommt sein eigenes _release_, welches sich über seinen +eigenen _release_name_ identifiziert. + +Mit diesem Konzept im Hinterkopf, können wir das Helm Konzept erklären wie: + +Helm installiert _charts_ in Kubernetes, erstellt ein neues _release_ für jede +Installation. Und zur Suche nach neuen Charts, können Sie Helm Chart _repositories_ durchsuchen. + +## 'helm search': Charts finden + +Helm kommt mit einem mächtigen Suchkommando. Es kann zwei verschiedene Quelltypen suchen: + +- `helm search hub` sucht [den Artifact Hub](https://artifacthub.io), welches + Helm Charts von dutzenden unterschiedlichen Repositories listet. +- `helm search repo` sucht das Repositorie, welches Sie lokal in Ihrem Helm + Programm hinzugefügt haben (mit `helm repo add`). Diese Suche wird über lokale Daten + durchgeführt, ohne das eine öffentliche Netzwerkverbindung notwendig ist. + +Sie können öffentlich verfügbare Charts finden mit dem Kommando `helm search hub`: + +```console +$ helm search hub wordpress +URL CHART VERSION APP VERSION DESCRIPTION +https://hub.helm.sh/charts/bitnami/wordpress 7.6.7 5.2.4 Web publishing platform for building blogs and ... +https://hub.helm.sh/charts/presslabs/wordpress-... v0.6.3 v0.6.3 Presslabs WordPress Operator Helm Chart +https://hub.helm.sh/charts/presslabs/wordpress-... v0.7.1 v0.7.1 A Helm chart for deploying a WordPress site on ... +``` + +Die obige Suche nach allen `wordpress` Charts auf Artifact Hub. + +Ohne Filter zeigt `helm search hub` alle verfügbaren Charts. + +Wenn Sie `helm search repo` benutzen, können Sie alle Namen von Charts +in Repositories finden, die Sie schon hinzugefügt haben: + +```console +$ helm repo add brigade https://brigadecore.github.io/charts +"brigade" has been added to your repositories +$ helm search repo brigade +NAME CHART VERSION APP VERSION DESCRIPTION +brigade/brigade 1.3.2 v1.2.1 Brigade provides event-driven scripting of Kube... +brigade/brigade-github-app 0.4.1 v0.2.1 The Brigade GitHub App, an advanced gateway for... +brigade/brigade-github-oauth 0.2.0 v0.20.0 The legacy OAuth GitHub Gateway for Brigade +brigade/brigade-k8s-gateway 0.1.0 A Helm chart for Kubernetes +brigade/brigade-project 1.0.0 v1.0.0 Create a Brigade project +brigade/kashti 0.4.0 v0.4.0 A Helm chart for Kubernetes +``` + +Die Helm Suche benutzt ein Fuzzy String Matching Algorithmus, wodurch +Sie Teile von Wortphrasen eingeben können: + +```console +$ helm search repo kash +NAME CHART VERSION APP VERSION DESCRIPTION +brigade/kashti 0.4.0 v0.4.0 A Helm chart for Kubernetes +``` + +Sie Suche ist ein guter Weg, um alle verfügbaren Pakete zu finden. Wennimmer +Sie ein Paket gefunden haben, können Sie es mit `helm install` installieren. + +## 'helm install': Ein Paket installieren + +Benutzen Sie das `helm install` Kommando, um ein neues Helm Paket zu installieren. +Am einfachsten hat das Kommando zwei Argumente: Einen Versionsnamen, den Sie gewählt +haben und den Namen des Charts, dass Sie installieren möchten. + +```console +$ helm install happy-panda bitnami/wordpress +NAME: happy-panda +LAST DEPLOYED: Tue Jan 26 10:27:17 2021 +NAMESPACE: default +STATUS: deployed +REVISION: 1 +NOTES: +** Please be patient while the chart is being deployed ** + +Your WordPress site can be accessed through the following DNS name from within your cluster: + + happy-panda-wordpress.default.svc.cluster.local (port 80) + +To access your WordPress site from outside the cluster follow the steps below: + +1. Get the WordPress URL by running these commands: + + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + Watch the status with: 'kubectl get svc --namespace default -w happy-panda-wordpress' + + export SERVICE_IP=$(kubectl get svc --namespace default happy-panda-wordpress --template "{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}") + echo "WordPress URL: http://$SERVICE_IP/" + echo "WordPress Admin URL: http://$SERVICE_IP/admin" + +2. Open a browser and access WordPress using the obtained URL. + +3. Login with the following credentials below to see your blog: + + echo Username: user + echo Password: $(kubectl get secret --namespace default happy-panda-wordpress -o jsonpath="{.data.wordpress-password}" | base64 --decode) +``` + +Jetzt ist das `wordpress` Chart installiert. Beachten Sie dass das Installieren +eines Charts ein neues _release_ Objekt erstellt. Die Version oben hat den Namen +`happy-panda`. (Wenn Sie möchten, dass Helm einen Namen für Sie generiert, lassen +Sie den Versionsnamen offen und geben den Parameter `--generate-name` an.) + +Währen der Installation gibt das `helm` Programm nützzliche Informationen aus wie +die erstellten Resourcen, der Status der Version und falls vorhanden zusätzliche +Konfigurationsschritte, die Sie durchführen können. + +Helm wartet nicht, bis alle Resourcen laufen. Viele Charts brauchen Docker Images +mit einer Grösse von 600 MB und brauchen länger, um im Cluster installiert zu +werden. + +Um auf dem Laufenden zu bleiben oder um Konfigurationsinformationen nochmal zu lesen, +können Sie `helm status` benutzen: + +```console +$ helm status happy-panda +NAME: happy-panda +LAST DEPLOYED: Tue Jan 26 10:27:17 2021 +NAMESPACE: default +STATUS: deployed +REVISION: 1 +NOTES: +** Please be patient while the chart is being deployed ** + +Your WordPress site can be accessed through the following DNS name from within your cluster: + + happy-panda-wordpress.default.svc.cluster.local (port 80) + +To access your WordPress site from outside the cluster follow the steps below: + +1. Get the WordPress URL by running these commands: + + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + Watch the status with: 'kubectl get svc --namespace default -w happy-panda-wordpress' + + export SERVICE_IP=$(kubectl get svc --namespace default happy-panda-wordpress --template "{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}") + echo "WordPress URL: http://$SERVICE_IP/" + echo "WordPress Admin URL: http://$SERVICE_IP/admin" + +2. Open a browser and access WordPress using the obtained URL. + +3. Login with the following credentials below to see your blog: + + echo Username: user + echo Password: $(kubectl get secret --namespace default happy-panda-wordpress -o jsonpath="{.data.wordpress-password}" | base64 --decode) +``` + +Die Informationen oben zeigen den Status der letzten Version. + +### Anpassen des Charts vor der Installation + +Bisher nutzen wir nur die Standardoptionen der Konfiguration eines Charts. +Öfters will man aber das Chart anpassen. + +Um zu sehen, welche Konfigurationsoptionen ein Chart bietet, nutzen Sie `helm show values`: + +```console +$ helm show values bitnami/wordpress +## Global Docker image parameters +## Please, note that this will override the image parameters, including dependencies, configured to use the global value +## Current available global Docker image parameters: imageRegistry and imagePullSecrets +## +# global: +# imageRegistry: myRegistryName +# imagePullSecrets: +# - myRegistryKeySecretName +# storageClass: myStorageClass + +## Bitnami WordPress image version +## ref: https://hub.docker.com/r/bitnami/wordpress/tags/ +## +image: + registry: docker.io + repository: bitnami/wordpress + tag: 5.6.0-debian-10-r35 + [..] +``` + +Sie können alle Einstellungen in einer YAML formatierten Datei überschreiben und +dann bei der Installation angeben. + +```console +$ echo '{mariadb.auth.database: user0db, mariadb.auth.username: user0}' > values.yaml +$ helm install -f values.yaml bitnami/wordpress --generate-name +``` + +Das oben wird eine Standard MariaDB mit dem Benutzer `user0` erstellen, ihm +Rechte auf der neu erstellten Datenbank `user0db` einrichten, aber alle anderen +Werte auf dem Standard des Charts belassen. + +Es gibt zwei Wege, um Konfigurationsdaten während der Installation anzupassen: + +- `--values` (or `-f`): Gibt eine YAML Datei mit Werten zum Überschreiben an. Das + kann beliebig oft gemacht werden, die am weitesten rechts benutzte Datei wird + den Wert bestimmen. +- `--set`: Gibt Überschreibungen auf der Kommandozeile an. + +Wenn beide verwendet werden, `--set` Werte werden in `--values` mit einer höheren +Gewichtung verschmolzen. Überschreibungen mit `--set` sind in einer ConfigMap persistiert. +Werte die mit `--set` angegeben wurden, können in einer Version mit `helm get +values ` ausgegeben werden. Werte, die mit `--set` angegeben wurden, +können mit dem Kommando `helm upgrade` mit `--reset-values` gelöscht werden. + +#### Format und Limitierungen von `--set` + +Die `--set` Option hat null oder mehrere Name/Wert Paare. Am einfachsten ist es zu +benutzen wie: `--set name=value`. Die YAML Syntax ist: + +```yaml +name: value +``` + +Mehere Werte werden separiert mit `,` Zeichen. Aus `--set a=b,c=d` wird: + +```yaml +a: b +c: d +``` + +Mehr komplextere Beschreibungen werden auch unterstützt. Zum Beispiel `--set outer.inner=value` +wird übersetzt in: + +```yaml +outer: + inner: value +``` + +Listen können mit geschweiften Klammern `{` und `}` angegeben werden. Zum Beispiel `--set +name={a, b, c}` wird übersetzt in: + +```yaml +name: + - a + - b + - c +``` + +Mit Helm 2.5.0 ist es möglich, Listenwerte in einer Arrayindex-Syntax +anzugeben, Zum Beispiel `--set servers[0].port=80` wird: + +```yaml +servers: + - port: 80 +``` + +Mehrere Werte können auf diesem Weg angebenen werden. Die Zeile `--set +servers[0].port=80,servers[0].host=example` wird: + +```yaml +servers: + - port: 80 + host: example +``` + +Manchmal brauchen Sie spezielle Zeichen in Ihrer `--set` Zeile. Sie können +Backslash zum Verstecken des Zeichens benutzen: `--set name=value1\,value2` wird: + +```yaml +name: "value1,value2" +``` + +Genauso können Sie Punktsequenzen verstecken, die möglicherweise beim Parsen von Charts +in Annotations, Labels und Node Selectors mit der `toYaml` Funktion problematisc +werden könnten. Die Syntax für `--set nodeSelector."kubernetes\.io/role"=master` +wird: + +```yaml +nodeSelector: + kubernetes.io/role: master +``` + +Tief verzweigte Datenstrukturen können schwierig darzustellen sein mit `--set`. Chart Designer +sind angewiesen, die Benutzung von `--set` durch die Benutzung des Formats +der `values.yaml` Datei zu minimieren. +(Lesen Sie mehr dazu in [Values Files]({{< relref path="/docs/chart_template_guide/values_files/_index.md" lang="en" >}})). + +### Mehr Installationsmethoden + +Das `helm install` Kommando kann von verschiedenen Quellen installieren: + +- Ein Chart Repository (wie wir es oben gesehen haben) +- Ein lokales Chart Archiv (`helm install foo foo-0.1.1.tgz`) +- Ein ungepacktes Chart Verzeichnis (`helm install foo path/to/foo`) +- Eine URL (`helm install foo https://example.com/charts/foo-1.2.3.tgz`) + +## 'helm upgrade' und 'helm rollback': Eine Version aktualisieren und die Wiederherstellung nach einem Fehler + +Wenn eine neue Version von einem Chart installiert ist oder wenn Sie Änderungen +an der Konfiguration durchführen möchten, können Sie das +`helm upgrade` Kommando verwenden. + +Eine Aktualisierung nimmt eine bestehende Version und aktualisiert sie nach +den gegebenen Informationen, die Sie bereitstellen. Da Kubernetes Charts +sehr gross und komplex sein können, probiert Helm die wenigst invasive +Aktualisierung. Es wird nur Dinge aktualisieren, die sich seit der letzten +Version wirklich geändert haben. + +```console +$ helm upgrade -f panda.yaml happy-panda bitnami/wordpress +``` + +In dem Fall oben wird die `happy-panda` Version mit dem selben Chart aber mit einer +neuen YAML Datei aktualisiert: + +```yaml +mariadb.auth.username: user1 +``` + +Wir können `helm get values` benutzen, um zu sehen, ob die Änderungen durchgeführt wurden. + +```console +$ helm get values happy-panda +mariadb: + auth: + username: user1 +``` + +Das `helm get` Kommando ist ein nützliches Werkzeug, um nach der Version in Ihrem +Cluster zu schauen. Wie wir oben sehen können, sieht es so aus, als wenn unsere +neuen Werte von `panda.yaml` im Cluster installiert wurden sind. + +Jetzt, wenn etwas ungeplantes in dieser Version passiert ist, ist es einfach zu +einer vorherigen Version mit dem Kommando `helm rollback [RELEASE] [REVISION]` +zu wechseln. + + +```console +$ helm rollback happy-panda 1 +``` + +Dies rollt unsere happy-panda Installation zur allerersten Version zurück. Bei jeder +Installation, Aktualisierung oder Zurückrollen wird die Revisionsnummer um 1 erhöht. +Die erste Revisionsnummer ist immer die 1. Und mit dem Kommando `helm history [RELEASE]` +sehen wir die Historie zu jeder Version. + +## Hilfreiche Optionen für Installation/Aktualisierung/Zurückrollen + +Es gibt sehr viele hilfreiche Optionen, um das Verhalten von Helm bei der Installation, +der Aktualisierung oder dem Zurückrollen zu ändern. Bitte beachten Sie, dass das keine +vollständige Liste der Optionen ist. Zur vollen Beschreibung rufen Sie einfach +`helm --help` auf. + +- `--timeout`: Ein Wert der [Go Wartezeit](https://golang.org/pkg/time/#ParseDuration), + um auf den Abschluss eines Kubernetes Kommandos zu warten. Der Standardwert ist `5m0s`. +- `--wait`: Wartet bis alle Pods im Status Running sind, PVCs gebunden sind und + Deployments eine minimale Verfügbarkeit besitzen (`Desired` minus `maxUnavailable`), + Services eine IP-Adresse haben (Ingress wenn es ein `LoadBalancer` ist), bevor + die ganze Version als erfolgreich installiert markiert wird. Wenn das Timeout `--timeout` + erreicht wird, wird die Version als `FAILED` markiert. Hinweis: In Deployments in denen + `replicas` auf 1 und `maxUnavailable` als Teil der Aktualisierungsstrategie gesetzt ist, + wird `--wait` den Status fertig melden, wenn es den minimalen Pod als fertig gesehen hat. +- `--no-hooks`: Dies übergeht Hooks für dieses Kommando +- `--recreate-pods` (nur verfügbar bei `upgrade` und `rollback`): Diese Option wird + alle Pods neu erstellen (ausser den Pods in diesem Deployment). (VERALTET in Helm 3) + +## 'helm uninstall': Eine Version deinstallieren + +Benutzen Sie das Kommando `helm uninstall`, wenn es an der Zeit ist, eine Version vom +Cluster zu deinstallieren: + +```console +$ helm uninstall happy-panda +``` + +Das wird die Version vom Cluster löschen. Sie können die derzeit im Cluster installierte +Version mit dem Kommando `helm list` sehen: + +```console +$ helm list +NAME VERSION UPDATED STATUS CHART +inky-cat 1 Wed Sep 28 12:59:46 2016 DEPLOYED alpine-0.1.0 +``` + +Von der Ausgaben oben sehen wir, dass die Version `happy-panda` deinstalliert +wurde. + +In einer vorherigen Version von Helm wurde sich immer das Löschen einer Version +gemerkt. In Helm 3 wird dieser Eintrag auch gelöscht. +Wenn Sie diese Löscheinträge behalten wollen, benutzen Sie beim Deinstallieren +--keep-history`. Die Benutzung von `helm list --uninstalled` wird nur die Versionen +zeigen, die mit der Option `--keep-history` gelöscht wurden. + +Die Option `helm list --all` zeigt alle Versionseinträge, die Helm aufgehoben hat, +incl. fehlerhafte und gelöschte Werte (wenn `--keep-history` verwendet wurde): + +```console +$ helm list --all +NAME VERSION UPDATED STATUS CHART +happy-panda 2 Wed Sep 28 12:47:54 2016 UNINSTALLED wordpress-10.4.5.6.0 +inky-cat 1 Wed Sep 28 12:59:46 2016 DEPLOYED alpine-0.1.0 +kindred-angelf 2 Tue Sep 27 16:16:10 2016 UNINSTALLED alpine-0.1.0 +``` + +Beachten Sie, dass es durch die standardmässig gelöschten Versionen es nicht mehr +möglich ist, eine nicht installierte Resource zurückzurollen. + +## 'helm repo': Arbeiten mit Repositories + +Helm 3 wird nicht mehr mit einem Standard Chart Verzeichnis ausgeliefert. Das +`helm repo` Gruppenkommando stellt Kommandos zum Hinzufügen, Auflisten und Löschen +von Verzeichnissen zur Verfügung. + +Mit dem Kommando `helm repo list` können Sie sehen, welche Verzeichnisse konfiguriert sind: + +```console +$ helm repo list +NAME URL +stable https://charts.helm.sh/stable +mumoshu https://mumoshu.github.io/charts +``` + +Und neue Verzeichnisse können hinzugefügt werden mit `helm repo add`: + +```console +$ helm repo add dev https://example.com/dev-charts +``` + +Weil Sich Chart Repositories ständig ändern, sollten Sie an dieser Stelle +sicherstellen, dass Ihr Helm Programm mit dem Kommando `helm repo update` +aktuell ist. + +Repositories können mit `helm repo remove` gelöscht werden. + +## Ihr eigenes Chart erstellen + +Das [Chart Entwicklungshandbuch]({{< relref path="/docs/topics/charts.md" lang="en">}}) erklärt, +wie Sie Ihr eigenes Chart entwickeln können. Aber Sie können auch schnell starten +mit dem Kommando `helm create`: + +```console +$ helm create deis-workflow +Creating deis-workflow +``` + +Nun gibt es ein Chart in `./deis-workflow`. Sie können es editieren und Ihre +eigene Vorlage erstellen. + +Nach dem Editieren können Sie das Format mit dem Kommando `helm lint` validieren. + +Wenn es Zeit ist, ein Paket von diesem Chart für eine Distribution zu erstellen, können Sie das +Kommando `helm package` verwenden: + +```console +$ helm package deis-workflow +deis-workflow-0.1.0.tgz +``` + +Jetzt kann das Chart einfach installiert werden mit `helm install`: + +```console +$ helm install deis-workflow ./deis-workflow-0.1.0.tgz +... +``` + +Chart Pakete können einfach in ein Repository geladen werden. Schauen Sie +die Dokumentation für [Helm Chart Repositories]({{< relref path="/docs/topics/chart_repository.md" lang="en">}}) für mehr Details. + +## Zusammenfassung + +Dieses Kapitel behandelte die Verwendung des Basismodels vom `helm` Programm, +incl. Suchen, Installieren, Aktualisieren und Uninstallieren. Es wurden auch +hilfreiche Zusatzkommandos besprochen wie `helm status`, `helm get` und `helm repo`. + +Für mehr Informationen zu diesen Kommandos, schauen Sie in die eingebaute Hilfe: +`helm help`. + +Im [nächsten Kapitel]({{< relref path="/docs/howto/charts_tips_and_tricks.md" lang="en">}}) werden wir +einen Blick in die Entwicklung von Charts. diff --git a/content/en/blog/2018-06-01-cncf.md b/content/en/blog/2018-06-01-cncf.md new file mode 100755 index 0000000000..e09246aeee --- /dev/null +++ b/content/en/blog/2018-06-01-cncf.md @@ -0,0 +1,19 @@ +--- +title: "Helm Enters the CNCF" +slug: "helm-enters-the-cncf" +aliases: ["/blog/2018-06-01-cncf/", "/helm-enters-the-cncf/"] +authorname: "Matt Butcher" +author: "@technosophos" +authorlink: "https://twitter.com/technosophos" +date: "2018-06-01" +--- + +Today we are happy to announce that Helm has become an official top-level [CNCF](https://www.cncf.io/) project, joining the ranks of Prometheus, Linkerd, OpenTracing, and others. Helm will enter the CNCF as an incubating project as we continue to work on the next-generation Helm 3 cloud-native package manager. + +We are grateful to the Helm community, which has diligently contributed to the core Helm project, to the official charts repository, Monocular, to Chart Museum, and to other Helm-related projects. As a CNCF project, we look forward to expanding the Helm ecosystem. Over the coming months, we will be re-organizing as we ease our way out of the Kubernetes org and into CNCF. + +Helm began as an internal hackathon project at Deis, and we made our first public release at the original KubeCon. Now, only a few short years later, the Helm ecosystem has seen 3,500 contributors spanning 566 companies. We have made more than 50 releases, and see over 50,000 downloads per month. And last February, we had the [inaugural Helm Summit](https://www.youtube.com/playlist?list=PLVt9l4b66d5EjjJ_VBe_5tEiJrAGLsDb-), where 179 developers, operators, and SREs gathered in Portland, Oregon to talk about the future of the project. + +Thank you for making the Helm community a welcoming place where people from all skill levels can participate in this emerging cloud-native landscape! We are excited to improve Helm as the package manager for the cloud-native landscape. + +We would like to conclude with special thanks to Brian Grant for sponsoring the CNCF proposal, and Matt Farina for writing the proposal and guiding it through the process. diff --git a/content/en/blog/2018-07-23-bring-helm-home.md b/content/en/blog/2018-07-23-bring-helm-home.md new file mode 100755 index 0000000000..00981f9a0b --- /dev/null +++ b/content/en/blog/2018-07-23-bring-helm-home.md @@ -0,0 +1,19 @@ +--- +title: "Bringing Helm Home" +slug: "bringing-helm-home" +aliases: "/blog/2018-07-23-bring-helm-home/" +authorname: "Matt Butcher" +author: "@technosophos" +authorlink: "https://twitter.com/technosophos" +date: "2018-07-23" +--- + +Earlier this summer, we announced that [Helm joined the CNCF](https://www.cncf.io/blog/2018/06/01/cncf-to-host-helm/) as an official incubating project. Part of that transition involves moving the Helm project out of the Kubernetes GitHub org and into its org. We’re excited to announce that we’ve completed that process. As of last week, we have moved the Helm code repository to [https://github.com/helm/helm](https://github.com/helm/helm). + +Fun fact: This is the same GitHub repository where the Helm project first started. When we started Helm in 2015, we created the Helm organization in GitHub. But thanks to the enthusiastic support of the Kubernetes community, we migrated the entire codebase into the Kubernetes org in 2016. As a separate CNCF project with its own vibrant and growing ecosystem, it makes sense to once again have Helm back home in its own GitHub org. + +Since the first beta release of Helm 2.0, we have pledged to keep Helm stable for users and developers alike. Before moving Helm into its new GitHub home, we tested to make sure that this would not break existing builds or existing tooling. Thanks to GitHub’s excellent support for repository moving, we believe we have maintained our stability promise. + +Along with the main Helm source code repo, we have moved a few other Helm related repositories including [Charts](https://github.com/helm/charts), [Monocular](https://github.com/helm/monocular), [Community](https://github.com/helm/community), [ChartMuseum](https://github.com/helm/chartmuseum), and other Helm projects all under the official CNCF Helm GitHub org. This means the community can find all Helm related items under one GitHub org. + +This isn’t our only big news since joining CNCF. Helm 3 is now underway, as developers begin adding new features. And soon we will announce a minor process change that will simplify the process of becoming a Helm contributor as we switch from requiring a CLA to a DCO. diff --git a/content/en/blog/2018-07-24-helm-emeritus-rimus.md b/content/en/blog/2018-07-24-helm-emeritus-rimus.md new file mode 100755 index 0000000000..b0120e30ed --- /dev/null +++ b/content/en/blog/2018-07-24-helm-emeritus-rimus.md @@ -0,0 +1,13 @@ +--- +title: "Helm Emeritus Maintainer Rimas Mocevicius" +slug: "helm-emeritus-maintainer-rimas-mocevicius" +aliases: ["/blog/2018-07-24-helm-emeritus-rimus/", "/helm-emeritus-maintainer-rimas-mocevicius/"] +authorname: "Matt Butcher" +author: "@technosophos" +authorlink: "https://twitter.com/technosophos" +date: "2018-07-24" +--- + +Rimas Mocevicius ([rimusz](https://github.com/rimusz)) has become the fourth Helm Emeritus Maintainer. Rimas is one of the three original founders of Helm. Author of [CoreOS Essentials](https://rimusz.net/coreos-essential-book/) (Packt, 2016) and creator of [Kube Solo](https://github.com/TheNewNormal/kube-solo-osx), Rimas is a long-time member of the Kubernetes ecosystem. Rimas was an active contributor on Helm Classic, and has been a leading voice in the community ever since. + +Check out Rimas' latest blog post on [Tillerless Helm](https://rimusz.net/tillerless-helm). diff --git a/content/en/blog/2018-08-27-helm-switch-dco.md b/content/en/blog/2018-08-27-helm-switch-dco.md new file mode 100755 index 0000000000..489ea4ed35 --- /dev/null +++ b/content/en/blog/2018-08-27-helm-switch-dco.md @@ -0,0 +1,112 @@ +--- +title: "Helm Moves To DCO" +slug: "helm-dco" +aliases: "/blog/2018-08-27-helm-switch-dco/" +authorname: "Matt Farina" +authorlink: "https://mattfarina.com" +date: "2018-08-27" +--- + +When Helm was part of the Kubernetes project it, like the rest of Kubernetes, used the [CNCF Contributor License Agreement (CLA)](https://github.com/cncf/cla). This served Helm well for years. But, most of the CNCF projects use a [Developers Certificate of Origin (DCO)](https://developercertificate.org/) instead of a CLA. The exceptions are Kubernetes and gRPC. Upon Helm becoming a CNCF project itself we were asked if we wanted to move Helm to a DCO. After some careful consideration and a little research, the Helm maintainers voted to move to a DCO. +## What Does This Solve? Why Switch? + +Making a change like this should have a good reason and we have one. It is often easier to get started contributing under a DCO than a CLA. + +When one is developing software for a company they need to have the company sign the Corporate CLA prior to submitting contributions. That means there is a step after the business decides to contribute where legal documents need to be signed and exchanged. Once this is done there are steps to associate people with those legal documents. All of this takes time. In some companies this process can take weeks or longer. + +We wanted to make it simpler to contribute. + +## What Is A DCO? + +A DCO is lightweight way for a developer to certify that they wrote or otherwise have the right to submit code or documentation to a project. The way a developer does this is by adding a `Signed-off-by` line to a commit. When they do this they are agreeing to the DCO. + +The full text of the DCO can be found at https://developercertificate.org. It reads: + +> Developer Certificate of Origin +> Version 1.1 +> +> Copyright (C) 2004, 2006 The Linux Foundation and its contributors. +> 1 Letterman Drive +> Suite D4700 +> San Francisco, CA, 94129 +> +> Everyone is permitted to copy and distribute verbatim copies of this +> license document, but changing it is not allowed. +> +> +> Developer's Certificate of Origin 1.1 +> +> By making a contribution to this project, I certify that: +> +> (a) The contribution was created in whole or in part by me and I +> have the right to submit it under the open source license +> indicated in the file; or +> +> (b) The contribution is based upon previous work that, to the best +> of my knowledge, is covered under an appropriate open source +> license and I have the right under that license to submit that +> work with modifications, whether created in whole or in part +> by me, under the same open source license (unless I am +> permitted to submit under a different license), as indicated +> in the file; or +> +> (c) The contribution was provided directly to me by some other +> person who certified (a), (b) or (c) and I have not modified +> it. +> +> (d) I understand and agree that this project and the contribution +> are public and that a record of the contribution (including all +> personal information I submit with it, including my sign-off) is +> maintained indefinitely and may be redistributed consistent with +> this project or the open source license(s) involved. + +An example signed commit message might look like: + +> An example commit message +> +> Signed-off-by: Some Developer + +Git has a flag that can sign a commit for you. An example using it is: + +``` +$ git commit -s -m 'An example commit message' +``` + +In the past, once someone wanted to contribute they needed to go through the CLA process first. Now they just need to signoff on the commit. + +## FAQs + +### What About Existing Pull Requests Under The CLA + +If a pull request was previously submitted under the CLA we will still honor those. All new contributions will need to be under the DCO and any pull requests that are updated will need to conform to the DCO prior to merging. + +### What About The Other Elements Of A CLA + +The CNCF CLA has provisions for some areas other than right to contribute the code. For example, there is an explicit patent grant and that the contribution is "on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND". The CNCF views elements like these as already being covered elsewhere. For example, through the code contributions being under the Apache 2 license which has patent grant and warranty clauses. + +### What About Commits With Multiple Contributors + +If more than one person works on something it's possible for more than one person to sign off on it. For example, + +> An example commit message +> +> Signed-off-by: Some Developer +> Signed-off-by: Another Developer + +### If I Contribute As An Employee Does My Employer Need To Sign Anything + +Nope. The DCO assumes you are authorized to submit the code. This is what makes the contributor experience simpler for many people. + +### What If I Forget To Sign-off On A Commit + +There is a DCO check, similar to the previous CLA check, that will cause the status of the pull requests to be listed as failed. This will remind everyone that the commit was not signed off. + +To update the last commit message with a sign off you can use the command: + +``` +$ git commit --amend -s +``` + +The `-s` flag is short for `--signoff`. + +If you need to amend older commit message the process is a little more detailed. [GitHub has a writeup detailing on changing commit messages](https://help.github.com/articles/changing-a-commit-message/) that deals with numerous different cases. diff --git a/content/en/blog/2018-09-07-new-gov-and-elections.md b/content/en/blog/2018-09-07-new-gov-and-elections.md new file mode 100755 index 0000000000..6bc4431739 --- /dev/null +++ b/content/en/blog/2018-09-07-new-gov-and-elections.md @@ -0,0 +1,28 @@ +--- +title: "New Governance And Elections" +slug: "new-gov-and-elections" +aliases: "/blog/2018-09-07-new-gov-and-elections/" +authorname: "Matt Farina" +authorlink: "https://mattfarina.com" +date: "2018-09-07" +--- + +Being a top level incubating CNCF project requires having a governance structure to ensure that there is a publicly documented process for making decisions regarding the project and the community. While Helm was under Kubernetes, we relied on Kubernetes governance. As part of the transition to CNCF, the Helm project is required to have its own governance structure. To handle this we set up a [provisional governance](https://github.com/helm/community/blob/aa0586011786dfbc3993e7edd959a841241c96e3/governance/provisional-governance.md) with a goal of creating a long term one. After a few months we are happy to announce that the new governance structure has been written and approved. + +The gist of the new governance is that it organizes those responsible into a couple groups (org and project maintainers), spells out their responsibilities, and provides for decision making processes. You can read all the details in the [governance doc (here)](https://github.com/helm/community/blob/main/governance/governance.md). + +## Two Types of Maintainers + +The new governance has two types of maintainers. **Project Maintainers** are those who maintain the code, documentation, websites, and so forth. There are currently several groups of maintainers for Helm core, Charts, ChartMuseum, Monocular, and Web/Docs. These are the same people who have been maintaining this work. + +The second type of maintainer is the **Helm Org Maintainer**. These individuals are responsible for elements such as the scope, vision, brand, code of conduct, owning security issues, finances, and other aspects of this nature. + +## Next Step: Selecting Helm Org Maintainers + +The next step in the process is to select the initial Helm Org Maintainers. To handle this selection we are using the documented process in the governance. _Anyone who has contributed to the Helm GitHub organization can nominate one of the Project Maintainers to be a Helm Org Maintainer._ This includes the Project Maintainers of Helm core, Charts, ChartMuseum, etc. The nomination period will be open for three weeks (closing on 9/28 at 12pm PT). We wanted Helm Org Maintainers to be project maintainers so that they have shown they are vested in Helm by their actions. + +After that the project maintainers will vote. How that vote works will depend on the number of nominated individuals, who they work for as no one company can have a majority of members, and some other rules. + +To provide for a diverse representation from the projects in the initial selection of Helm Org Maintainers the selected folks will include 3 Representatives from the Helm core project, 2 Representative from the Charts project, and 2 Representatives representing another Helm project. The initial election will create a total of 7 Helm Org Maintainers. The length of their terms is open ended and how changes happen is documented in the governance. + +If you have questions about the process, or how to nominate someone, please use the [Helm mailing list](https://lists.cncf.io/g/cncf-helm). diff --git a/content/en/blog/2018-09-25-chart-testing-intro.md b/content/en/blog/2018-09-25-chart-testing-intro.md new file mode 100755 index 0000000000..ccc6f91615 --- /dev/null +++ b/content/en/blog/2018-09-25-chart-testing-intro.md @@ -0,0 +1,146 @@ +--- +title: "Using the Community Chart Testing Tools Yourself" +slug: "chart-testing-intro" +aliases: "/blog/2018-09-25-chart-testing-intro/" +authorname: "Matt Farina" +authorlink: "https://mattfarina.com" +date: "2018-09-25" +--- + +The Helm community charts, [available as the stable and incubator repositories](https://github.com/helm/charts), have long had testing. That testing has grown and improved a significant amount in the past year; from Helm linting and testing if an application runs in a cluster to now include YAML linting, some validation on maintainers, `Chart.yaml` schema validation, tests on chart version increments, and more. + +These testing tools are useful for more than the community charts. They could be used in development workflows, in other testing systems, and for private charts. To make the testing more accessible we (mostly [Reinhard Nägele](https://github.com/unguiculus/)) refactored the tools into a container image that can be run outside of the community charts testing infrastructure. + +This new image is now available as the [Chart Testing project](https://github.com/helm/chart-testing). This project is built and maintained by the Helm Charts Maintainers, powers the community chart testing process, and is being used elsewhere. + +## Example: Locally on Mac + +One of the easiest ways to take a look at it is to try it out locally. To aid with that, one of the [examples provided by the project shows you how to use it with Docker for Mac](https://github.com/helm/chart-testing/tree/main/examples/docker-for-mac) with the [charts repository](https://github.com/helm/charts). An easy way to try it out is to make a change to a chart and run the following command from the root of the charts directory: + + $ /path/to/chart-testing/examples/docker-for-mac/my_test.sh + +To illustrate this I added a tag in the `Chart.yaml` file of the mariadb chart without incrementing the chart version. Running the test produced the following output: + + Cluster "docker-for-desktop-cluster" set. + Cluster "docker-for-desktop-cluster" set. + Switched to context "docker-for-desktop". + + -------------------------------------------------------------------------------- + Environment: + REMOTE=k8s + TARGET_BRANCH=master + CHART_DIRS=stable incubator + EXCLUDED_CHARTS=common + CHART_REPOS=incubator=https://kubernetes-charts-incubator.storage.googleapis.com/ + TIMEOUT=600 + LINT_CONF=/testing/etc/lintconf.yaml + CHART_YAML_SCHEMA=/testing/etc/chart_schema.yaml + VALIDATE_MAINTAINERS=true + GITHUB_INSTANCE=https://github.com + CHECK_VERSION_INCREMENT=true + -------------------------------------------------------------------------------- + + Charts to be installed and tested: stable/mariadb + Initializing Helm client... + Creating /root/.helm + Creating /root/.helm/repository + Creating /root/.helm/repository/cache + Creating /root/.helm/repository/local + Creating /root/.helm/plugins + Creating /root/.helm/starters + Creating /root/.helm/cache/archive + Creating /root/.helm/repository/repositories.yaml + Adding stable repo with URL: https://kubernetes-charts.storage.googleapis.com + Adding local repo with URL: http://127.0.0.1:8879/charts + $HELM_HOME has been configured at /root/.helm. + Not installing Tiller due to 'client-only' flag having been set + Happy Helming! + "incubator" has been added to your repositories + + -------------------------------------------------------------------------------- + Processing chart 'stable/mariadb'... + -------------------------------------------------------------------------------- + + Validating chart 'stable/mariadb'... + Checking chart 'stable/mariadb' for a version bump... + Chart version on k8s/master : 5.0.3 + New chart version: 5.0.3 + ERROR: Chart version not ok. Needs a version bump. + Linting 'stable/mariadb/Chart.yaml'... + Linting 'stable/mariadb/values.yaml'... + Validating Chart.yaml + Validating /workdir/stable/mariadb/Chart.yaml... + Validation success! 👍 + Validating maintainers + Verifying maintainer 'bitnami-bot'... + ERROR: Chart validation failed. + Building dependencies for chart 'stable/mariadb'... + No requirements found in stable/mariadb/charts. + Chart does not provide test values. Using defaults... + Linting chart 'stable/mariadb'... + ==> Linting stable/mariadb + Lint OK + + 1 chart(s) linted, no failures + -------------------------------------------------------------------------------- + ✖︎ stable/mariadb + -------------------------------------------------------------------------------- + +You'll notice the chart failed to pass testing because the version was not incremented. + +## Configurable + +While the testing image contains defaults, it is configurable so it can be used without any association to the community charts setup. The [configuration is handled via environment variables which are documented in the README.md file](https://github.com/helm/chart-testing/blob/main/README.md#configuration). + +For example, if you wanted to skip checking for a version increment on the chart for every change you can set `CHECK_VERSION_INCREMENT` to `false`. This will skip that check and is useful for cases where every change to a chart is not released. + +## Example: Using It with CircleCI + +Linting, without trying to operate the chart, is easy to incorporate into a workflow. The following is a simple example CircleCI configuration to do so: + + version: 2 + jobs: + lint-charts: + docker: + - image: quay.io/helmpack/chart-testing:v1.1.0 + steps: + - checkout + - run: + name: lint + command: | + chart_test.sh --config .testenv --no-install + workflows: + version: 2 + lint: + jobs: + - lint-charts + +In this case the environment variables for the configuration are stored in a file name `.testenv`. This file holds the environment variables and is sourced into the environment. The following is an example from the community charts: + + # The name of the Git remote + REMOTE=k8s + + # The name of the Git target branch + TARGET_BRANCH=master + + # Chart directories separated by a space + CHART_DIRS=( + stable + incubator + ) + + # Charts that should be skipped + EXCLUDED_CHARTS=( + common + ) + + # Additional chart repos to add (=), separated by a space + CHART_REPOS=( + incubator=https://kubernetes-charts-incubator.storage.googleapis.com/ + ) + + TIMEOUT=600 + +## Try It in Your Workflow + +This toolchain, wrapped in a container image, is meant to be used in a wide variety of workflows. Please take it for a spin, give it a try, use it in your workflows, and provide feedback. diff --git a/content/en/blog/2018-10-04-helm-org-maintainers.md b/content/en/blog/2018-10-04-helm-org-maintainers.md new file mode 100755 index 0000000000..26cab79105 --- /dev/null +++ b/content/en/blog/2018-10-04-helm-org-maintainers.md @@ -0,0 +1,28 @@ +--- +title: "Introducing the Helm Org Maintainers" +slug: "intro-helm-org-maintainers" +aliases: "/blog/2018-10-04-helm-org-maintainers/" +authorname: "Matt Farina & Matt Butcher" +authorlink: "https://helm.sh" +date: "2018-10-04" +--- + +The first major action under the [new Helm governance](https://www.helm.sh/blog/new-gov-and-elections/index.html) was to elect a set of [Helm Org Maintainers](https://github.com/helm/community/blob/52161625acabf4187ae052f4e5fdd36daea91684/governance/governance.md#helm-org-maintainers). In the initial election we were looking to select 7 people to represent Helm core, charts, and other projects under the Helm umbrella. The election is now complete and I would like to introduce the first set of Org Maintainers. + +In alphabetical order, by first name, they are: + +* Adam Reese (adamreese) +* Adnan Abdulhussein (prydonius) +* Josh Dolitsky (jdolitsky) +* Matt Butcher (technosophos) +* Matt Farina (mattfarina) +* Matt Fisher (bacongobbler) +* Reinhard Nägele (unguiculus) +* Scott Rigby (scottrigby) +* Vic Iglesias (viglesiasce) + +Thanks to everyone who ran. Helm is off to a great start under the CNCF and this is another step in our journey. + +## What Do Org Maintainers Do? + +Org Maintainers are responsible for maintaining the vision, mission, values, and scope of the broader Helm project. This includes the Helm client, the charts repository, ChartMuseum, and Monocular. While the org maintainers are not responsible for the technical direction of each individual project, they take on the higher level task of keeping the organization unified. diff --git a/content/en/blog/2018-12-11-helm-hub.md b/content/en/blog/2018-12-11-helm-hub.md new file mode 100755 index 0000000000..0b721f42b0 --- /dev/null +++ b/content/en/blog/2018-12-11-helm-hub.md @@ -0,0 +1,22 @@ +--- +title: "Introducing the Helm Hub" +slug: "intro-helm-hub" +aliases: "/blog/2018-12-11-helm-hub/" +authorname: "Matt Farina" +authorlink: "https://mattfarina.com" +date: "2018-12-11" +--- + +Helm was designed with many distributed repositories in mind. Like Homebrew Taps and Debian APT repositories, Helm has the ability to add and work with many repositories. While the Helm [stable and incubator repositories](https://github.com/helm/charts) have been front and center from the beginning it was never our intent for these to be the only public repositories. + +With this in mind, we are delighted to announce the launch of the [Helm Hub](https://hub.helm.sh). This hub provides a means for you to find charts hosted in many distributed repositories hosted by numerous people and organizations. + +![Helm Hub](https://helm.sh/img/blog/helm-hub.png) + +Helm repositories can be hosted in many ways including as GitHub or GitLab pages, in object storage, using [Chartmuseum](https://github.com/helm/chartmuseum), and via a service provider. + +If you have a chart repository you would like listed please head over to the [hub repository on GitHub](https://github.com/helm/hub) and follow the directions. The process is as simple as a pull request. + +The Helm Hub is powered by [Monocular](https://github.com/helm/monocular), one of the projects that has long been a part of Helm. This was originally crafted by Bitnami and Deis, now part of Microsoft. As the Helm Hub grows in complexity, Monocular will need to grow in its ability to handle many repositories and charts. This is an area where UI and UX designers looking to be part of the Helm and [CNCF](https://cncf.io) community can contribute and make a difference. + +We look forward to the Helm Hub ushering in a new phase of chart development and sharing. diff --git a/content/en/blog/2019-01-14-chartmuseum-security-notice.md b/content/en/blog/2019-01-14-chartmuseum-security-notice.md new file mode 100755 index 0000000000..1e0e324355 --- /dev/null +++ b/content/en/blog/2019-01-14-chartmuseum-security-notice.md @@ -0,0 +1,28 @@ +--- +title: "ChartMuseum Vulnerability: Authorization Bypass [CVE-2019-1000009]" +slug: "chartmuseum-security-notice-2019" +aliases: "/blog/2019-01-14-chartmuseum-security-notice/" +authorname: "Matt Farina & Josh Dolitsky" +authorlink: "https://helm.sh" +date: "2019-01-14" +--- + +Security researcher Bernard Wagner of [Entersekt](https://www.entersekt.com/) discovered a vulnerability in ChartMuseum, impacting **all versions of ChartMuseum between ChartMuseum >=0.1.0 and < 0.8.1**. A specially crafted chart could be uploaded that caused the uploaded archive to be saved outside of the intended location. + +When ChartMuseum is configured for multitenancy the specially crafted chart could be uploaded to one tenant but saved in the location of another tenant. This includes overwriting a chart at a version in the other tenant. + +Additionally, if ChartMuseum is configured to use a file system the uploaded Chart archive may be uploaded to locations outside of the storage directory. It could be uploaded to any place the ChartMuseum application binary has write permission to. + +We are unaware of any public exploits caused by this issue. + +## Details + +When a chart archive is uploaded the name of the chart, as listed in the `Chart.yaml` file, is used when creating the path location to save the file. The name is joined with the directory or object storage prefix path. The chart name was not sanitized or validated. This allowed directory traversal characters, such as `../..`, to be used in the name and affect the directory the archive file is saved within. + +When the Helm client creates a chart archive, via the `helm package` command, it validates that the chart name and encapsulating directory match. It will not generate a chart archive with directory traversal characters. + +## Fix + +Update to ChartMuseum >= 0.8.1 + +To prevent this from happening, ChartMuseum now checks the name of the chart to make sure there are no directory traversal characters in the name before using it to save the archive. If the name contains directory traversal characters the API will return a _400 Bad Request_ response and message to signify the name issue. diff --git a/content/en/blog/2019-01-14-helm-security-notice.md b/content/en/blog/2019-01-14-helm-security-notice.md new file mode 100755 index 0000000000..a8290e4349 --- /dev/null +++ b/content/en/blog/2019-01-14-helm-security-notice.md @@ -0,0 +1,38 @@ +--- +title: "Helm Vulnerability: Client Unpacking Chart that Contains Malicious Content [CVE-2019-1000008]" +slug: "helm-security-notice-2019" +aliases: "/blog/2019-01-14-helm-security-notice/" +authorname: "Matt Butcher" +author: "@technosophos" +authorlink: "https://twitter.com/technosophos" +date: "2019-01-14" +--- + +Security researcher Bernard Wagner of [Entersekt](https://www.entersekt.com/) discovered a vulnerability in the Helm client, impacting **all versions of Helm between Helm >=2.0.0 and < 2.12.2**. Two Helm client commands may be coerced into unpacking unsafe content from a maliciously designed chart. + +A specially crafted chart may be able to unpack content into locations on the filesystem outside of the chart’s path, potentially overwriting existing files. + +No version of Tiller is known to be impacted. This is a client-only issue. + +The following Helm commands may unsafely unpack malformed charts onto a local folder: `helm fetch --untar` and `helm lint some.tgz`. + + +We are unaware of any public exploits caused by this issue. + +## Details + +During unpacking operations, file names were not checked to see if they contained references to parent directories. Normally, this does not impact Helm’s operation because file names are only used as in-memory names. However, two operations were found to export files directly to disk without sanitizing the file names. The `helm lint` command may unpack a tar archive into a temporary directory, and `helm fetch --untar` will unpack an archive into a user-supplied directory. In both cases, not all file names were correctly sanitized. + +No Tiller version is impacted. This vulnerability does not render clusters vulnerable to attack. Tiller does not store unpacked charts. All charts are loaded in-memory, and paths are resolved as string names, not as locations on a file system. + +## Workarounds + +Unpack charts with the appropriate `tar` command, and do not use the `--untar` flag on `helm fetch`. Do not run `helm lint` on tars. Unpack them manually and run `helm lint` on the unpacked directory. + +## Fix + +Update to Helm >= 2.12.2. + +As of Helm 2.12.2, the unpacking operation disallows paths that could be used to store files outside of the present working directory. This is considered a bug fix, rather than a breaking change, because there is no way to produce such malformed packages from within Helm or from standard chart-building tools. + +From Helm 2.12.2 onward, charts that contain files that are not relative to the current working directory will fail to load, even when loaded into memory. diff --git a/content/en/blog/2019-04-18-helm-summit-eu-2019.md b/content/en/blog/2019-04-18-helm-summit-eu-2019.md new file mode 100755 index 0000000000..a8ad23fb05 --- /dev/null +++ b/content/en/blog/2019-04-18-helm-summit-eu-2019.md @@ -0,0 +1,21 @@ +--- +title: "Helm Summit EU 2019" +slug: "helm-summit-eu-2019" +aliases: ["/blog/2019-04-18-helm-summit-eu-2019/", "/helm-summit-eu-2019/"] +authorname: "Karen Chu" +author: "@karenhchu" +authorlink: "https://twitter.com/karenhchu" +date: "2019-04-18" +--- + +We're beyond excited to share that [Helm Summit EU 2019](https://events.linuxfoundation.org/events/helm-summit-2019/) is now official (h/t to [CNCF](https://cncf.io/))! Join the Helm community on September 11 - 12 in Amsterdam, The Netherlands at Pakhuis de Zwijger for our first European Helm Summit. Over the course of two days, we'll discuss all things Helm and hold tutorials, working sessions, and small group discussions with new and exisiting users. + +Interested in... + +* Registering? Sign up [here](https://events.linuxfoundation.org/events/helm-summit-2019/register/) before Aug 27 for Early Bird pricing of $250. Prices will go up to the Standard pricing of $300 thereafter. + +* CFPs? Submit a proposal for a lighting talk, presentation, or tutorial before the Friday May 31 deadline. Click [here](https://events.linuxfoundation.org/events/helm-summit-2019/program/call-for-proposals/) for details. + +* Sponsoring? Sponsorships are now open and in limited quantity. Please reach out to sponsor@cncf.io for the sponsorship prospectus. + +In the mean time, make sure to follow us on [Twitter](https://twitter.com/HelmPack) for the most up-to-date news on #HelmSummit! diff --git a/content/en/blog/2019-04-22-helm-3-preview-pt1.md b/content/en/blog/2019-04-22-helm-3-preview-pt1.md new file mode 100755 index 0000000000..bd79aaac6f --- /dev/null +++ b/content/en/blog/2019-04-22-helm-3-preview-pt1.md @@ -0,0 +1,71 @@ +--- +title: "Helm 3 Preview: Charting Our Future – Part 1: A History of Helm" +slug: "helm-3-preview-pt1" +aliases: ["/blog/2019-04-22-helm-3-preview-pt1/", "/helm-3-preview-pt1/"] +authorname: "Matt Fisher" +author: "@bacongobbler" +authorlink: "https://twitter.com/bacongobbler" +date: "2019-04-22" +--- +On October 15th, 2015, the project now known as Helm was born. Only one year later, the Helm community joined the Kubernetes organization as Helm 2 was fast approaching. In June 2018, the Helm community [joined the CNCF](https://www.cncf.io/blog/2018/06/01/cncf-to-host-helm/) as an incubating project. Fast forward to today, and Helm 3 is nearing its first alpha release. + +In this series of seven blog posts over the next four weeks, I'll provide some history on Helm's beginnings, illustrate how we got where we are today, showcase some of the new features available for the first alpha release of Helm 3, and explain how we move forward from here. + +In order, I'll discuss: + +1. The history of the creation of Helm +2. A Gentle Farewell to Tiller +3. Chart Repositories +4. Release Management +5. Changes to Chart Dependencies +6. Library Charts +7. What’s Next? + +### A History of Helm + +Let's get started. Part 1 of 7 of our *Helm 3 Preview: Charting Our Future* blog series is about the history of how Helm was created and evolved. + +#### Helm was Born + +Helm 1 began as an open source project created by Deis. We were a small startup company [acquired by Microsoft in the spring of 2017](https://blogs.microsoft.com/blog/2017/04/10/microsoft-acquire-deis-help-companies-innovate-containers/). Our other open source project - also called Deis - had a tool called [`deisctl`](https://github.com/deis/deis/tree/master/deisctl) that was used for (among other things) installing and operating the Deis platform on a [Fleet cluster](https://github.com/coreos/fleet). Fleet was one of the first "container orchestrator" platforms to exist at the time. + +In mid-2015, we decided to shift gears, and the foundation of Deis (now re-named "Deis Workflow") moved from Fleet to Kubernetes. One of the first things we had to rewrite was the installation tool, `deisctl`. We used this tool to install and manage Deis Workflow on a Fleet cluster. + +Modeled after package managers like Homebrew, apt, and yum, the focus of Helm 1 was to make it easy for users to package and install their applications on Kubernetes. We officially announced Helm in 2015 at the inaugural KubeCon in San Francisco. + +Our first attempt at Helm worked, but had its fair share of limitations. It took a set of Kubernetes manifests - sprinkled with generators as YAML front-matter - and loaded the generated results into Kubernetes. + +For example, to substitute a field in a YAML file, one would add the following to a manifest: + +``` +#helm:generate sed -i -e s|ubuntu-debootstrap|fluffy-bunny| my/pod.yaml +``` + +Makes you really happy that template languages exist today, eh? + +For many reasons, this early Kubernetes installer required a hard-coded list of manifest files and performed only a small fixed sequence of events. It was painful enough to use that the Deis Workflow R&D team was having a tough time replatforming their product around it, but the seed of an idea was there. Our first attempt was a very successful learning opportunity: we learned that we were passionate about building pragmatic solutions that solved real day-to-day problems for our users. + +Learning from our past mistakes, we started designing Helm 2. + +#### Designing Helm 2 + +As 2015 wound to a close, a team from Google reached out to the Helm team. They, too, had been working on a similar tool for Kubernetes. Deployment Manager for Kubernetes was a port of an existing tool they used for Google Cloud Platform. Would we be interested, they asked, in spending a few days talking about similarities and differences? + +In January 2016, the Helm and Deployment Manager teams sat down in Seattle to share some ideas. We walked out with a bold plan: merge the projects to create Helm 2. Along with Deis and Google, [SkippBox](https://github.com/skippbox) joined the development team, and we started work on Helm 2. + +Our goal was to maintain Helm's ease of use, but add the following: + +- Chart templates for customization +- In-cluster management for teams +- A first-class chart repository +- A stable and signable package format +- A strong commitment to semantic versioning and retaining backward compatibility version-to-version + +To accomplish these goals, we added a second component to the Helm ecosystem. This in-cluster component was called Tiller, and it handled installing and managing Helm charts. + +Since the release of Helm 2 in 2016, Kubernetes added several major features. Role-Based Access Control (RBAC) was added and eventually replaced Attribute-Based Access Control (ABAC). Many new resource types were introduced (Deployments were still in beta at the time). Custom Resource Definitions (then called Third Party Resources, or TPRs) were invented. And most importantly, a set of best practices emerged. + +Throughout all of these changes, Helm continued to serve the needs of Kubernetes users. After 3 years and many new feature additions, it became a good idea to introduce some major changes to the code base so that Helm would continue to meet the needs of this evolving ecosystem. + +This brings us to Helm 3 -- check out our next blog post [here](https://helm.sh/blog/helm-3-preview-pt2/) where we discuss the fate of Tiller in our *Helm 3 Preview: Charting Our Future* blog series over the course of 4 weeks. + diff --git a/content/en/blog/2019-04-25-helm-3-preview-pt2.md b/content/en/blog/2019-04-25-helm-3-preview-pt2.md new file mode 100755 index 0000000000..d7d4ffdb7f --- /dev/null +++ b/content/en/blog/2019-04-25-helm-3-preview-pt2.md @@ -0,0 +1,24 @@ +--- +title: "Helm 3 Preview: Charting Our Future – Part 2: A Gentle Farewell to Tiller" +slug: "helm-3-preview-pt2" +aliases: ["/blog/2019-04-25-helm-3-preview-pt2/", "/helm-3-preview-pt2/"] +authorname: "Matt Fisher" +author: "@bacongobbler" +authorlink: "https://twitter.com/bacongobbler" +date: "2019-04-25" +--- + +This is part 2 of 7 of our *Helm 3 Preview: Charting Our Future* blog series. (Check out our previous blog post on the history of Helm [here](https://helm.sh/blog/helm-3-preview-pt1/).) + +During the Helm 2 development cycle, we introduced Tiller as part of our integration with Google's Deployment Manager. Tiller played an important role for teams working on a shared cluster - it made it possible for multiple different operators to interact with the same set of releases. + +With role-based access controls (RBAC) enabled by default in Kubernetes 1.6, locking down Tiller for use in a production scenario became more difficult to manage. Due to the vast number of possible security policies, our stance was to provide a permissive default configuration. This allowed first-time users to start experimenting with Helm and Kubernetes without having to dive headfirst into the security controls. Unfortunately, this permissive configuration could grant a user a broad range of permissions they weren't intended to have. DevOps and SREs had to learn additional operational steps when installing Tiller into a multi-tenant cluster. + +After hearing how community members were using Helm in certain scenarios, we found that Tiller's release management system did not need to rely upon an in-cluster operator to maintain state or act as a central hub for Helm release information. Instead, we could simply fetch information from the Kubernetes API server, render the Charts client-side, and store a record of the installation in Kubernetes. + +Tiller’s primary goal could be accomplished without Tiller, so one of the first decisions we made regarding Helm 3 was to completely remove Tiller. + +With Tiller gone, the security model for Helm is radically simplified. Helm 3 now supports all the modern security, identity, and authorization features of modern Kubernetes. Helm's permissions are evaluated using your [kubeconfig file](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/). Cluster administrators can restrict user permissions at whatever granularity they see fit. Releases are still recorded in-cluster, and the rest of Helm's functionality remains. + +Read the next blog post [here](https://helm.sh/blog/helm-3-preview-pt3/) where we discuss chart repositories in the next part of our *Helm 3 Preview: Charting Our Future* blog series over the course of 4 weeks. + diff --git a/content/en/blog/2019-04-29-helm-3-preview-pt3.md b/content/en/blog/2019-04-29-helm-3-preview-pt3.md new file mode 100755 index 0000000000..3f17f8d47a --- /dev/null +++ b/content/en/blog/2019-04-29-helm-3-preview-pt3.md @@ -0,0 +1,30 @@ +--- +title: "Helm 3 Preview: Charting Our Future – Part 3: Chart Repositories" +slug: "helm-3-preview-pt3" +aliases: ["/blog/2019-04-29-helm-3-preview-pt3/", "/helm-3-preview-pt3/"] +authorname: "Matt Fisher" +author: "@bacongobbler" +authorlink: "https://twitter.com/bacongobbler" +date: "2019-04-29" +--- + +This is part 3 of 7 of our *Helm 3 Preview: Charting Our Future* blog series, discussing chart repositories. (Check out our previous blog post on the gentle goodbye to Tiller [here](https://helm.sh/blog/helm-3-preview-pt2/).) + +At a high level, a Chart Repository is a location where Charts can be stored and shared. The Helm client packs and ships Helm Charts to a Chart Repository. Simply put, a Chart Repository is a basic HTTP server that houses an index.yaml file and some packaged charts. + +While there are several benefits to the Chart Repository API meeting the most basic storage requirements, a few drawbacks have started to show: + +- Chart Repositories have a very hard time abstracting most of the security implementations required in a production environment. Having a standard API for authentication and authorization is very important in production scenarios. +- Helm’s Chart provenance tools used for signing and verifying the integrity and origin of a chart are an optional piece of the Chart publishing process. +- In multi-tenant scenarios, the same Chart can be uploaded by another tenant, costing twice the storage cost to store the same content. Smarter chart repositories have been designed to handle this, but it’s not a part of the formal specification. +- Using a single index file for search, metadata information, and fetching Charts has made it difficult or clunky to design around in secure multi-tenant implementations. + +Docker’s [Distribution project](https://github.com/docker/distribution) (also known as Docker Registry v2) is the successor to the Docker Registry project, and is the de-facto toolset to pack, ship, store, and deliver Docker images. Many major cloud vendors have a product offering of the Distribution project, and with so many vendors offering the same product, the Distribution project has benefited from many years of hardening, security best practices, and battle-testing, making it one of the most successful unsung heroes of the open source world. + +But did you know that the Distribution project was designed to distribute any form of content, not just container images? + +Thanks to the efforts of the [Open Container Initiative (or OCI for short)](https://www.opencontainers.org/), Helm Charts can be hosted on any instance of Distribution. The work is experimental, with login support and other features considered "table stakes" for Helm 3 yet to be finished, but we're very excited to learn from previous discoveries that the OCI and Distribution teams have made over the years, learning through their mentorship and guidance on what it means to run a highly available service at scale. + +I wrote a more detailed deep-dive on some of the [upcoming changes to Helm Chart Repositories](https://blog.bacongobbler.com/post/2019-01-25-distributing-with-distribution/) if you'd like to read more on the subject. + +You can check out the next blog [here](https://helm.sh/blog/helm-3-preview-pt4/) where we discuss release management in the next part of our *Helm 3 Preview: Charting Our Future* blog series over the course of 4 weeks. diff --git a/content/en/blog/2019-05-02-helm-3-preview-pt4.md b/content/en/blog/2019-05-02-helm-3-preview-pt4.md new file mode 100755 index 0000000000..16515c0ceb --- /dev/null +++ b/content/en/blog/2019-05-02-helm-3-preview-pt4.md @@ -0,0 +1,30 @@ +--- +title: "Helm 3 Preview: Charting Our Future – Part 4: Release Management" +slug: "helm-3-preview-pt4" +aliases: ["/blog/2019-05-02-helm-3-preview-pt4/", "/helm-3-preview-pt4/"] +authorname: "Matt Fisher" +author: "@bacongobbler" +authorlink: "https://twitter.com/bacongobbler" +date: "2019-05-02" +--- + +This is part 4 of 7 of our *Helm 3 Preview: Charting Our Future* blog series on release management. (Check out our previous blog post on the Helm chart repositories [here](https://helm.sh/blog/helm-3-preview-pt3/.). + +In Helm 3, an application's state is tracked in-cluster by a pair of objects: + +- The release object: represents an instance of an application +- The release version secret: represents an application's desired state at a particular instance of time (the release of a new version, for example) + +A `helm install` creates a release object and a release version secret. A `helm upgrade` requires an existing release object (which it may modify) and creates a new release version secret that contains the new values and rendered manifest. + +The release object contains information about a release, where a release is a particular installation of a named chart and values. This object describes the top-level metadata about a release. The release object persists for the duration of an application lifecycle, and is the owner of all release version secrets, as well as of all objects that are directly created by the Helm chart. + +The release version secret ties a release to a series of revisions (install, upgrades, rollbacks, delete). + +In Helm 2, revisions were merely incremental. `helm install` created v1, a subsequent upgrade created v2, and so on. The release and release version secret were collapsed into a single object known as a revision. Revisions were stored in the same namespace as Tiller, meaning that each release name was "globally" namespaced; as a result, only one instance of a name could be used. + +For Helm 3, a release has one or more release version secrets associated with it. The release object always describes the current release deployed to Kubernetes. Each release version secret describes just one version of that release. An upgrade operation, for example, will create a new release version secret, and then modify the release object to point to this new version. Rollback operations can use older release version secrets to roll back a release to a previous state. + +With Tiller gone, Helm 3 stores release data in the same namespace as the release's destination. This change allows one to install a chart with the same release name in another namespace, and data is persisted between cluster upgrades/reboots in etcd. You can install Wordpress into namespace "foo" as well as namespace "bar", and both releases can be referred to as "wordpress". + +Speaking of Charts...read the next blog [here](https://helm.sh/blog/helm-3-preview-pt5/) where we discuss changes to chart dependicies in our *Helm 3 Preview: Charting Our Future* blog series over the course of 4 weeks. diff --git a/content/en/blog/2019-05-06-helm-3-preview-pt5.md b/content/en/blog/2019-05-06-helm-3-preview-pt5.md new file mode 100755 index 0000000000..688673a2dd --- /dev/null +++ b/content/en/blog/2019-05-06-helm-3-preview-pt5.md @@ -0,0 +1,45 @@ +--- +title: "Helm 3 Preview: Charting Our Future – Part 5: Changes to Chart Dependencies" +slug: "helm-3-preview-pt5" +aliases: ["/blog/2019-05-06-helm-3-preview-pt5/", "/helm-3-preview-pt5/"] +authorname: "Matt Fisher" +author: "@bacongobbler" +authorlink: "https://twitter.com/bacongobbler" +date: "2019-05-06" +--- + +This is part 5 of 7 of our *Helm 3 Preview: Charting Our Future* blog series about chart dependencies and some subtle differences between Helm 2 and Helm 3. (Check out our previous blog post on release management [here](https://helm.sh/blog/helm-3-preview-pt4/).) + +Charts that were packaged (with `helm package`) for use with Helm 2 can be installed with Helm 3, but the chart development workflow received an overhaul, so some changes are necessary to continue developing charts with Helm 3. One of the components that changed was the chart dependency management system. + +The Chart dependency management system moved from requirements.yaml and requirements.lock to Chart.yaml and Chart.lock, meaning that charts that relied on the `helm dependency` command will need some tweaking to work in Helm 3. + +Let's take a look at an example. Let's add a dependency to a chart in Helm 2 and then look at how that changed in Helm 3. + +In Helm 2, this is how a requirements.yaml looked: + +``` +dependencies: +- name: mariadb + version: 5.x.x + repository: https://kubernetes-charts.storage.googleapis.com/ + condition: mariadb.enabled + tags: + - database +``` + +In Helm 3, the same dependency is expressed in your Chart.yaml: + +``` +dependencies: +- name: mariadb + version: 5.x.x + repository: https://kubernetes-charts.storage.googleapis.com/ + condition: mariadb.enabled + tags: + - database +``` + +Charts are still downloaded and placed in the charts/ directory, so subcharts vendored into the charts/ directory will continue to work without modification. + +Click [here](https://helm.sh/blog/helm-3-preview-pt6/) to read the next blog where we introduce library charts in the next part of our *Helm 3 Preview: Charting Our Future* blog series over the course of 4 weeks. diff --git a/content/en/blog/2019-05-09-helm-3-preview-pt6.md b/content/en/blog/2019-05-09-helm-3-preview-pt6.md new file mode 100755 index 0000000000..dcb9438e10 --- /dev/null +++ b/content/en/blog/2019-05-09-helm-3-preview-pt6.md @@ -0,0 +1,26 @@ +--- +title: "Helm 3 Preview: Charting Our Future – Part 6: Introducing Library Charts" +slug: "helm-3-preview-pt6" +aliases: ["/blog/2019-05-09-helm-3-preview-pt6/", "/helm-3-preview-pt6/"] +authorname: "Matt Fisher" +author: "@bacongobbler" +authorlink: "https://twitter.com/bacongobbler" +date: "2019-05-09" +--- + +This is part 6 of 7 of our *Helm 3 Preview: Charting Our Future* blog series on library charts. You can find our previous blog post on the Helm chart dependencies [here](https://helm.sh/blog/helm-3-preview-pt5/). + +Helm 3 supports a class of chart called a "library chart". This is a chart that is shared by other charts, but does not create any release artifacts of its own. A library chart's templates can only declare `define` elements. Globally scoped non-define content is simply ignored. This allows users to re-use and share snippets of code that can be re-used across many charts, avoiding redundancy and keeping charts [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself). + +Library charts are declared in the `dependencies` directive in Chart.yaml, and are installed and managed like any other chart. + +``` +dependencies: + - name: mylib + version: 1.x.x + repository: quay.io +``` + +We're very excited to see the use cases this feature opens up for chart developers, as well as any best practices that arise from consuming library charts. + +Click [here](https://helm.sh/blog/helm-3-preview-pt7/) to read the final part of our *Helm 3 Preview: Charting Our Future* blog series over the course of 4 weeks. diff --git a/content/en/blog/2019-05-13-helm-3-preview-pt7.md b/content/en/blog/2019-05-13-helm-3-preview-pt7.md new file mode 100755 index 0000000000..4964aa880c --- /dev/null +++ b/content/en/blog/2019-05-13-helm-3-preview-pt7.md @@ -0,0 +1,28 @@ +--- +title: "Helm 3 Preview: Charting Our Future – Part 7: What's Next?" +slug: "helm-3-preview-pt7" +aliases: ["/blog/2019-05-13-helm-3-preview-pt7/", "/helm-3-preview-pt7/"] +authorname: "Matt Fisher" +author: "@bacongobbler" +authorlink: "https://twitter.com/bacongobbler" +date: "2019-05-13" +--- + +This is the seventh and final part of our *Helm 3 Preview: Charting Our Future* blog series. Read our previous blog post on library charts [here](https://helm.sh/blog/helm-3-preview-pt6/). + +Helm 3.0.0-alpha.1 is the foundation upon which we'll begin to build the next version of Helm. The features shared over the last few weeks were some of the big promises we made for Helm 3. Many of those features are still in their early stages and that is OK; the idea of an alpha release is to test out an idea, gather feedback from early adopters, and validate those assumptions. + +Once the alpha has been released, we can start accepting patches from the community for Helm 3. We should have a stable foundation on which to build and accept new features, and users should feel empowered to open tickets and contribute fixes. + +In this blog series, I have tried to highlight some of the big improvements coming to Helm 3, but this list is by no means exhaustive. The full plan for Helm 3 includes features such as improved upgrade strategies, deeper integrations with OCI registries, and applying JSON schemas against chart values for validation purposes. We’re also taking a moment to clean up the codebase and updating parts that have languished over the last three years. + +If you feel like a topic was missed, we'd love to hear your thoughts! + +Feel free to join the discussion in [our Slack channels](https://kubernetes.slack.com): + + - `#helm-users` for questions and just to hang out with the community + - `#helm-dev` for discussing PRs, code, and bugs + +You can also join and hang out in our weekly Public Developer Calls on Thursdays at 09:30PDT. The meeting is focused on discussing what the core maintainers and the community are working on, as well as any discussion topics for the week. Anyone is welcome to join this call and participate. The link is in the `#helm-dev` Slack channel. + +TTFN, ta ta for now! diff --git a/content/en/blog/2019-06-10-get-helm-sh.md b/content/en/blog/2019-06-10-get-helm-sh.md new file mode 100755 index 0000000000..2eb1c6fcff --- /dev/null +++ b/content/en/blog/2019-06-10-get-helm-sh.md @@ -0,0 +1,82 @@ +--- +title: "Announcing get.helm.sh" +slug: "get-helm-sh" +authorname: "Matt Fisher" +author: "@bacongobbler" +authorlink: "https://twitter.com/bacongobbler" +date: "2019-06-10" +--- + +The Helm Client has long been available to download from Google Cloud Storage at the bucket . This bucket in Google Cloud has been used by Helm since before Kubernetes was part of the CNCF. The first release hosted on this bucket was Helm v2.0.0-alpha.5! + +Google has long been gracious in providing funding for this location. Since Helm started using it, Helm (as part of Kubernetes) moved into the CNCF, and then moved out from under the Kubernetes umbrella, becoming a sister project to Kubernetes within the CNCF. + +The CNCF is in the process of taking over the infrastructure for Kubernetes. It was time for Helm to move from a location funded by Google to one funded by the CNCF. Google Cloud buckets cannot be transferred between projects, which meant we could not transfer the bucket over to a CNCF account. We needed to move to a new location as part of the move. + +## Where are we now? + +The Helm project now publishes client downloads to . All Helm releases from Helm v2.0.0-alpha.5 onwards are available for download, as well as the latest Helm 3 alpha.1 release. + +For backwards compatibility concerns, new releases of Helm 2 will continue to be published at the old URL, however we strongly encourage users to migrate. + +Going forward, this is the only location where you will find Helm 3; they are not being uploaded to the old storage bucket. Helm 3.0.0-alpha.1 builds are available there now. + +## What do I need to do? + +If you're using the old URL in your CI pipeline, you can replace with . + +If you're using [the get script](https://helm.sh/docs/using_helm/#from-script), it is now [pulling from the new URL](https://github.com/helm/helm/blob/2ca025d48222d6fa188653e2ca5eda6ed799145c/scripts/get#L114), so no changes on your end are required. + +All the download URLs in our [GitHub releases](https://github.com/helm/helm/releases) have also been changed to use the new URL. + +## What's under the hood? + +`get.helm.sh` has three main components: + +1. [Azure Blob Storage](https://azure.microsoft.com/en-ca/services/storage/blobs/) +1. [Azure CDN](https://azure.microsoft.com/en-ca/services/cdn/) +1. The domain name `get.helm.sh` + +In our release pipeline, Helm 2 and Helm 3 downloads are [uploaded to Azure Blob Storage](https://github.com/helm/helm/commit/022c8869bee37d02cf01507c11c6cfc6d58a1eca) (Helm 2 downloads are also [uploaded to Google Cloud Storage](https://github.com/helm/helm/commit/95775d0c60804b3d3674510e1f57a30ca8074ddd) for backwards compatibililty). Azure CDN serves that content, which is fronted with a custom domain name. + +## Why the new location? + +As part of the move, we started considering some new features the community has been asking for: + +### An official helm.sh URL + +During this transition, we wanted to ensure that we won't disrupt users a second time, asking them to change their deployment pipelines to point to a new location. We decided to place a URL we control in front of the storage provider. This way, we do not need to ask users to switch URLs again in the future. If the underlying storage provider needs to change at some point in the future, we can have the URL point at the new location without this level of disruption going forward. + +### Content delivery at the edge + + is fronted by [Azure CDN](https://azure.microsoft.com/en-ca/services/cdn/), a Content Delivery Network that is globally available. This should provide faster downloads to those distributed around the world, not just to those located in the Eastern United States. + +It also provides availability in regions that were previously unavailable, such as... + +### Availability in China + +China is a large market for the CNCF, and therefore a large market for Helm. Google Cloud Storage is not accessible in China, so users in that region interested in using Helm have set up mirrors to work around this problem. + +This is an area of concern in particular around adoption: As a user, I am now relying on an unofficial mirror to fetch my downloads, which comes with a certain level of risk I would not be subject to if I were fetching from the official release page like every other user. + +Azure CDN [can serve content to users in China](https://docs.microsoft.com/en-us/azure/cdn/cdn-china-delivery) using point-of-presence (POP) locations near China. With Helm downloads now available in China, we are seeing just how popular Helm is in that area thanks to... + +### Download metrics + +One of the questions that keep popping up in our minds was how users are consuming Helm on a daily basis. The core maintainers were interested in answering the following questions: + +- what versions of Helm are being used? +- what regions of the world are using Helm today? +- How long does it take for the community to migrate over to a new version of Helm? +- How many users are downloading Helm 3 vs Helm 2? + +Our new CDN provides a rich set of metrics can provide answers to these questions. + +While these metrics are only available to core maintainers at this time, we are discussing how we can share these metrics with the community similar to . + +## Caveat: Tiller and Chart downloads + +Please note that this change is only for the Helm client downloads. Tiller has not moved from Google Container Registry, and the stable and incubator Helm chart repositories are still hosted on Google Cloud. + + +If you have any questions about this change, please let us know. More information on this change can be found under [issue #5663](https://github.com/helm/helm/issues/5663). diff --git a/content/en/blog/2019-08-27-helm-v3-beta.md b/content/en/blog/2019-08-27-helm-v3-beta.md new file mode 100755 index 0000000000..14632a8e9a --- /dev/null +++ b/content/en/blog/2019-08-27-helm-v3-beta.md @@ -0,0 +1,41 @@ +--- +title: "Helm v3 Beta 1 Released" +slug: "helm-v3-beta" +authorname: "Matt Farina" +author: "@mattfarina" +authorlink: "https://mattfarina.com" +date: "2019-08-27" +--- + +Helm v3 development has hit a new milestone with the release of the [first beta](https://github.com/helm/helm/releases/tag/v3.0.0-beta.1). This is an especially important milestone because it is the end of the effort to refactor Helm v3. The last of the _intended_ breaking changes has landed. From this point on, Helm v3 is focused on bug fixes, stability, and preparing it for a stable release. + +If you are interested in Helm v3 now is a great time to test it out. If you find issues please file an issue if one has not already been filed. + +## Notable changes since Helm v2 + +* Tiller has been removed. This simplifies the experience of using Helm. There is no more need to have cluster admin privileges or to install a Tiller in every namespace. With Tiller removed, Helm now uses the settings and access defined in the local kubeconfig file. +* A name is now required on install or you can use the `--generate-name` flag to have one automatically generated. This is a reverse of the Helm v2 behavior. +* The `helm init` command has been removed. It performed two primary functions. First, it installed Tiller. This is no longer needed. Second, it setup directories and repositories where Helm configuration lived. This is now automated. If the directory is not present it will be created. +* The Helm home directory used to be located off a users home directory. There is a standard known as the [XDG Base Directory Specification](https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html) that describes a standard method to handle these directories. Helm now follows the XDG specification. +* The `stable` repository is no longer added by default. This repository will be deprecated during the life of Helm v3 and we are now moving to a distributed model of repositories that can be searched by the [Helm Hub](https://hub.helm.sh). +* The `helm search` command has been refactored to have sub-commands that can search the local repositories and the Helm Hub. +* Release names are now scoped to namespaces. In Helm v2 the names were scoped to the namespace Tiller was running in. When Tiller was running for an entire cluster the names were scoped to the cluster. Names are now scoped to the same namespace as the release. +* JSON schemas can now be imposed on chart values and bundled with the chart. The schemas can be used for validating chart values. +* A new API version of charts are available. This new `apiVersion` is `v2` and contains several changes including: + * Requirements are now listed in the `Chart.yaml` file instead of the `requirements.yaml` file. + * A `crd` directory has been added to charts for the placement of CRDs. These will be installed before the rendering of the templates is performed. Once the Kubernetes community has worked out more workflow details with CRDs more features can be added to Helm to support them. +* The `crd-install` hook has been removed and will not work for Helm v2 charts. A "legacy" plugin will be released by the Helm project to support v1 charts with the `crd-install` hook. +* Experimental feature gates are now supported. As new potential features are added to Helm they can be worked on as experiments and enabled using an environment variable. +* Pushing and pulling charts from OCI registries is now an experimental feature. The final details of this feature are being worked out with the OCI on the proper use of the API. To access this feature set the environment variable `HELM_EXPERIMENTAL_OCI=1` needs to be set. +* `helm serve` has been removed. +* Helm now supports library charts. These charts are not meant to be installed but can be depended on and referenced by other charts. These were inspired by the [common chart](https://github.com/helm/charts/tree/master/incubator/common) in the incubator repository. +* `helm test` received some major refactoring. This included the `test-success` hook's behavior coming in line with other hooks and the removal of the `test-failure` hook due to lack of use. +* Several CLI changes have happened for usability including: + * `helm inspect` is now `helm show` + * `helm fetch` is now `helm pull` + * `helm delete` is now `helm uninstall` + * Instead of using the `--purge` flag on `helm uninstall` the behavior is to use the `--keep-history` if you want to keep the history. + +## Helm v3 Next Steps + +The next steps in the road to a Helm v3 stable release will be to focus on fixing bugs and stability. More beta releases or release candidates will follow before making a final `3.0.0` release. diff --git a/content/en/blog/2019-09-11-migrate-from-helm-v2-to-helm-v3.md b/content/en/blog/2019-09-11-migrate-from-helm-v2-to-helm-v3.md new file mode 100755 index 0000000000..c99483a400 --- /dev/null +++ b/content/en/blog/2019-09-11-migrate-from-helm-v2-to-helm-v3.md @@ -0,0 +1,347 @@ +--- +title: "How to migrate from Helm v2 to Helm v3" +slug: "migrate-from-helm-v2-to-helm-v3" +authorname: "Rimas Mocevicius" +author: "@rimusz" +authorlink: "https://rimusz.net" +date: "2019-09-11" +--- + +![../images/helm-2to3.png](../images/helm-2to3.png) + +One of the most important parts of upgrading to a new major release of Helm is the migration of data. This is especially true of Helm v2 to v3 considering the architectural changes between the releases. This is where the [helm-2to3](https://github.com/helm/helm-2to3) plugin comes in. + +It helps with this migration by supporting: + +- Migration of Helm v2 configuration. +- Migration of Helm v2 releases. +- Clean up Helm v2 configuration, release data and Tiller deployment. + +## Setting up Helm v3 + +As we do not want to override Helm v2 CLI binary, we need to perform an additional step to ensure that both CLI versions can co-exist until we are ready to remove Helm v2 CLI and all it's related data: + +Download latest Helm v3 release from [here](https://github.com/helm/helm/releases), rename the binary to `helm3` and store it in your path. + +We are ready to use `helm3`: + +``` +$ helm3 repo list +Error: no repositories to show +``` + +As you see there are no repositories set as Helm v3 comes without `stable` repository setup by default, let's fix it up. + +## helm-2to3 plugin + +`helm-2to3` plugin will allow us to migrate and cleanup Helm v2 configuration and releases to Helm v3 in-place. + +Installed Kubernetes objects will not be modified or removed. + +### Installing + +Let's install it: + +``` +$ helm3 plugin install https://github.com/helm/helm-2to3 +Downloading and installing helm-2to3 v0.2.0 ... +https://github.com/helm/helm-2to3/releases/download/v0.2.0/helm-2to3_0.2.0_darwin_amd64.tar.gz +Installed plugin: 2to3 +``` + +``` +$ helm3 plugin list +NAME VERSION DESCRIPTION +2to3 0.2.0 migrate and cleanup Helm v2 configuration and releases in-place to Helm v3 +``` + +``` +$ helm3 2to3 +Migrate and Cleanup Helm v2 configuration and releases in-place to Helm v3 + +Usage: + 2to3 [command] + +Available Commands: + cleanup cleanup Helm v2 configuration, release data and Tiller deployment + convert migrate Helm v2 release in-place to Helm v3 + help Help about any command + move migrate Helm v2 configuration in-place to Helm v3 + +Flags: + -h, --help help for 2to3 + +Use "2to3 [command] --help" for more information about a command. +``` + +Awesome. + +### Plugin features + +Currently plugin supports: + +- Migration of Helm v2 configuration +- Migration of Helm v2 releases +- Clean up Helm v2 configuration, release data and Tiller deployment + +## Migrate Helm v2 configuration + +First we need to migrate Helm v2 config and data folders: + +``` +$ helm3 2to3 move config -h +migrate Helm v2 configuration in-place to Helm v3 + +Usage: + 2to3 move config [flags] + +Flags: + --dry-run simulate a command + -h, --help help for move +``` + +It will migrate: + +- Chart starters +- Repositories +- Plugins + +The safest way is to start with --dry-run flag: + +``` +$ helm3 2to3 move config --dry-run +2019/11/14 14:54:04 NOTE: This is in dry-run mode, the following actions will not be executed. +2019/11/14 14:54:04 Run without --dry-run to take the actions described below: +2019/11/14 14:54:04 +2019/11/14 14:54:04 WARNING: Helm v3 configuration maybe overwritten during this operation. +2019/11/14 14:54:04 +[Move Config/confirm] Are you sure you want to move the v2 configration? [y/N]: y +2019/11/14 14:54:12 +Helm v2 configuration will be moved to Helm v3 configration. +2019/11/14 14:54:12 [Helm 2] Home directory: /Users/rimas/.helm +2019/11/14 14:54:12 [Helm 3] Config directory: /Users/rimas/Library/Preferences/helm +2019/11/14 14:54:12 [Helm 3] Data directory: /Users/rimas/Library/helm +2019/11/14 14:54:12 [Helm 3] Create config folder "/Users/rimas/Library/Preferences/helm" . +2019/11/14 14:54:12 [Helm 2] repositories file "/Users/rimas/.helm/repository/repositories.yaml" will copy to [Helm 3] config folder "/Users/rimas/Library/Preferences/helm/repositories.yaml" . +2019/11/14 14:54:12 [Helm 3] Create data folder "/Users/rimas/Library/helm" . +2019/11/14 14:54:12 [Helm 2] plugins "/Users/rimas/.helm/plugins" will copy to [Helm 3] data folder "/Users/rimas/Library/helm/plugins" . +2019/11/14 14:54:12 [Helm 2] starters "/Users/rimas/.helm/starters" will copy to [Helm 3] data folder "/Users/rimas/Library/helm/starters" . +``` + +Cool, now let's do the actual migration: + +``` +$ helm3 2to3 move config +WARNING: Helm v3 configuration maybe overwritten during this operation. + +[Move Config/confirm] Are you sure you want to move the v2 configration? [y/N]: y + +2019/11/14 14:55:00 Helm v2 configuration will be moved to Helm v3 configration. +2019/11/14 14:55:00 [Helm 2] Home directory: /Users/rimas/.helm +2019/11/14 14:55:00 [Helm 3] Config directory: /Users/rimas/Library/Preferences/helm +2019/11/14 14:55:00 [Helm 3] Data directory: /Users/rimas/Library/helm +2019/11/14 14:55:00 [Helm 3] Create config folder "/Users/rimas/Library/Preferences/helm" . +2019/11/14 14:55:00 [Helm 3] Config folder "/Users/rimas/Library/Preferences/helm" created. +2019/11/14 14:55:00 [Helm 2] repositories file "/Users/rimas/.helm/repository/repositories.yaml" will copy to [Helm 3] config folder "/Users/rimas/Library/Preferences/helm/repositories.yaml" . +2019/11/14 14:55:00 [Helm 2] repositories file "/Users/rimas/.helm/repository/repositories.yaml" copied successfully to [Helm 3] config folder "/Users/rimas/Library/Preferences/helm/repositories.yaml" . +2019/11/14 14:55:00 [Helm 3] Create data folder "/Users/rimas/Library/helm" . +2019/11/14 14:55:00 [Helm 3] data folder "/Users/rimas/Library/helm" created. +2019/11/14 14:55:00 [Helm 2] plugins "/Users/rimas/.helm/plugins" will copy to [Helm 3] data folder "/Users/rimas/Library/helm/plugins" . +2019/11/14 14:55:00 [Helm 2] plugins "/Users/rimas/.helm/plugins" copied successfully to [Helm 3] data folder "/Users/rimas/Library/helm/plugins" . +2019/11/14 14:55:00 [Helm 2] starters "/Users/rimas/.helm/starters" will copy to [Helm 3] data folder "/Users/rimas/Library/helm/starters" . +2019/11/14 14:55:00 [Helm 2] starters "/Users/rimas/.helm/starters" copied successfully to [Helm 3] data folder "/Users/rimas/Library/helm/starters" . +2019/11/14 14:55:00 Helm v2 configuration was moved successfully to Helm v3 configration. +``` + +Now let's run `helm3 repo list` again: + +``` +$ helm3 repo list +NAME URL +stable https://kubernetes-charts.storage.googleapis.com +jfrog https://charts.jfrog.io +rimusz https://charts.rimusz.net +buildkite https://buildkite.github.io/charts +jetstack https://charts.jetstack.io +odavid https://odavid.github.io/k8s-helm-charts +elastic https://helm.elastic.co +appscode https://charts.appscode.com/stable + +$ helm3 plugin list +NAME VERSION DESCRIPTION +2to3 0.1.0 migrate Helm v2 configuration and releases in-place to Helm v3 +edit 0.3.0 Edit a release. +gcs 0.2.0 Provides Google Cloud Storage protocol support. + https://github.com/vigles... +linter 0.1.1 Helm plugin to find hardcoded passwords in values.yaml files +monitor 0.3.0 Query at a given interval a Prometheus, ElasticSearch or Sentry instance... +``` + +Nice, now I can use the same Helm repositories and plugins which I have in Helm v2. + +**Note:** Please check that all Helm v2 plugins work fine with the Helm v3, and remove plugins that do not work. + +The move config will create the Helm v3 `config` and `data` folders if they don't exist, and will override the `repositories.yaml` file if it does exist. + +The plugin also supports non default Helm v2 `home` and Helm v3 `config` and `data` folders, an example of it's use: + +``` +$ export HELM_V2_HOME=$HOME/.helm2 +$ export HELM_V3_CONFIG=$HOME/.helm3 +$ export HELM_V3_DATA=$PWD/.helm3 +$ helm3 2to3 move config +``` + +## Migrate Helm v2 releases + +Now we are ready to start migrating releases. + +Let's check available options: + +``` +$ helm3 2to3 convert -h +migrate Helm v2 release in-place to Helm v3 + +Usage: + 2to3 convert [flags] RELEASE + +Flags: + --delete-v2-releases v2 release versions are deleted after migration. By default, the v2 release versions are retained + --dry-run simulate a command + -h, --help help for convert + -l, --label string label to select Tiller resources by (default "OWNER=TILLER") + -s, --release-storage string v2 release storage type/object. It can be 'secrets' or 'configmaps'. This is only used with the 'tiller-out-cluster' flag (default "secrets") + --release-versions-max int limit the maximum number of versions converted per release. Use 0 for no limit (default 10) + -t, --tiller-ns string namespace of Tiller (default "kube-system") + --tiller-out-cluster when Tiller is not running in the cluster e.g. Tillerless +``` + +Nice, the plugin even supports the [Tillerless Helm v2](https://github.com/rimusz/helm-tiller). + +Let's check out for Helm v2 releases and pick one to test out the migration: + +``` +$ helm list + +NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE +postgres 1 Thu Nov 14 15:01:00 2019 DEPLOYED postgresql-7.1.0 11.5.0 postgres +redis 1 Thu Nov 14 15:02:12 2019 DEPLOYED redis-9.5.4 5.0.6 redis +``` + +The safest way of course to start with `--dry-run` flag: + +``` +$ helm3 2to3 convert --dry-run postgres +2019/11/14 15:03:17 NOTE: This is in dry-run mode, the following actions will not be executed. +2019/11/14 15:03:17 Run without --dry-run to take the actions described below: +2019/11/14 15:03:17 +2019/11/14 15:03:17 Release "postgres" will be converted from Helm v2 to Helm v3. +2019/11/14 15:03:17 [Helm 3] Release "postgres" will be created. +2019/11/14 15:03:17 [Helm 3] ReleaseVersion "postgres.v1" will be created. +``` + +Now, let's run the actual migration: + +``` +$ helm3 2to3 convert postgres +2019/11/14 15:03:57 Release "postgres" will be converted from Helm v2 to Helm v3. +2019/11/14 15:03:57 [Helm 3] Release "postgres" will be created. +2019/11/14 15:03:57 [Helm 3] ReleaseVersion "postgres.v1" will be created. +2019/11/14 15:03:57 [Helm 3] ReleaseVersion "postgres.v1" created. +2019/11/14 15:03:57 [Helm 3] Release "postgres" created. +2019/11/14 15:03:57 Release "postgres" was converted successfully from Helm v2 to Helm v3. +2019/11/14 15:03:57 Note: The v2 release information still remains and should be removed to avoid conflicts with the migrated v3 release. +2019/11/14 15:03:57 v2 release information should only be removed using `helm 2to3` cleanup and when all releases have been migrated over. +``` + +Check out whether it was succesful: + +``` +$ helm list +NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE +postgres 1 Thu Nov 14 15:01:00 2019 DEPLOYED postgresql-7.1.0 11.5.0 postgres +redis 1 Thu Nov 14 15:02:12 2019 DEPLOYED redis-9.5.4 5.0.6 redis + +$ helm3 list -n postgres +NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION +postgres postgres 1 2019-11-14 13:01:00.188487 +0000 UTC deployed postgresql-7.1.0 11.5.0 +``` + +**Note:** As we did not specify `--delete-v2-releases` flag Helm v2 `postgres` release information was left in-tact, it can be deleted with `helm3 2to3 cleanup` later on. + +When are you ready to move all your releases, you can automate it with running `helm list` in a loop and applying `helm3 2to3 convert RELEASE` for each Helm v2 release. + +If you are using Tillerless Helm v2, just add `--tiller-out-cluster` to migrate the release: + +``` +$ helm3 2to3 convert postgres --tiller-out-cluster +``` + +Very cool and simple, right :-) + +## Clean up of Helm v2 data + +The last step is cleaning up the old data. While this is not required, we strongly recommend it. + +Let's check available options: + +``` +$ helm3 2to3 cleanup -h +cleanup Helm v2 configuration, release data and Tiller deployment + +Usage: + 2to3 cleanup [flags] + +Flags: + --config-cleanup if set, configuration cleanup performed + --dry-run simulate a command + -h, --help help for cleanup + -l, --label string label to select Tiller resources by (default "OWNER=TILLER") + --release-cleanup if set, release data cleanup performed + -s, --release-storage string v2 release storage type/object. It can be 'secrets' or 'configmaps'. This is only used with the 'tiller-out-cluster' flag (default "secrets") + --tiller-cleanup if set, Tiller cleanup performed + -t, --tiller-ns string namespace of Tiller (default "kube-system") + --tiller-out-cluster when Tiller is not running in the cluster e.g. Tillerless +``` + +It will clean: +- Configuration (Helm home directory) +- v2 release data +- Tiller deployment + +And of course the safest way is to start with `--dry-run` flag: + +``` +$ helm3 2to3 cleanup --dry-run +2019/11/14 15:06:59 NOTE: This is in dry-run mode, the following actions will not be executed. +2019/11/14 15:06:59 Run without --dry-run to take the actions described below: +2019/11/14 15:06:59 +WARNING: "Helm v2 Configuration" "Release Data" "Release Data" will be removed. +This will clean up all releases managed by Helm v2. It will not be possible to restore them if you haven't made a backup of the releases. +Helm v2 may not be usable afterwards. + +[Cleanup/confirm] Are you sure you want to cleanup Helm v2 data? [y/N]: y +2019/11/14 15:07:01 +Helm v2 data will be cleaned up. +2019/11/14 15:07:01 [Helm 2] Releases will be deleted. +2019/11/14 15:07:01 [Helm 2] ReleaseVersion "postgres.v1" will be deleted. +2019/11/14 15:07:01 [Helm 2] ReleaseVersion "redis.v1" will be deleted. +2019/11/14 15:07:01 [Helm 2] Home folder "/Users/rimasm/.helm" will be deleted. +``` + +It will show what releases going to be deleted, Tiller service to be removed from `kube-system` namespace and Helm v2 home folder will be deleted. + +When you are ready to clean up Hem v2 data, just run that command without `--dry-run` flag. + +**NOTE:** The `cleanup` command will remove the Helm v2 Configuration, Release Data and Tiller Deployment. It cleans up all releases managed by Helm v2. It will not be possible to restore them if you haven't made a backup of the releases. Helm v2 will not be usable afterwards. + +If you are using Tillerless Helm v2, just add `--tiller-out-cluster` to clean up Helm v2 data. + +The plugin also supports non default Helm v2 `home` data folder and Tiller releases `namespace`: + +``` +$ export HELM_V2_HOME=$PWD/.helm2 +$ helm 2to3 cleanup --tiller-ns some_namespace +``` + +**Happy Helm v3 sailing** diff --git a/content/en/blog/2019-10-22-helm-2150-released.md b/content/en/blog/2019-10-22-helm-2150-released.md new file mode 100755 index 0000000000..e20b70d917 --- /dev/null +++ b/content/en/blog/2019-10-22-helm-2150-released.md @@ -0,0 +1,37 @@ +--- +title: "Helm 2.15.0 Released" +authorname: "Matthew Fisher" +author: "@bacongobbler" +authorlink: "https://blog.bacongobbler.com" +date: "2019-10-22" +--- + +[Helm 2.15.0](https://github.com/helm/helm/releases/tag/v2.15.0) was released last week. The 2.15.0 release of Helm introduces several improvements to `helm test`. Several commands - `helm search`, `helm repo list`, and `helm install` - received the `--output` flag for machine-readable output. + +In addition to these new features (and many more!), many bugs and edge cases in Helm continue to fixed by members of the community. Several parts of the codebase have been refactored for easier maintainability, usability, and better testing. + +As Helm moves towards Helm 3's first release, Helm 2 is now transitioning into "maintenance mode". Helm 2.15.0 will be the final feature release for Helm 2. + +## Helm 2 support plan + +During the transition, we want to take into account any migration issues for users. We also want to clarify what actions may occur after the support contract ends for Helm 2, so that users will not be surprised or caught off guard. + +For Helm 2, we will continue to accept bug fixes and fix any security issues that arise, but no new features will be accepted. All feature development will be moved over to Helm 3. + +6 months after Helm 3's public release, Helm 2 will stop accepting bug fixes. Only security issues will be accepted. + +12 months after Helm 3's public release, support for Helm 2 will formally end. Download links for the Helm 2 client through Google Cloud Storage, the Docker image for Tiller stored in Google Container Registry, and the Google Cloud buckets for the stable and incubator chart repositories may no longer work at any point. Client downloads through get.helm.sh will continue to work, and we will distribute a Tiller image that will be made available at an alternative location which can be updated with `helm init --tiller-image`. + +## The big branch switch + +Ever since Helm 3's initial development, the core maintainers and the community have been pushing commits for Helm 3 to the `dev-v3` branch, and pushing commits for Helm 2 to the `master` branch. As Helm 3 now becomes the main development branch for all future work, we decided to switch the main trunk of the Helm repository over to Helm 3's development branch. + +With Helm 2 transitioning into maintenance mode, now was a good opportunity to switch branches over. + +Earlier this week, the transition was completed with no downtime. Moving forward, bug fixes for Helm 2 should target the `dev-v2` branch. Features and bug fixes for Helm 3 should target the `master` branch. + +## Parting thoughts + +The Helm team would like to thank the community for [nearly 3 years of contributions](https://github.com/helm/helm/releases/tag/v2.0.0) and [over 5,000 commits](https://github.com/helm/helm/tree/dev-v2) towards Helm 2 since its initial release. + +Onwards and upwards! diff --git a/content/en/blog/2019-10-30-helm-symlink-security-notice.md b/content/en/blog/2019-10-30-helm-symlink-security-notice.md new file mode 100755 index 0000000000..fa063aa143 --- /dev/null +++ b/content/en/blog/2019-10-30-helm-symlink-security-notice.md @@ -0,0 +1,36 @@ +--- +title: "Helm Vulnerability: Client Loading and Packaging Chart Directory Containing Malicious Symlinked Content [CVE-2019-18658]" +authorname: "Matt Farina" +author: "@mattfarina" +authorlink: "https://mattfarina.com" +date: "2019-10-30" +--- + +Part of the process for Helm to become a graduated CNCF project is to complete an independent and third party security audit with the results being published. As part of the audit of Helm 3 a security issue was found that also impacts Helm v2. [Cure53](https://cure53.de/) performed the audit and found the issue. More about the audit will be covered in a future post. + +The vulnerability found impacts **all versions of Helm between Helm >=2.0.0 and < 2.15.2**. Helm commands that deal with loading a chart as a directory or packaging a chart provide an opportunity for a maliciously designed chart to include content not intended in the chart or to execute a denial of service (DOS) on the computer performing the packaging via the use of symlinks. + +No version of Tiller is known to be impacted. This is a client-only issue. + +The following Helm commands may unsafely handle malformed charts: `helm package`, `helm install`, `helm upgrade`, and `helm dependency build`. + +We are unaware of any public exploits caused by this issue. + +## Details + +Helm charts can include symlinks. This feature provides a means of symlinking chart dependencies together when stored in a filesystem. Two types of symlinks can cause vulnerabilities. + +1. A symlink to a specially crafted file on the targets system. For example, a file containing sensitive information. When someone runs `helm package` this symlinked file will be copied into the archive without any notification. When the packaged file is moved elsewhere, such as to a Helm repository, the sensitive file will be sent along. +2. A symlink to a special file, such as a device driver. For example, a symlink to `/dev/urandom`. This would cause a command like `helm install` or `helm package` to continuously read from `/dev/urandom` as it tries to create the payload. + +No Tiller version is impacted. This vulnerability does not render clusters vulnerable to attack. Tiller does not load chart directories. + +## Workarounds + +A process work around can be used to mitigate the vulnerability. Do not load chart directories or package charts whose contents you do not trust or in an environment with sensitive information. + +## Fix + +Update to Helm >= 2.15.2. + +As of Helm 2.15.2, Helm will log to output all of the symlinked files referenced when packaging a chart and it will return an error while failing to load chart directories containing symlinks to irregular files (e.g., device or unix socket). diff --git a/content/en/blog/2019-11-04-helm-security-audit-results.md b/content/en/blog/2019-11-04-helm-security-audit-results.md new file mode 100755 index 0000000000..6d7a390540 --- /dev/null +++ b/content/en/blog/2019-11-04-helm-security-audit-results.md @@ -0,0 +1,35 @@ +--- +title: "Helm Security Audit Results" +authorname: "Matt Farina" +author: "@mattfarina" +authorlink: "https://mattfarina.com" +date: "2019-11-04" +--- + +Today, the Helm Maintainers are proud to announce that we have successfully completed a 3rd party security audit for Helm 3. Helm has been recommended for public deployment. + +A security audit is part of the graduation criteria for CNCF projects. Specifically, the [graduation criteria](https://github.com/cncf/toc/blob/main/process/graduation_criteria.adoc#graduation-stage) says: + +> Have completed an independent and third party security audit with results published of similar scope and quality as the following example (including critical vulnerabilities addressed): https://github.com/envoyproxy/envoy#security-audit and all critical vulnerabilities need to be addressed before graduation. + +During October, the CNCF funded [Cure53](https://cure53.de/) to perform a security audit of Helm version 3. Cure53 has performed audits of other CNCF projects including Prometheus, Envoy, Jaeger, Notary, and others. + +A [report from the security audit is available in the Helm community repo](https://github.com/helm/community/blob/main/security-audit/HLM-01-report.pdf). We recommend that you take a look at it for the details. The report covers their process, what they reviewed, and what they found. Their review included, but was not limited to: + +* The programming language used along with patterns and the use of external libraries +* Access control which is different in Helm v3 than in Helm v2 due to the removal of Tiller +* How logging and monitoring are handled +* Unit and regression testing +* Documentation, including the security contacts and process +* The process for fixing security issues +* The software used for signing and verification of Helm charts +* Manipulation of chart files +* TLS handling for communications + +From the Cure53 analysis there was only one noteworthy finding and it did not lead not an exploit. While the audit and issue were found to be in Helm v3 we also found the issue was present in Helm v2. Since Helm v2 has stable releases we announced a [security vulnerability](https://helm.sh/blog/2019-10-30-helm-symlink-security-notice/) and created a CVE. + +The [entire report](https://github.com/helm/community/blob/main/security-audit/HLM-01-report.pdf) is worth reading as no summary can do it justice. Cure53 provided a conclusion as part of their summary which reads: + +> To conclude, in light of the findings stemming from this CNCF-funded project, Cure53 can only state that the Helm project projects the impression of being highly mature. This verdict is driven by a number of different factors described above and essentially means that Helm can be recommended for public deployment, particularly when properly configured and secured in accordance to recommendations specified by the development team. + +Security audits are one of the benefits of CNCF projects and we are grateful for them and the analysis performed by Cure53. This analysis has provided some concrete areas we can work to improve and given us confidence in what we have. diff --git a/content/en/blog/2019-11-11-community-management.md b/content/en/blog/2019-11-11-community-management.md new file mode 100755 index 0000000000..f12da64759 --- /dev/null +++ b/content/en/blog/2019-11-11-community-management.md @@ -0,0 +1,17 @@ +--- +title: "Helm Community Management" +authorname: "Matt Farina" +author: "@mattfarina" +authorlink: "https://mattfarina.com" +date: "2019-11-11" +--- + +[Devstats](https://helm.devstats.cncf.io/) and stats on GitHub are able to capture many different types of contributions to an open source project. But there is one type of contribution for which we have yet to figure out a good metric, and it has been essential for Helm's success. That is community management. + +Karen Chu has handled community management for Helm since the project was first announced at the inaugural KubeCon in San Francisco. Her work ranges from big things, like planning and executing two Helm Summits, down to smaller (but still essential) things like managing the [Helm twitter account](https://twitter.com/HelmPack). + +Until this point, Karen's role has been pseudo-official. There has been no Helm related title or sub-project of Helm for this work. We are happy to announce that we have now rectified the situation by formalizing community management as a sub-project of Helm with Karen as the person running the show. + +Community managers do so much to make open source successful. Dave Neary, a community architect at Red Hat, highlighted some of the areas of value they bring in [a post about the roles filled by a community manager](https://community.redhat.com/blog/2018/01/the-many-faces-of-the-community-manager/). He talked about activities ranging from partnerships to developer enablement. We look forward to Karen's continued contributions in this space! + +If you want to learn more about community management, Karen is part of a panel at KubeCon + CloudNativeCon North America 2019 entitled ["What’s Essential in an OSS Project Launch Playbook?"](https://sched.co/Uabt). diff --git a/content/en/blog/2019-11-13-helm-3-released.md b/content/en/blog/2019-11-13-helm-3-released.md new file mode 100644 index 0000000000..0bc4c933a5 --- /dev/null +++ b/content/en/blog/2019-11-13-helm-3-released.md @@ -0,0 +1,125 @@ +--- +title: "Helm 3.0.0 has been released!" +slug: "helm-3-released" +authorname: "Matthew Fisher" +author: "@bacongobbler" +authorlink: "https://blog.bacongobbler.com" +date: "2019-11-13" +--- + +The Helm Team is proud to announce the first stable release of Helm 3. + +Helm 3 is the latest major release of the CLI tool. Helm 3 builds upon the success of Helm 2, continuing to meet the needs of the evolving ecosystem. + +The internal implementation of Helm 3 has changed considerably from Helm 2. The most apparent change is the removal of Tiller, but it's worth checking out the other changes by diving into the new release. A rich set of new features have been added as a result of the community's input and requirements. Some features have been deprecated or refactored in ways that make them incompatible with Helm 2. Some new experimental features have also been introduced, including OCI support. + +Additionally, the Helm Go SDK has been refactored for general use. The goal is to share and re-use code we've open sourced with the broader Go community. We are actively looking for feedback from other engineers integrating Helm in their own projects, and would love to hear from you in the [#helm-dev Kubernetes Slack channel](https://slack.k8s.io/). + +Here are some Helm 3 resources: + +- [Documentation](https://helm.sh/docs/) +- [FAQ: Changes since Helm 2](https://helm.sh/docs/faq/#changes-since-helm-2) +- [Installing Helm](https://helm.sh/docs/intro/install/) +- [Documentation on Helm 2 to Helm 3 migration](https://helm.sh/docs/topics/v2_v3_migration/) +- [Plugin to help migrate from Helm 2 to Helm 3](https://github.com/helm/helm-2to3) +- Chat with developers and contributors in the [#helm-users Kubernetes Slack channel](https://slack.k8s.io/) +- Please report bugs at + +## What is Helm? + +Helm gives teams the tools they need to collaborate when creating, installing, and managing applications inside of Kubernetes. + +With Helm, you can... + +- Find prepackaged software (charts) to install and use +- Easily create and host your own packages +- Install packages into any Kubernetes cluster +- Query the cluster to see what packages are installed and running +- Update, delete, rollback, or view the history of installed packages + +Helm makes it easy to run applications inside Kubernetes. + +## Let's see it! + +Assuming you have a Kubernetes cluster running and a correctly configured `kubectl`, working with Helm is a piece of cake. + +Helm makes it easy to search for new charts by adding repositories hosted by the community. + +```bash +$ helm repo add nginx https://helm.nginx.com/stable +``` + +Once you've added a few repositories, you can search for charts: + +```bash +$ helm search repo nginx-ingress +NAME CHART VERSION APP VERSION DESCRIPTION +nginx/nginx-ingress 0.3.7 1.5.7 NGINX Ingress Controller +``` + +Helm gives you a quick way to install that chart with `helm install`: + +```bash +$ helm install my-ingress-controller nginx/nginx-ingress +``` + +If we inspect the cluster with `kubectl`: + +```bash +$ kubectl get deployments +``` + +We have an ingress controller running! We can just as easily remove it with `helm uninstall my-ingress-controller`. + +Okay. You've tried some charts. You've customized a few. And now you're ready to build your own. Helm makes that part easy, too. + +```bash +$ helm create diy +Creating diy +``` + +Now you have a new chart named `diy`. You could go to that directory and edit it, run `helm template` to view the rendered output, or install it with `helm install`. + +Want to submit it upstream to the [Helm Hub](https://hub.helm.sh/)? Please do! Make sure to follow the documentation on [adding your own repositories](https://github.com/helm/hub/blob/master/Repositories.md) to the Helm Hub. + +## What changed in Helm 3? + +You may be asking yourself at this point: + +> How did the workflow change from Helm 2? If I run those commands with Helm 2, will I see the same output? + +Helm 2 described a workflow for creating, installing, and managing charts. Helm 3 builds upon that workflow, changing the underlying infrastructure to meet the needs of the evolving ecosystem. + +If you're comfortable with Helm 2, you'll feel right at home with Helm 3. + +To learn more about what changed under the hood, [check out the FAQ](https://helm.sh/docs/faq/) in the documentation. A list of changes and explanations for the changes involved are provided there. + +## The Future of Helm + +The core maintainers are really excited to release Helm 3.0. Helm's next phase of development will see new features targeted toward stability and enhancements to existing features. Features on the road map include: + +- Enhanced functionality for `helm test` +- Improvements to Helm's OCI integration +- Enhanced functionality for the Go client libraries + +### Helm 2 Support Plan + +In the Helm 2.15.0 release announcement, we shared details about the future plans for Helm 2. You can read more about those plans in [the announcement post](https://helm.sh/blog/2019-10-22-helm-2150-released/). + +## Relation of Helm 3 to Helm 1 and 2 + +In November 2015, the first version of Helm was released at the first KubeCon. Modeled on the macOS software installer [Homebrew](https://brew.sh/), Helm 1 (known by the team as "Helm Classic") was designed to help individual developers create packages of Kubernetes resources and deploy them into a cluster. + +A few months later (January 2016), Deis’ core Helm team joined forces with Google, Skippbox, and (shortly thereafter) Bitnami to produce a new version of Helm that shifted emphasis from individuals to teams. Along the way, we applied many of the lessons we’d learned. The result was a tool designed to not only make teamwork a central value, but also meet the needs of a burgeoning community of Kubernetes users who are installing sophisticated applications. + +In June 2018, Helm [joined the Cloud Native Computing Foundation](https://helm.sh/blog/helm-enters-the-cncf/). Helm 3 became a joint community effort, with core maintainers including members from Microsoft, Samsung SDS, IBM, and Blood Orange. Since the first alpha release, Helm 3 has seen contributions from 37 different members of the community, spanning across many time zones. The end result is a tool that reflects the needs of its community as those change and evolve over time. + +## Conclusion + +We set out to build a tool that is an on-ramp to Kubernetes. We wanted to make it easier for the Kubernetes user to create, share, and run production-grade workloads. + +Over 500 community members have contributed code to the Helm CLI since its inception. Thousands of community members actively maintain charts on the Helm Hub. There are a countless number of active community members. This is a credit to the colossal efforts of the Kubernetes community which has transformed this project from a simple Deis installer into a power tool for all Kubernetes users. + +Thank you all, and see you on GitHub! + +- The Helm Team :heart: \ No newline at end of file diff --git a/content/en/blog/2019-11-15-helm-at-cloudnativecon.md b/content/en/blog/2019-11-15-helm-at-cloudnativecon.md new file mode 100644 index 0000000000..b28873fb42 --- /dev/null +++ b/content/en/blog/2019-11-15-helm-at-cloudnativecon.md @@ -0,0 +1,17 @@ +--- +title: "Helm at KubeCon + CloudNativeCon NA 2019" +authorname: "Matt Farina" +author: "@mattfarina" +authorlink: "https://mattfarina.com" +date: "2019-11-15" +--- + +Next week is the annual [KubeCon and CloudNativeCon in North America](https://events19.linuxfoundation.org/events/kubecon-cloudnativecon-north-america-2019/). The Helm project and maintainers have several things going on and we wanted to invite you to them. + +Helm will have two maintainer track sessions that focus on an [_Introduction to Helm_](https://sched.co/UajI) and a [_Helm 3 Deep Dive_](https://sched.co/Uagg). Anyone who is new to Helm or would be interested in learning how and why they should use Helm, please consider attending the _Introduction to Helm_. If you are curious about the [recently released Helm 3](https://helm.sh/blog/helm-3-released/), the _Helm 3 Deep Dive_ is for you. Please let others know about these talks if you think they will interest them! + +This year also marks the first time the Helm project will have their own project specific booth! If you want to talk with the maintainers or have other questions about the project, the booth will be an excellent space to meet the people who regularly work on the project. + +There are several exciting Helm-centric sessions from the community this year. For example, Ricarto Rocha from CERN will be presenting [_Managing Helm Deployments with Gitops at CERN_](https://sched.co/UabD). You can check the schedule to learn about other sessions in the [official schedule](https://events19.linuxfoundation.org/events/kubecon-cloudnativecon-north-america-2019/schedule/). + +Going to be at the conference the weekend before it starts? [Cloud_Native Rejekts](https://cloud-native.rejekts.io/) will be going on and Taylor Thomas, one of the Helm project maintainers, will be presenting [_Advanced Interactions with Kubernetes (As Taught by Helm)_](https://cfp.cloud-native.rejekts.io/cloud-native-rejekts-na-2019/talk/SQ9DWX/). \ No newline at end of file diff --git a/content/en/blog/2020-04-02-covid-19-extending-helm-v2-bug-fixes.md b/content/en/blog/2020-04-02-covid-19-extending-helm-v2-bug-fixes.md new file mode 100644 index 0000000000..bf8626d989 --- /dev/null +++ b/content/en/blog/2020-04-02-covid-19-extending-helm-v2-bug-fixes.md @@ -0,0 +1,13 @@ +--- +title: "COVID-19: Extending Helm v2 Bug Fixes" +slug: "covid-19-extending-helm-v2-bug-fixes" +authorname: "Matt Farina & Bridget Kromhout" +authorlink: "https://helm.sh" +date: "2020-04-03" +--- + +As our world comes together to fight the global pandemic, the Helm maintainers want to ensure that we're doing our part to help you maintain your critical systems while they are operating at peak demand in a time where normal development and operation schedules have had to be adjusted. + +When Helm v3 was released in November 2019, our original commitment was that we would offer six months of Helm v2 bug fixes, which would end May 13, 2020, followed by six more months of security fixes for Helm v2. Given the expectation that current priorities require a singular focus on fighting the pandemic, we now plan to release Helm v2 bug fixes for an extra three months, until August 13th, 2020, giving Helm users more time for serving their communities' most immediate needs. + +We will monitor the situation to see if any additional adjustments are needed due to these circumstances. All Helm v2 support is currently still planned to end November 13th (with the window for security-only fixes now planned for three months). Join us in our [community calls, chats, mailing lists, and GitHub repositories](https://github.com/helm/community/blob/main/communication.md) if there is anything we can do to help unblock you in critical work, and stay safe! diff --git a/content/en/blog/2020-04-30-celebrating-helms-cncf-graduation.md b/content/en/blog/2020-04-30-celebrating-helms-cncf-graduation.md new file mode 100644 index 0000000000..ffb433c491 --- /dev/null +++ b/content/en/blog/2020-04-30-celebrating-helms-cncf-graduation.md @@ -0,0 +1,36 @@ +--- +title: "Celebrating Helm's CNCF Graduation" +slug: "celebrating-helms-cncf-graduation" +authorname: "Matt Butcher" +author: "@technosophos" +authorlink: "https://twitter.com/technosophos" +date: "2020-04-30" +twittertype: "summary_large_image" +twitterimage: "blog/images/helmgraduation-twitter.png" +--- + +![../images/helmgraduation.png](../images/helmgraduation.png) + +Today we are happy to see Helm [reach the final stage of the CNCF ladder](https://www.cncf.io/announcement/2020/04/30/cloud-native-computing-foundation-announces-helm-graduation/). Helm has moved from the incubating level to the graduated level as a [CNCF project](https://www.cncf.io/projects/), alongside Kubernetes and other select projects. + +Given Helm's humble beginnings as a hackathon project at Deis, a small startup, we are ecstatic to see our little baby all grown up. And we have certainly learned a lot about coding, community, and organizational politics over the last five years. But those are not the big reasons why we are celebrating Helm's graduation. + +Several months after Helm got started, we became a sub-project of Kubernetes itself. It was early 2016, and in short order we had gone from a side project to a viable package manager in the Kubernetes ecosystem. While Kubernetes had focused on the SRE and DevOps story, not masking complexity, Helm took a different approach. During a meeting in February of 2016, [Michelle Noorali](https://twitter.com/michellenoorali) wrote the following phrase on our whiteboard: "Zero to dopamine in five minutes." That was our Helm mantra: We saw an opportunity to make Kubernetes more approachable to newcomers. If we did things right, users could install Helm and then within minutes be installing production-grade off-the-shelf components. + +These days, Helm is [used by over 70% of Kubernetes users](https://www.cncf.io/wp-content/uploads/2020/03/CNCF_Survey_Report.pdf), from college students to major cloud providers. But we are most proud when we hear stories of Kubernetes newcomers getting up and running quickly because of Helm. + +Be that as it may, Helm's graduation marks a second distinction. Since the first commits to Helm, we called it "the package manager for Kubernetes," meaning that our overall design focus would be enabling redistribution, installation, upgrade, and deletion of bundles of Kubernetes resource definitions. Our goal was to be for Kubernetes what homebrew is to macOS, apt-get is to Debian/Ubuntu, and Chocolatey is to Windows. + +At the time, it seemed like a modest goal. After all, Kubernetes (at version 1.2) had very few users. But Kubernetes exploded in popularity. A few notable companies began running it in production. Then major cloud providers built hosted Kubernetes offerings. And then large enterprises known for focusing on stability rather than shininess also began using Kubernetes in earnest. This was an acid test for Helm. Could we meet the needs of hundreds of thousands of users, all with different goals and desires? It appears so. + +The term "graduation" confers the idea that a notable set of requirements has been completed. While we are thrilled to have a tremendous user base, CNCF publishes a list of criteria designed to test for enterprise-readiness. Stability, security, healthy governance, strong community -- these things are an absolute necessity if a large open source project is to succeed. + +CNCF states that [projects](https://www.cncf.io/projects/) can only graduate when they demonstrate that they are ready for the mainstream majority of users. The list of criteria for moving from incubation to graduation defines what it means to be a stable open source project. Helm took the graduation criteria to heart. Helm didn't just pass our security review, we did so with flying colors. We didn't just qualify for the [CII badge](https://bestpractices.coreinfrastructure.org/en), we scored a [198% on the certification test](https://bestpractices.coreinfrastructure.org/en/projects?q=helm%20package%20manager). While we only needed two committers from two different companies, we have many, many contributors from all over the globe. And over the years we have repeatedly demonstrated our commitment to open and fair governance. + +And so we stand at this milestone. We completed the last requirement for graduation: the CNCF Technical Oversight Committee (TOC) has voted by supermajority in agreement that Helm is now a top-level project. + +So what changes are in store for Helm in the future? Process-wise, things will remain as they already are. We will continue our unwavering commitment to stability and compatibility from major version to major version. We have begun the very earliest investigations into what Helm 4 may have in store. And we are (as always) eager to welcome new participants into our community, from helpful users who want to share their experiences through seasoned experts who wish to contribute substantial time to the upkeep of the project. Moreover, we are excited for the [CNCF's Artifact Hub](https://devclass.com/2020/03/12/cncf-starts-new-artifact-hub/) project, which we believe will truly bring together several major movements within CNCF. We are excited to continue working with CNCF's community. + +We would like to continue our tradition of ending our Helm articles with a huge thank-you to the tens of thousands of community members who have, in ways small and large, contributed to the success of Helm. Here's to many more years of providing that "zero to dopamine in five minutes" experience to all Kubernetes users! + + diff --git a/content/en/blog/2020-08-13-helm-v2-deprecation-timeline.md b/content/en/blog/2020-08-13-helm-v2-deprecation-timeline.md new file mode 100644 index 0000000000..9e2e3619c1 --- /dev/null +++ b/content/en/blog/2020-08-13-helm-v2-deprecation-timeline.md @@ -0,0 +1,46 @@ +--- +title: "Helm v2 Deprecation Timeline" +slug: "helm-v2-deprecation-timeline" +authorname: "Bridget Kromhout" +author: "@bridgetkromhout" +authorlink: "https://twitter.com/bridgetkromhout" +date: "2020-08-12" +--- + + +_[with a nod to Lewis Carroll...](https://www.jabberwocky.com/carroll/walrus.html)_ + + “The time has come,” the maintainers said, + “To talk of software fates: + Of upgrades -- and shipping Helm v3 -- + Of bugfixes -- and k8s --” + +[Helm v3 was released in November 2019](/blog/helm-3-released/), the result of ongoing community effort to evolve Helm to meet the community’s needs. With a streamlined client-only experience, a renewed focus on security, and tighter integration with Kubernetes APIs, Helm v3 continues to provide production-tested package management for Kubernetes. And as a [graduated CNCF project](/blog/celebrating-helms-cncf-graduation/), Helm is a key part of the cloud native ecosystem. + +We recognize that rolling out a major version change in production requires time. The Helm maintainers committed to providing bugfixes for Helm v2 until May 2020 (which they [extended to August 2020](/blog/covid-19-extending-helm-v2-bug-fixes/)) and security patches for Helm v2 until November 2020. And now the bugfix window is closing; [Helm v2.16.10](https://github.com/helm/helm/releases/tag/v2.16.10) will be the final bugfix release and 2.17.0 will follow with the [download location updated](https://github.com/helm/helm/issues/8346). + +What does this mean for Helm users? + +_After August 13, 2020, you will see these changes:_ +- If you’re still using Helm v2, you will want to [migrate to Helm v3](/blog/migrate-from-helm-v2-to-helm-v3/) now. Helm 3.2.4 is widely used and production-ready. While largely backwards-compatible, there are specific changes you’ll want to be aware of when carrying out your migration. +- Starting now, ongoing support of Helm v2 is limited to the next three months of security patches. That means we will no longer be accepting pull requests for anything but verified security issues. +- The `stable` and `incubator` repos will be de-listed from the Helm Hub, [introduced in December 2018](/blog/intro-helm-hub/). Find your preferred repositories on [Helm Hub](https://hub.helm.sh) to add them to your configs, and [track the migration of charts to their new decentralized locations](https://github.com/helm/charts/issues/21103). + + +_After November 13, 2020, you will see these changes:_ +- No further Helm v2 releases (even for security patches) +- No further updates to [Helm v2 documentation](https://v2.helm.sh/docs), which will remain available for the present time but may be discontinued +- Existing and new issues/PRs that are v2-specific will be closed +- [Transitioning Helm release and chart hosting ownership to CNCF](https://github.com/helm/community/issues/114) + +| | | +| - | - | +| To Be Removed | Replacement | +| Download links for the Helm v2 client through Google Cloud Storage | Client downloads through [get.helm.sh](/blog/get-helm-sh/)| +| Docker image for Tiller stored in Google Container Registry | We will distribute a Tiller image that will be [made available at an alternative location](https://github.com/helm/helm/issues/8346) which can be updated with helm init --tiller-image. | +| Google Cloud buckets for the stable and incubator chart repositories | “Stable” and “incubator” repositories discontinued; https://github.com/helm/charts marked as obsolete | + +The community has found Helm v3 to be a vastly improved experience, and community resources like the [helm-2to3 plugin](https://github.com/helm/helm-2to3) are available to assist you in your essential migration. Please ensure that you migrate to Helm v3 before the November 13th deadline, as operating software which no longer receives security patches is a risk best avoided. + +We want to take this moment to thank everyone in the community who has used Helm or contributed an issue or pull request to help improve it. Many great ideas that don’t fit into Helm itself have much success as [related ecosystem projects](https://helm.sh/docs/community/related/). Every time you submit updates to the docs, you’re helping others get started and be more effective with Helm. Thank you all! + diff --git a/content/en/blog/2020-10-07-helm-hub-moving-artifact-hub.md b/content/en/blog/2020-10-07-helm-hub-moving-artifact-hub.md new file mode 100644 index 0000000000..e5eda6bbda --- /dev/null +++ b/content/en/blog/2020-10-07-helm-hub-moving-artifact-hub.md @@ -0,0 +1,34 @@ +--- +title: "Helm Hub Moving To Artifact Hub" +slug: "helm-hub-moving-to-artifact-hub" +authorname: "Matt Farina" +author: "@mattfarina" +authorlink: "https://mattfarina.com" +date: "2020-10-07" +--- + +Today, we are happy to announce that the Helm Hub is moving to the [Artifact Hub](https://artifacthub.io/). That means, when you go to the Helm Hub you will be redirected to the Artifact Hub. + +## What This Means For You + +If you search the Helm Hub or list your charts in the Helm Hub you might wonder, what does this mean for me? + +The Artifact Hub lists all of the same charts the Helm Hub has listed. It provides search that is faster and includes [faceted search](https://en.wikipedia.org/wiki/Faceted_search). You should be able to discover charts in a similar way to what you did before. Searching continues to work with the Helm CLI, as well. + +There is more in the Artifact Hub than just searching for charts. You can get notifications via email or web hook when a chart is updated. You can find other artifacts and see related artifacts. The Artifact Hub provides more than the Helm Hub did. + +If you listed your chart repositories in the Helm Hub and didn't already have them listed in the Artifact Hub, they were automatically brought over. The Artifact Hub provides a means to claim your repository as well as list new ones. When listing a repository you can connect it to a user account or a multi-user organization. + +## Why We Are Doing This + +The Helm Hub was built on the Monocular project. This project was built to handle a limited number of Helm repositories and was designed for a slightly different use case than a public listing of as many chart repositories as possible. It served the Helm project well but has begun to show some limitations as the number of Helm charts and repositories grew. We knew we needed to do something about this problem with the Helm Hub. + +The Artifact Hub came along as we were starting to experience growth issues. Instead of operating our own instance of the Artifact Hub or writing our own software to handle the scaling issues, we are deferring to the Artifact Hub to handle chart discovery and management. The Artifact Hub supports and promotes more of the CNCF ecosystem than just charts. + +## Questions, Concerns, or Issues + +If you experience issues with the changeover please let us know. There are a few ways you can do this: + +1. If the issue is claiming your chart repository on the Artifact Hub from the migration, please file an issue on the [Helm Hub repository](https://github.com/helm/hub). +2. Experiencing a problem with the Artifact Hub site, then you can file an issue with the [Artifact Hub project](https://github.com/artifacthub/hub). It is a CNCF project and open source. +3. Having problems using the Helm CLI to search the Artifact Hub? You can file an issue with [Helm](https://github.com/helm/helm). Note, URLs for charts will still begin with `hub.helm.sh`, by default, when found in search. diff --git a/content/en/blog/2020-10-19-helm-turns-five.md b/content/en/blog/2020-10-19-helm-turns-five.md new file mode 100644 index 0000000000..aff37a92e4 --- /dev/null +++ b/content/en/blog/2020-10-19-helm-turns-five.md @@ -0,0 +1,41 @@ +--- +title: " Helm Turns 5, and GitHub Gives the Gift of Charts" +slug: "helm-turns-five" +authorname: "Matt Butcher & Matt Farina" +author: "@technosophos & @mattfarina" +authorlink: "https://helm.sh" +date: "2020-10-19" +--- + +{{< figure src="https://helm.sh/blog/images/happy-5th.png" alt="Happy 5th Birthday Helm" >}} + +Five years ago, in a hackathon at Deis (who has since been acquired by Microsoft) Helm was born. + + +``` +commit ecad6e2ef9523a0218864ec552bbfc724f0b9d3d +Author: Matt Butcher +Date: Mon Oct 19 17:43:26 2015 -0600 + + initial add +``` + +[This commit](https://github.com/helm/helm-classic/commit/ecad6e2ef9523a0218864ec552bbfc724f0b9d3d) can be found on the helm-classic Git repository where the codebase for Helm v1 is located. This is the original Helm, before it merged with Deployment Manager and was folded into Kubernetes. This is where it all began. + +Since day one, the Helm project has relied upon GitHub for source control, pull request management, and issue tracking. As a graduated CNCF project, the Helm org now manages dozens of GitHub repositories. + +But when it came to hosting the packaged charts, we stored them in an object storage bucket hosted on Google Cloud. This historical decision reflects that at that time Google was one of the principal contributors to Helm. + +Recently, Google’s time of supporting the official Helm chart repository has come to a close. We are grateful for Google’s hosting the Helm chart repository these last few years. But this event has given us an opportunity to further integrate our chart development pipeline with GitHub. + +{{< figure src="../images/octocat.png" alt="Hello Github Octocat!" width="350px" >}} + +So for today’s birthday celebration, we would like to announce that the Helm `stable` and `incubator` chart repositories will be directly hosted out of GitHub. Furthermore, GitHub Actions will power the pipeline for publishing charts. And thanks to GitHub’s blazingly fast network, chart downloads are faster than ever! + +We have even published official Helm GitHub Actions in the GitHub marketplace. Check out [Helm Chart Releaser](https://github.com/marketplace/actions/helm-chart-releaser) for a way to host Helm charts in GitHub. + +While Helm 2 is at the end of its support, we did also move the [official Tiller Docker images](https://github.com/orgs/helm/packages) to GitHub’s container registry. + +We are deeply appreciative of GitHub’s tooling and their support for open source projects of all sizes. + +Happy Birthday, Helm! diff --git a/content/en/blog/2020-10-26-new-location-stable-incubator-charts.md b/content/en/blog/2020-10-26-new-location-stable-incubator-charts.md new file mode 100644 index 0000000000..497787d214 --- /dev/null +++ b/content/en/blog/2020-10-26-new-location-stable-incubator-charts.md @@ -0,0 +1,61 @@ +--- +title: "New Location For Stable and Incubator Charts" +slug: "new-location-stable-incubator-charts" +authorname: "Matt Farina" +author: "@mattfarina" +authorlink: "https://mattfarina.com" +date: "2020-10-26" +--- + +[As previously announced](https://helm.sh/blog/helm-turns-five/), the stable and incubator repositories have moved to a new location. This post will update you on the new locations and provide directions to start using them. + +_**Important Note:** This does not affect the obsolescence timeline for the stable and incubator repositories that was announced in 2019. On November 13, 2020 the stable and incubator charts repository will reach the end of development and become archives. You can find that many of the charts have moved to other, community managed, repositories. You can discover these on the [Artifact Hub](https://artifacthub.io/). More information on the obsolescence will follow in future blog posts and communications._ + +The new location for the stable repository is https://charts.helm.sh/stable and the new location for the incubator repository is https://charts.helm.sh/incubator. If you use charts in either of these old locations below you MUST update the repositories you use before November 13, 2020. The new locations are hosted using GitHub pages. + +| Name | Old Location | New Location | +| --------- | ------------ | ------------ | +| stable | https://kubernetes-charts.storage.googleapis.com | https://charts.helm.sh/stable | +| incubator | https://kubernetes-charts-incubator.storage.googleapis.com | https://charts.helm.sh/incubator | + + +Along with the new locations, Helm v2.17.0 and v3.4.0 have been released to help you use the new location. You are encouraged to upgrade to the latest versions. + +## Helm v3.4.0 + +Helm v3.4.0 will now detect if you have the stable and incubator repository configured with the old location and warn you that you need to update your configuration to the new location. You can do this using a single command. For example, to update the stable repository that was set with the name `stable` you can run: + +``` +helm repo add stable https://charts.helm.sh/stable --force-update +``` + +This command will also work on Helm v3 versions prior to v3.4.0. You can use it without updating to the latest Helm v3 release. + +In addition to that, if you try to use `helm repo add` to add one of the repositories at the old location Helm v3.4.0 and newer will fail to add the repository and warn you to use the new location. Instead of making it automatically add the new location we wanted to make people aware of the location change. If you have a reason to use one of the old locations you can use the new `--allow-deprecated-repos` flag to allow them to be used. The flag will only be useful for as long as the previous location is still operating. + +## Helm v2.17.0 + +Helm v2 added the stable repository by default when `helm init` was run. This has led to a different solution for Helm v2, starting in v2.17.0. + +If you do not need the stable or local repositories, you can use the `--skip-repos` flag when running `helm init`. This is a new flag in v2.17.0. This can have some performance benefits in some use cases such as CI systems where you aren't using the stable repository. + +In v2.17.0, when `helm init` is run the new location is used instead of the old location. This is what will happen in CI systems that regularly run `helm init`. If you need to continue to use the old location, you can pass the new `--use-deprecated-stable-repository` flag to `helm init`. This will only work for as long as the old locations continue to operate. + +If you already have an old location configured for the stable or incubator repository, Helm will warn you that you need to switch to the new location. Doing this in Helm v2 is a little different from v3. You will need to use two commands. For example, to change the `stable` repository you can run: + +``` +helm repo rm stable +helm repo add stable https://charts.helm.sh/stable +``` + +This command will work on Helm v2 versions prior to v2.17.0. You can use it without updating to the latest Helm v2 release. + +_Note: In addition to the stable and incubator repositories moving to GitHub Pages, the default location for [Tiller has moved to GitHub Container Repository (ghcr.io)](https://github.com/orgs/helm/packages/container/package/tiller). [Tiller is still available from GCR](https://gcr.io/kubernetes-helm/tiller) (its previous home). You can also get Tiller from [Docker Hub](https://hub.docker.com/r/helmpack/tiller) and [Quay](http://quay.io/helmpack/tiller). To specify a non-default location for Tiller you can use the `-i` or `--tiller-image` flag when running `helm init`._ + +## Host Your Own Copy + +There are cases where you may control where Helm can make network calls to and you do not want Helm to make calls to GitHub pages. One option, if you need some charts from the stable or incubator repository, is to host a copy of the chart and chart versions you need in your own repository. You could host this repository with [ChartMuseum](https://github.com/helm/chartmuseum), [Harbor](https://goharbor.io/), a static web server, or another system. + +Scott Rigby, one of the Helm Org and Charts maintainers, has created [a script that can copy all or some of the charts and their histories](https://github.com/scottrigby/helm-adopt-package-history) (previous chart versions). This tool, and those like it, can be used to make copies of the charts you use. This can be served from an alternative location. + +In Helm v2, you can specify an alternative location for the stable repository when running `helm init` by using the `--stable-repo-url` flag. diff --git a/content/en/blog/2020-10-30-charts-repo-deprecation.md b/content/en/blog/2020-10-30-charts-repo-deprecation.md new file mode 100644 index 0000000000..7b5e966996 --- /dev/null +++ b/content/en/blog/2020-10-30-charts-repo-deprecation.md @@ -0,0 +1,38 @@ +--- +title: "Helm Chart Repository Deprecation Update" +slug: "charts-repo-deprecation" +authorname: "Vic Iglesias" +author: "@vicnastea" +authorlink: "https://twitter.com/vicnastea" +date: "2020-10-30" +--- + +Back in 2019, when the Helm v2 support timeline and end of life plan was announced, [the deprecation](https://github.com/helm/charts#deprecation-timeline) of the [helm/charts GitHub repository](https://github.com/helm/charts) was announced, as well. The primary reason for the deprecation is the significant increase in upkeep for the [repo maintainers](https://github.com/helm/charts/blob/master/OWNERS). Over the last couple of years the number of charts under maintainance increased from ~100 to 300+ causing a commensurate increase in pull requests and updates to the repo. Unfortunately, despite many efforts to automate review and maintenance tasks, the amount of time available from maintainers has not increased. + +When we announced the deprecation we also began to share the tools and guidance that we had used to maintain the helm/charts repo. For folks that want to host and maintain their own repositories you now have these tools available to streamline the process: + +- [Chart Testing](https://github.com/helm/chart-testing) provides linting and testing for PRs against your charts +- [Chart Releaser](https://github.com/helm/chart-releaser) provides tooling to help you host your own chart repo with GitHub Releases and Pages used to host your artifacts +- [Testing and Releasing Github Actions](https://github.com/helm?q=chart+action) to automate the tooling described above using GitHub Actions + +With these tools available we've enabled many charts to [migrate to their own repositories](https://github.com/helm/charts/issues/21103) for active maintenance. + +## Key Dates and Recommended Actions + +There has been refinement to the plans and confusion/questions about what happens next, so we wanted to provide a timeline of key events and **recommended actions** moving forward: + +* Nov 2, 2020 - READMEs for all non-deprecated charts will get a note added, stating that they will no longer be updated + * **RECOMMENDED ACTION** - If you depend on a chart in the Charts repository look for the new official location. If one does not exist, consider adopting the chart. +* Nov 6, 2020 the stable and incubator charts repos will be removed from the [Artifact Hub](https://artifacthub.io/) + * **RECOMMENDED ACTION** - None +* Nov 13, 2020 - CI on the [helm/charts repository](https://github.com/helm/chart) will be disabled and no more Pull Requests will be accpeted. + * **RECOMMENDED ACTION** - For more info on the ongoing initiative to relocate charts to new repos please see [this issue](https://github.com/helm/charts/issues/21103). +* *After* Nov 13, 2020 - Downloads of Charts at their old locations will be re-directed to the read-only archive available in GitHub Pages. The old locations may no longer be available after this date. + * **RECOMMENDED ACTION** - See info on [switching to the archived stable and incubator charts](https://helm.sh/docs/faq/#i-am-getting-a-warning-about-unable-to-get-an-update-from-the-stable-chart-repository). Keep in mind that these charts will no longer be updated with bug fixes or security patches. + + +## References + +* [Charts Repo Deprecation Timeline](https://github.com/helm/charts/issues/23944) +* [Relocation of package history](https://github.com/helm/charts/issues/23850) +* [Request to transition Helm Chart hosting to CNCF](https://github.com/helm/community/issues/114) diff --git a/content/en/blog/2020-11-11-helm-release-process.md b/content/en/blog/2020-11-11-helm-release-process.md new file mode 100644 index 0000000000..ebb330b75d --- /dev/null +++ b/content/en/blog/2020-11-11-helm-release-process.md @@ -0,0 +1,21 @@ +--- +title: "Helm’s First Patch Wednesday" +slug: "helm-release-process" +authorname: "Matt Farina" +author: "@mattfarina" +authorlink: "https://mattfarina.com" +date: "2020-11-11" +--- + +Helm recently adopted [a release schedule for minor and patch releases](https://github.com/helm/community/blob/main/hips/hip-0002.md). Today, the second Wednesday in November 2020, marks the first release under the new schedule. This release schedule provides predictability to those who use Helm, contribute to Helm, and maintain Helm. + +The release schedule generally follows these rules: + +* Patch releases happen on the 2nd Wednesday of the month when there isn't a major or minor release. This will happen if there are changes that could be released. +* Minor releases will roughly align with Kubernetes releases and have three to four month development windows, as Kubernetes does. These releases will lag behind Kubernetes so that Helm can be updated and tested for any changes to Kubernetes. +* When a minor version is released the next minor version will be scheduled. The date will be published to https://helm.sh/. For example, v3.5.0 is scheduled for Wednesday January 13th. Instead of a patch release that day there will be a minor release. +* Security releases do not need to follow any of these rules. They will be released as needed. + +A calendar of upcoming dates for releases can be found on the calendar at https://helm.sh/calendar/release. This is a redirect to the calendar. + +More details can be found in [Helm Improvement Proposal 2](https://github.com/helm/community/blob/main/hips/hip-0002.md). diff --git a/content/en/blog/2020-11-13-helm-2-becomes-unsupported.md b/content/en/blog/2020-11-13-helm-2-becomes-unsupported.md new file mode 100644 index 0000000000..a8541bccf5 --- /dev/null +++ b/content/en/blog/2020-11-13-helm-2-becomes-unsupported.md @@ -0,0 +1,27 @@ +--- +title: "Helm 2 and the Charts Project Are Now Unsupported" +slug: "helm-2-becomes-unsupported" +authorname: "Matt Butcher" +author: "@technosophos" +authorlink: "https://technosophos.com" +date: "2020-11-13" +--- + +A year ago, we [introduced Helm 3](https://helm.sh/blog/helm-3-released/), a major evolution in Helm's development. And we [announced](https://helm.sh/blog/2019-10-22-helm-2150-released/) at that time that Helm 2 would receive patches and security updates for a year. + +Here we are, one year later. Friday the 13th, 2020 seems like a fitting day to end support for a major version. And today, we are announcing the official end of support for Helm 2. The charts repository is also now read-only, with no further changes. + +From this point forward, the Helm team will devote all of its energy to Helm 3 and our ecosystem tools. + +In practice, this means the following: + +- **Helm 2** will receive no more updates (not even security patches). +- The **Helm Charts** [GitHub project](https://github.com/helm/charts) will receive no more updates. +- The Helm **Stable and Incubator charts** repositories have been moved to an archive. See [our blog post](https://helm.sh/blog/new-location-stable-incubator-charts/) for more. +- **Helm 3** will [continue](https://github.com/helm/helm/releases) to add new features, fix bugs, and address security issues. +- [Other Helm projects](https://github.com/helm) like our **GitHub actions** will continue feature development as well. +- **Artifact Hub** is now the official location for [finding Helm charts](https://artifacthub.io/). + +We strongly discourage continued use of Helm 2, as it will be receiving no future security updates or patches. But if you need more time to migrate, we strongly encourage you to upgrade to Helm [2.17.0](https://github.com/helm/helm/releases/tag/v2.17.0), which has the final patches. For more, [check out the migration documentation](https://helm.sh/docs/topics/v2_v3_migration/). + +Finally, I would like to close with a heartfelt word of thanks to the dedicated people who have contributed to Helm and Charts over the years. \ No newline at end of file diff --git a/content/en/blog/2021-03-05-second-security-audit/arch.png b/content/en/blog/2021-03-05-second-security-audit/arch.png new file mode 100644 index 0000000000..e225b57f5c Binary files /dev/null and b/content/en/blog/2021-03-05-second-security-audit/arch.png differ diff --git a/content/en/blog/2021-03-05-second-security-audit/index.md b/content/en/blog/2021-03-05-second-security-audit/index.md new file mode 100644 index 0000000000..d02dc53126 --- /dev/null +++ b/content/en/blog/2021-03-05-second-security-audit/index.md @@ -0,0 +1,20 @@ +--- +title: "Helm 2nd Security Audit" +slug: "helm-2nd-security-audit" +authorname: "Matt Farina" +author: "@mattfarina" +authorlink: "https://mattfarina.com" +date: "2021-03-05" +--- + +Helm has now completed a second security audit, funded by the [CNCF](https://cncf.io). The [first audit](https://helm.sh/blog/2019-11-04-helm-security-audit-results/) focused on the source code for the Helm client along with the process Helm uses to handle security. The second audit, performed by [Trail of Bits](https://www.trailofbits.com/), looked at the source code for the Helm client along with a threat model for the use of Helm. + +The following diagram is from the [threat model](https://github.com/helm/community/blob/main/security-audit/Helm%20Threat%20Model%202020.pdf) and looks at the connections Helm makes along with how it stores files on the local filesystem. + +![](arch.png) + +As a result of the audit, the Helm security team worked on [a release](https://github.com/helm/helm/releases/tag/v3.3.2). + +We want to thank the CNCF for providing these security assessments. They provide an expert and outside look at projects, like Helm, so that we can have more security cloud native tooling. We also want to thank Trail of Bits for the assessment. It was a pleasure working with them. + +You can get the full reports for the [threat model](https://github.com/helm/community/blob/main/security-audit/Helm%20Threat%20Model%202020.pdf) and [security assessment](https://github.com/helm/community/blob/main/security-audit/Helm%20Final%20Report%202020.pdf) in the [Helm community repository](https://github.com/helm/community/tree/main/security-audit). diff --git a/content/en/blog/2021-06-24-welcome-martin-hickey.md b/content/en/blog/2021-06-24-welcome-martin-hickey.md new file mode 100644 index 0000000000..07fb605763 --- /dev/null +++ b/content/en/blog/2021-06-24-welcome-martin-hickey.md @@ -0,0 +1,13 @@ +--- +title: "Martin Hickey Joins Helm Org Maintainers" +slug: "welcome-martin-hickey" +authorname: "Matt Butcher" +author: "@technosophos" +authorlink: "https://twitter.com/technosophos" +date: "2021-06-24" +--- +Meet Helm's newest org maintainer: [Martin Hickey](https://hickeyma.github.io/). Martin has been a longtime Helm project maintainer. He was instrumental in the development of Helm 3, and has been one of the most active maintainers on the project. He is also one of the creators of the [Helm 2-to-3 migration plugin](https://github.com/helm/helm-2to3). + +This week, the Helm maintainers voted to elect Martin onto the Helm Org Maintainers board. In this new role, Martin will help shape not just Helm, but the many projects that are hosted together with Helm. As a first order of business, Martin will be migrating the [Map KubeAPIs plugin](https://github.com/hickeyma/helm-mapkubeapis) to the Helm organization. + +Congratulations to Martin! \ No newline at end of file diff --git a/content/en/blog/2022-01-11-welcome-karen-chu.md b/content/en/blog/2022-01-11-welcome-karen-chu.md new file mode 100644 index 0000000000..12a85aa11a --- /dev/null +++ b/content/en/blog/2022-01-11-welcome-karen-chu.md @@ -0,0 +1,14 @@ +--- +title: "Karen Chu Joins Helm Org Maintainers" +slug: "welcome-karen-chu" +authorname: "Matt Butcher" +author: "@technosophos" +authorlink: "https://twitter.com/technosophos" +date: "2022-01-11" +--- + +The Helm organization is thrilled to introduce [Karen Chu](https://twitter.com/karenhchu) as the latest member of the [Helm org maintainers](https://github.com/helm/community/blob/main/governance/governance.md#helm-org-maintainers). She will be the [ninth committee member](https://github.com/helm/community/blob/main/MAINTAINERS.md). Karen has been active in the Helm ecosystem since day one when Rimas, Jack, and I first started the project. She was instrumental in Helm's early branding, organized both of the Helm Summits, and leads Helm's community management team. You may also know her from her Helm-adjacent work as the co-creator of the [Illustrated Children's Guide to Kubernetes](https://www.cncf.io/phippy/) series or her role as a CNCF ambassador. + +Last week, the Helm project maintainers voted to elect Karen onto the Helm org maintainers board. In this role, Karen will help shape the many projects that are hosted under the Helm umbrella, bringing her insights from the wider ecosystem to her leadership of the Helm organization. + +Congratulations to Karen! \ No newline at end of file diff --git a/content/en/blog/2022-02-28-storing-charts-in-oci.md b/content/en/blog/2022-02-28-storing-charts-in-oci.md new file mode 100644 index 0000000000..0d1baac70b --- /dev/null +++ b/content/en/blog/2022-02-28-storing-charts-in-oci.md @@ -0,0 +1,104 @@ +--- +title: "Storing Helm Charts in OCI Registries" +slug: "storing-charts-in-oci" +authorname: "Scott Rigby, Josh Dolitsky, Matt Farina" +author: "@scottrigby, @jdolitsky, @mattfarina" +authorlink: "https://helm.sh" +date: "2022-02-28" +--- + +With the release of Helm 3.8.0, Helm is able to store and work with charts in container registries, as an alternative to [Helm repositories](https://helm.sh/docs/topics/chart_repository/). This feature, which used to be an experimental feature, is now generally available. + + + +Over the past several years container registry developers have been working on ways to store other artifacts in container registries. To facilitate this in a cross platform manner, the Open Containers Initiative (OCI) - the organization that defines the specifications for containers - released their [distribution specification](https://specs.opencontainers.org/distribution-spec/?v=v1.0.0) which allowed other "artifacts" to be stored in registries. + + + +## Common Storage + +Since OCI artifacts now makes it possible to store more than container images, you can store charts, images, and other artifacts in a single OCI registry. Sharing a common storage standard that's not specific to Helm allows greater interoperability between tools from the wider container ecosystem for security, identity and access management, and more. + +## Working With Charts In Registries + +The combination of OCI artifact support in a registry and new functionality within Helm provides the capability to pull and push charts to and from a registry. You can also specify charts stored in OCI as a dependency in any `Chart.yaml` file. The following example illustrates logging into a registry and pushing a chart: + +```text +$ helm create demo +Creating demo + +$ helm package demo +Successfully packaged chart and saved it to: /tmp/demo-0.1.0.tgz + +$ echo "mypass" | helm registry login r.example.com -u myuser --password-stdin +Login Succeeded + +$ helm push demo-0.1.0.tgz oci://r.example.com/myuser +Pushed: r.example.com/myuser/demo:0.1.0 +Digest: sha256:7ed393daf1ffc94803c08ffcbecb798fa58e786bebffbab02da5458f68d0ecb0 +``` + +More detail on [working with registries can be found in the Helm documentation](https://helm.sh/docs/topics/registries/). + +## The Helm SDK + +The Helm SDK, which is useful for those building tools to integrate with Helm, also includes support to work with registries programatically. The following example illustrates pushing a chart to a registry: + +```go +package main + +import ( + "fmt" + "io/ioutil" + + "helm.sh/helm/v3/pkg/registry" +) + +func check(err error) { + if err != nil { + panic(err) + } +} + +func main() { + client, err := registry.NewClient() + check(err) + + b, err := ioutil.ReadFile("demo-0.1.0.tgz") + check(err) + + info, err := client.Push(b, "r.example.com/myuser/demo:0.1.0") + check(err) + + fmt.Printf("Pushed: %s\n", info.Ref) + fmt.Printf("Digest: %s\n", info.Manifest.Digest) +} +``` + +More detail can be found in the [documentation for the registry package](https://pkg.go.dev/helm.sh/helm/v3/pkg/registry). + +## Limitations + +There are some limitations when using registries to store charts compared to Helm repositories or storing container images in registries. + +Helm repositores can be added and searched from the local Helm client. This is similar to how repositories work with other package managers such as zypper or apt. When working with OCI registries, this is not an option. OCI based registries don't provide standard APIs to facilitate searching. + +While the OCI specification provides support for artifacts, not all registries support storing Helm charts or other artifacts that are not container images. Before choosing a registry, you should confirm whether it supports storing Helm charts. + +## Artifact Hub Support + +[Artifact Hub](https://artifacthub.io/), another CNCF project, provides a means to search and discover cloud native assets, including charts. Helm charts stored in OCI based registries can be listed on Artifact Hub, which already knows how to work with them. More details on working with Artifact Hub and Helm charts in container registries can be found in their [documentation](https://artifacthub.io/docs/topics/repositories/#helm-charts-repositories). + +## ORAS + +The [OCI Registry as Storage (ORAS) project](https://oras.land/), another CNCF project, is used by Helm as the underlying library for working with registries. The ORAS project bills itself as: + +> Registries are evolving as generic artifact stores. To enable this goal, the ORAS project provides a way to push and pull OCI Artifacts to and from OCI Registries. + +If you want to work with other artifacts in registries the ORAS project may provide some tools to help you. + +## Thanks and Help Us Keep Improving + +Thanks to everyone who worked on adding support for Helm charts and OCI registries, from the initial experiment to bringing this to a full feature. Thanks especially for end user testing, bug reports and feature requests, and coordination between community members and maintainers across several CNCF projects. + +We hope this post helps give a good intro, and some things to consider when evaluating storing your Helm charts in OCI. See if it fits your needs, take it for a spin, and let us know what you think! diff --git a/content/en/blog/2022-04-19-tools-to-manage-helm-declaratively.md b/content/en/blog/2022-04-19-tools-to-manage-helm-declaratively.md new file mode 100644 index 0000000000..9854da9a7d --- /dev/null +++ b/content/en/blog/2022-04-19-tools-to-manage-helm-declaratively.md @@ -0,0 +1,84 @@ +--- +title: "Tools You Can Use To Manage Your Helm Releases Declaratively" +slug: "tools-to-manage-helm-declaratively" +authorname: "Scott Rigby, Matt Farina" +author: "@scottrigby, @mattfarina" +authorlink: "https://helm.sh" +date: "2022-04-19" +--- + +We regularly get questions from people who want tools or methods to manage their Helm releases in an environment. This post provides some insight and direction to help people get started. + + + +## Why Helm Doesn't Have Tools To Do This + +You might wonder, why doesn't Helm provide tools to do this out of the box? + +Helm is a package manager. We often compare it to package managers for other platforms like apt, yum, zipper, homebrew, and others. All of these projects, Helm included, keep their scope within the realm of package management. + +Managing how instances of packages are run in an environment is a separate concern and one people have varying ideas about. For example, some people use Ansible, others use Terraform, some use both, and some use something entirely different. Different tools can even use different methods (e.g. some are push based and others pull based). _All of these are able work with the same package managers._ + +The Helm project strives to provide a package manager that works well with various other tools that can use a variety of different methods to manage releases. + +## Declarative and Imperative + +In the Kubernetes space we talk about _declarative_ management. If you're not familiar with the concept, here is a brief explanation. + +With declarative management you _declare_ to the _system_ what you want the end state to look like. For example, that you want X number of instances of your workload to be running. The system then works to make this a reality and usually reports status on the progress of making the declared status a reality. Over time, the way the system makes the declared state a reality can change without the need for what you declare or the status of the progress to change. + +Imperative management has to do with telling the system what to do step by step. Instead of declaring what you want you tell the system each step to take to achieve the end goal. + +Kubernetes provides a means to do both [declarative and imperative management of resources](https://kubernetes.io/docs/tasks/manage-kubernetes-objects/). As the Kubernetes community tends to prefer declarative management, when possible, the rest of this post is going to focus on declarative tools you can use with Helm. + +## Tools + +The Kubernetes ecosystem has produced numerous projects of various styles to help you declaratively manage your Helm releases. To illustrate the options we will look at sister projects to Helm in the Cloud Native Computing Foundation (CNCF) and some more general open source projects. You can find more options in the [CNCF Landscape](https://landscape.cncf.io/). + +### CNCF Projects + +The scope of this section is limited to [graduated and incubating](https://www.cncf.io/projects/) CNCF projects. There are over 100 CNCF projects and many of them are [sandbox projects](https://www.cncf.io/sandbox-projects/). You can learn more about the differences between types of projects in the [maturity level explanation](https://www.cncf.io/projects/#maturity-levels). The following projects are worth looking at: + +* [Flux Helm Controller](https://fluxcd.io/docs/components/helm/) - [Flux](https://fluxcd.io/) is a collection of projects that enable GitOps. One of the components provides a GitOps method to manage Helm releases. Flux natively supports Helm. +* [Argo CD](https://github.com/argoproj/argo-cd) - The [Argo](https://argoproj.github.io/) project defines itself as providing "Open source tools for Kubernetes to run workflows, manage clusters, and do GitOps right." Argo CD is focused on declarative continuous delivery and has the ability to work with Helm charts. + +### Other Projects + +There are many projects beyond the CNCF projects you can use to help you manage your Helm releases. The following set is an example and not exhaustive. + +* [Helmfile](https://github.com/helmfile/helmfile) - A declarative spec for deploying Helm charts. +* [Captain](https://github.com/alauda/captain) - A Helm controller. +* [Terraform Helm provider](https://github.com/hashicorp/terraform-provider-helm) - Enables you to manage Helm charts through Terraform. +* [Orkestra](https://azure.github.io/orkestra/) - Built on other tools in this list, Orkestra adds a robust dependency graph for a related group of Helm releases and their subcharts, as well as a reverse DAG for specifying dependency requirements for rollbacks. +* [Fleet](https://github.com/rancher/fleet) - A GitOps tool chain that works with Kubernetes manifests, Helm charts, and Kustomize. + +### High-Level Tool Comparison + +There are some differences between the tools we've looked at so far. The following table provides some insight into their differences. This is not exhaustive and you should evaluate any tools you use yourself. + +| | Retains Helm release info | Supports Helm hooks | OCI support | Does not require Helm binary | +| -- | -- | -- | -- | -- | +| Flux Helm controller | ✅ | ✅ | 🚫[^1] | ✅ | +| Argo CD | 🚫 | :warning:[^2] | ✅[^3] | 🚫 | +| Helmfile | ✅ | :warning:[^4] | :warning:[^5] | 🚫[^6] | +| Captain | ✅ | ✅ | :warning:[^7] | ✅ | +| Terraform Helm provider | ✅ | :warning:[^8] | ✅ | ✅ | +| Orkestra | ✅ | ✅ | 🚫[^9] | ✅ | +| Fleet | ✅ | ✅ | 🚫[^10] | ✅ | + +_Note, this comparison is from when the blog post was published. Projects change over time and the feature set may change over time. You should evaluate the projects in their current state before choosing one._ + +## Conclusion + +If you want to use a configuration manager with your Helm and Kubernetes configuration there are many choices. While the Helm project doesn't endorse one project over another, we do suggest using a configuration manager when it's appropriate. + +[^1]: Because Flux makes full use of the Helm SDK, as of Helm v3.8.0 Flux is now unblocked to add OCI artifact integration (Flux team members helped finish bringing OCI support out of experimental into a full feature in Helm). [RFC-0002](https://github.com/fluxcd/flux2/tree/main/rfcs/0002-helm-oci) is now marked as implementable, and work on this is now in progress for Flux. You can follow this fluxcd/source-controller issue [#669](https://github.com/fluxcd/source-controller/issues/669) for progress. +[^2]: Because Argo does not retain Helm release information, there is an [attempt to map](https://argo-cd.readthedocs.io/en/stable/user-guide/helm/#helm-hooks) Helm hooks to ArgoCD hooks, however, there are far fewer Argo hooks and unmappable concepts such as no differentiation between install and upgrade. You can work around this by writing your charts specifically for ArgoCD, however hooks in commonly used community charts will not work. +[^3]: ArgoCD shells out to the Helm CLI, only to render templates. This has allowed Argo to turn on Helm CLI's OCI feature before it was finished, for the same reason that it can not support Helm features beyond templating. Because of this, OCI is not part of the ArgoCD source architecture. +[^4]: Helmfile has a custom concept of hooks, not necessarily mapped to Helm hooks. See readme [hooks section](https://github.com/helmfile/helmfile#hooks) and [this issue](https://github.com/roboll/helmfile/issues/1291) for clarification and work in progress. +[^5]: Helmfile has experimental OCI support, without explicitly explaining to users that it sets `HELM_EXPERIMENTAL_OCI=1` before shelling out to the Helm CLI. See [#2112](https://github.com/roboll/helmfile/issues/2112) and [#2111](https://github.com/roboll/helmfile/issues/2111). +[^6]: Helmfile parameterizes the Helm binary (default: `helm`). +[^7]: Captain relies on a related project [alauda/oci-chartrepo](https://github.com/alauda/oci-chartrepo) to mix concepts of using oci registry as helm chart repo. +[^8]: Terraform Helm provider has [some issues](https://github.com/hashicorp/terraform-provider-helm/issues/683) with Helm hooks and wait configurations. +[^9]: Orkestra leverages Flux Helm Controller to reconcile the releases. See the note above about Flux Helm controller OCI status. Once a full implementation is released in Flux, Orkestra will also support OCI. +[^10]: Fleet uses the Helm SDK. Once it uses a version of the Helm SDK that supports OCI registries, Fleet will inherit support. diff --git a/content/en/blog/2022-10-14-helm-at-kubecon-na-22.md b/content/en/blog/2022-10-14-helm-at-kubecon-na-22.md new file mode 100644 index 0000000000..24efcb3346 --- /dev/null +++ b/content/en/blog/2022-10-14-helm-at-kubecon-na-22.md @@ -0,0 +1,38 @@ +--- +title: "Helm @ KubeCon + CloudNativeCon NA '22" +slug: "helm-at-kubecon-na-22" +authorname: "Karen Chu" +author: "@karenhchu" +authorlink: "https://twitter.com/karenhchu" +date: "2022-10-14" +--- + +The Helm maintainers are excited to be headed to KubeCon + CloudNativeCon NA '22 in Detroit, MI in a couple of weeks! As always, there will be a few different places you can find us! + + + +## Helm Maintainer Track Talk: [Learn about Helm and Its Ecosystem](https://sched.co/182Ns) + +DATE: Thursday October 27 + +TIME: 11:00am - 11:35am EDT + +LOCATION: Room 410 A + +Maintainers [Matt Farina](https://twitter.com/mattfarina), [Karena Angell](https://twitter.com/karenaangell), [Scott Rigby](https://twitter.com/r6by), & [Andrew Block](https://twitter.com/sabre1041) will be doing a [Maintainer Track talk](https://sched.co/182Ns) introducing Helm itself and then doing a deep dive into the ecosystem around building packages, along with using Helm packages in clusters. + +## Helm Booth in Project Pavilion + +WED OCT 26: 15:30 – 20:00 ET + +THUR OCT 27: 14:00 – 17:30 ET + +FRI Oct 28: 13:00 – 16:00 ET + +LOCATION: opposite side of the Fuzz booth, near the LitmusChaos/Flux/Cortex/Falco booths + +Our maintainers will be hanging out at our Helm project booth the second half of each day. We'd love to learn from the community how Helm is being used, what pain points exists, and what users are looking for in the future. Help us help you by sharing your thoughts in our [Helm User Survey](https://docs.google.com/forms/d/e/1FAIpQLSeR9fSlWShh49_URhAEPA88JVjlPiz1441CA1B2ySJGZg1dzQ/viewform), even if you're unable to drop by the booth. + +Now for the fun part – the Helm booth will be giving away 3D Helm stickers, glow-in-the-dark Helm stickers, Helm bike bells, or limited edition Helm + Carhartt beanies to stay warm while in Detroit! + +With that, we'll see the Helm community soon in-person! diff --git a/content/en/blog/2022-11-14-welcome-yxxhero.md b/content/en/blog/2022-11-14-welcome-yxxhero.md new file mode 100644 index 0000000000..6400f5a788 --- /dev/null +++ b/content/en/blog/2022-11-14-welcome-yxxhero.md @@ -0,0 +1,13 @@ +--- +title: "Helm welcomes yxxhero as our newest helm-www repo maintainer" +slug: "welcome-yxxhero" +authorname: "Karen Chu" +author: "@karenhchu" +authorlink: "https://twitter.com/karenhchu" +date: "2022-11-14" +--- + +The Helm project is happy to welcome [yxxhero](https://github.com/yxxhero) as our newest maintainer for the helm-www repo! + yxxhero has been a long time contributor to the Helm project over the years. With a supermajority vote from the existing maintainers, yxxhero will be joining to help with Helm documentation. With their background, yxxhero will continue to help strengthen both our simplified and traditional Chinese docs. + +Cheers to yxxhero! diff --git a/content/en/blog/2023-03-31-helm-completes-fuzzing-security-audit.md b/content/en/blog/2023-03-31-helm-completes-fuzzing-security-audit.md new file mode 100644 index 0000000000..8af247f224 --- /dev/null +++ b/content/en/blog/2023-03-31-helm-completes-fuzzing-security-audit.md @@ -0,0 +1,28 @@ +--- +title: "Helm Completes Fuzzing Security Audit" +slug: "helm-completes-fuzzing-security-audit" +authorname: "Adam Korczynski, David Korczynski & Martin Hickey" +author: "@AdamKorcz, @DavidKorczynski & @hickeyma" +authorlink: "https://helm.sh" +date: "2023-03-31 15:00:00" +--- + +In the past year, the team at [Ada Logics](https://adalogics.com) has worked on integrating continuous fuzzing into the [Helm core project](https://github.com/helm/helm). This was an effort focused on improving the security posture of Helm and ensuring a continued good experience for Helm users. The fuzzing integration involved enrolling Helm in the [OSS-Fuzz project](https://github.com/cncf/cncf-fuzzing) and writing a set of fuzzers that further enriches the test coverage of Helm. In total, 38 fuzzers were written, and nine bugs were found (with eight fixed so far), demonstrating the work’s value for Helm both short term and long term. All fuzzers were implemented by way of [Go-fuzz](https://github.com/dvyukov/go-fuzz) and are run daily by OSS-Fuzz against the latest Helm commit to make sure Helm is continuously fuzz tested. The full report of the engagement can be found [here](https://github.com/helm/community/tree/main/security-audit/FUZZING_AUDIT_2022.pdf). + +[Helm](https://helm.sh) is described as the Kubernetes package manager. It helps simplify finding, sharing, and using software built for Kubernetes. Helm began as what is now known as [Helm Classic](https://github.com/helm/helm-classic), a Deis project begun in 2015 and introduced at the inaugural KubeCon. In January of 2016, the project merged with a GCS tool called Kubernetes Deployment Manager, and the project was moved under Kubernetes. Helm was promoted from a Kubernetes subproject to a full-fledged CNCF project in June 2018. Helm [graduated as a CNCF project in April 2020](https://www.cncf.io/announcement/2020/04/30/cloud-native-computing-foundation-announces-helm-graduation/). [The CNCF annual survey of 2022](https://www.cncf.io/reports/cncf-annual-survey-2021) found that around 90% of companies are either using or evaluating Kubernetes, and Helm’s performance and security are important, for the continued business operations of these users. + +## What is fuzzing? + +[Fuzzing](https://en.wikipedia.org/wiki/Fuzzing) is a technique for testing software for bugs and vulnerabilities by passing it pseudo-random data. The key idea is to write a fuzzing harness similar to a unit — or integration — test that will execute the application under test with some arbitrary input. The fuzzing engine that will run the fuzzing harness uses mutational algorithms to generate new inputs - also called "testcases" - that will cause the code under test to execute uniquely, i.e., generate inputs that trigger new code execution paths. The goal is then to observe if the code under test misbehaves in the event of any of the generated inputs. Fuzzing has been effective in uncovering reliability bugs and vulnerabilities in software for more than two decades, and open source software is increasingly adopting the technique. + +## Helm fuzzing overview + +In this engagement, the goal was to write a set of fuzzers that would cover a lot of the Helm codebase and integrate the setup into the open source fuzzing service OSS-Fuzz. OSS-Fuzz is a free service offered by Google for critical open source projects to run their fuzzers continuously and report any crashes. Continuous analysis is important due to fuzzing relying on genetic algorithms, which effectively means the fuzzers will improve over time, and OSS-Fuzz will run the fuzzers daily indefinitely. In addition to this, continuous analysis is crucial for capturing any regressions. + +Helm is written in the Go programming language, making it safe from memory-corruptions. Fuzzing Go will find panics such as slice/index out of range, nil-pointer dereferences, invalid type assertions, timeouts, and out of memory. At the end of this engagement, nine issues were found, all but one of which were fixed. Refer to the report for a detailed breakdown of the issues. + +At the end of this engagement, the fuzzers provide significant coverage of the Helm project, including critical parts such as chart handling, release storage, and repositories. To write these fuzzers, Ada Logics used [go-fuzz-headers](https://github.com/AdaLogics/go-fuzz-headers) to deterministically create pseudo-random structs from the data provided by libFuzzer. + +## Closing thoughts + +The Helm team is thankful to CNCF for providing the opportunity to work with Ada Logics to develop new fuzzers for Helm. The CNCF takes security seriously, and it previously funded two third-party security audits for the Helm project, [source code for the Helm client along with the process Helm uses to handle security](https://helm.sh/blog/2019-11-04-helm-security-audit-results/) and [source code for the Helm client along with a threat model for the use of Helm](https://helm.sh/blog/helm-2nd-security-audit/). We want to thank the following Helm maintainers who participated in this endeavour and provided fixes where required: [Matt Butcher](https://github.com/technosophos), [Martin Hickey](https://github.com/hickeyma), [Matt Farina](https://github.com/mattfarina) and [Scott Rigby](https://github.com/scottrigby). We would also like to mention and thank the Flux maintainers, especially [Paulo Gomes](https://github.com/pjbgf) for collaborating on an issue. The fuzzing findings and fixes are valuable add-ons to the previous conclusions of the security audits. The Helm project has efficient test suites, and code changes are backed by tests, but the newly developed fuzzers and findings have provided significant value to the project. During the fuzzing, only nine issues were found, which revalidated the high quality of the Helm code. The Helm team can now maintain the newly developed fuzzers and build on them to continue code quality and security. \ No newline at end of file diff --git a/content/en/blog/images/happy-5th.png b/content/en/blog/images/happy-5th.png new file mode 100644 index 0000000000..8d99085b9e Binary files /dev/null and b/content/en/blog/images/happy-5th.png differ diff --git a/content/en/blog/images/helm-2to3.png b/content/en/blog/images/helm-2to3.png new file mode 100755 index 0000000000..a5372385cb Binary files /dev/null and b/content/en/blog/images/helm-2to3.png differ diff --git a/content/en/blog/images/helmgraduation-twitter.png b/content/en/blog/images/helmgraduation-twitter.png new file mode 100644 index 0000000000..c8be7e89bc Binary files /dev/null and b/content/en/blog/images/helmgraduation-twitter.png differ diff --git a/content/en/blog/images/helmgraduation.png b/content/en/blog/images/helmgraduation.png new file mode 100644 index 0000000000..019b6eecdd Binary files /dev/null and b/content/en/blog/images/helmgraduation.png differ diff --git a/content/en/blog/images/octocat.png b/content/en/blog/images/octocat.png new file mode 100644 index 0000000000..ac88aec901 Binary files /dev/null and b/content/en/blog/images/octocat.png differ diff --git a/content/en/code/chartmuseum.md b/content/en/code/chartmuseum.md new file mode 100755 index 0000000000..827723b175 --- /dev/null +++ b/content/en/code/chartmuseum.md @@ -0,0 +1,5 @@ +--- +name: "chartmuseum" +repoURL: "https://github.com/helm/chartmuseum" +branch: "main" +--- diff --git a/content/en/code/helm-v2.md b/content/en/code/helm-v2.md new file mode 100755 index 0000000000..4c825d4149 --- /dev/null +++ b/content/en/code/helm-v2.md @@ -0,0 +1,6 @@ +--- +url: "helm/v2" +name: "helm/v2" +repoURL: "https://github.com/helm/helm" +branch: "dev-v2" +--- diff --git a/content/en/code/helm-v3.md b/content/en/code/helm-v3.md new file mode 100755 index 0000000000..67185526df --- /dev/null +++ b/content/en/code/helm-v3.md @@ -0,0 +1,6 @@ +--- +url: "helm/v3" +name: "helm/v3" +repoURL: "https://github.com/helm/helm" +branch: "main" +--- diff --git a/content/en/code/helm.md b/content/en/code/helm.md new file mode 100755 index 0000000000..af5c8d5ce7 --- /dev/null +++ b/content/en/code/helm.md @@ -0,0 +1,5 @@ +--- +name: "helm" +repoURL: "https://github.com/helm/helm" +branch: "main" +--- diff --git a/content/en/docs/_index.md b/content/en/docs/_index.md new file mode 100644 index 0000000000..2bff1fe62a --- /dev/null +++ b/content/en/docs/_index.md @@ -0,0 +1,27 @@ +--- +title: "Docs Home" +description: "Everything you need to know about how the documentation is organized." +--- + +# Welcome + +Welcome to the [Helm](https://helm.sh/) documentation. Helm is the package +manager for Kubernetes, and you can read detailed background information in the +[CNCF Helm Project Journey +report](https://www.cncf.io/cncf-helm-project-journey/). + +# How the documentation is organized + +Helm has a lot of documentation. A high-level overview of how it’s organized +will help you know where to look for certain things: + +- [Tutorials](intro) take you by the hand through a series of steps to create + your first Helm chart. Start here if you’re new to Helm. +- [Topic guides](topics) discuss key topics and concepts at a fairly high level + and provide useful background information and explanation. +- [Community Guides](community) discuss topics centered around Helm’s community. + Start here if you want to learn more about the development process of Helm + itself and how you can contribute. +- [How-to guides](howto) are recipes. They guide you through the steps involved + in addressing key problems and use-cases. They are more advanced than + tutorials and assume some knowledge of how Helm works. diff --git a/content/en/docs/chart_best_practices/_index.md b/content/en/docs/chart_best_practices/_index.md new file mode 100644 index 0000000000..77e4db8c03 --- /dev/null +++ b/content/en/docs/chart_best_practices/_index.md @@ -0,0 +1,15 @@ +--- +title: "Best Practices" +sidebar: true +weight: 4 +aliases: ["/docs/topics/chart_best_practices/"] +--- + +# The Chart Best Practices Guide + +This guide covers the Helm Team's considered best practices for creating charts. +It focuses on how charts should be structured. + +We focus primarily on best practices for charts that may be publicly deployed. +We know that many charts are for internal-use only, and authors of such charts +may find that their internal interests override our suggestions here. diff --git a/content/en/docs/chart_best_practices/conventions.md b/content/en/docs/chart_best_practices/conventions.md new file mode 100644 index 0000000000..3537fe3d39 --- /dev/null +++ b/content/en/docs/chart_best_practices/conventions.md @@ -0,0 +1,50 @@ +--- +title: "General Conventions" +description: "General conventions for charts." +weight: 1 +aliases: ["/docs/topics/chart_best_practices/conventions/"] +--- + +This part of the Best Practices Guide explains general conventions. + +## Chart Names + +Chart names must be lower case letters and numbers. Words _may_ be separated +with dashes (-): + +Examples: + +``` +drupal +nginx-lego +aws-cluster-autoscaler +``` + +Neither uppercase letters nor underscores can be used in chart names. Dots +should not be used in chart names. + +## Version Numbers + +Wherever possible, Helm uses [SemVer 2](https://semver.org) to represent version +numbers. (Note that Docker image tags do not necessarily follow SemVer, and are +thus considered an unfortunate exception to the rule.) + +When SemVer versions are stored in Kubernetes labels, we conventionally alter +the `+` character to an `_` character, as labels do not allow the `+` sign as a +value. + +## Formatting YAML + +YAML files should be indented using _two spaces_ (and never tabs). + +## Usage of the Words Helm and Chart + +There are a few conventions for using the words _Helm_ and _helm_. + +- _Helm_ refers to the project as a whole +- `helm` refers to the client-side command +- The term `chart` does not need to be capitalized, as it is not a proper noun +- However, `Chart.yaml` does need to be capitalized because the file name is + case sensitive + +When in doubt, use _Helm_ (with an uppercase 'H'). diff --git a/content/en/docs/chart_best_practices/custom_resource_definitions.md b/content/en/docs/chart_best_practices/custom_resource_definitions.md new file mode 100644 index 0000000000..8386bafe43 --- /dev/null +++ b/content/en/docs/chart_best_practices/custom_resource_definitions.md @@ -0,0 +1,72 @@ +--- +title: "Custom Resource Definitions" +description: "How to handle creating and using CRDs." +weight: 7 +aliases: ["/docs/topics/chart_best_practices/custom_resource_definitions/"] +--- + +This section of the Best Practices Guide deals with creating and using Custom +Resource Definition objects. + +When working with Custom Resource Definitions (CRDs), it is important to +distinguish two different pieces: + +- There is a declaration of a CRD. This is the YAML file that has the kind + `CustomResourceDefinition` +- Then there are resources that _use_ the CRD. Say a CRD defines + `foo.example.com/v1`. Any resource that has `apiVersion: example.com/v1` and + kind `Foo` is a resource that uses the CRD. + +## Install a CRD Declaration Before Using the Resource + +Helm is optimized to load as many resources into Kubernetes as fast as possible. +By design, Kubernetes can take an entire set of manifests and bring them all +online (this is called the reconciliation loop). + +But there's a difference with CRDs. + +For a CRD, the declaration must be registered before any resources of that CRDs +kind(s) can be used. And the registration process sometimes takes a few seconds. + +### Method 1: Let `helm` Do It For You + +With the arrival of Helm 3, we removed the old `crd-install` hooks for a more +simple methodology. There is now a special directory called `crds` that you can +create in your chart to hold your CRDs. These CRDs are not templated, but will +be installed by default when running a `helm install` for the chart. If the CRD +already exists, it will be skipped with a warning. If you wish to skip the CRD +installation step, you can pass the `--skip-crds` flag. + +#### Some caveats (and explanations) + +There is no support at this time for upgrading or deleting CRDs using Helm. This +was an explicit decision after much community discussion due to the danger for +unintentional data loss. Furthermore, there is currently no community consensus +around how to handle CRDs and their lifecycle. As this evolves, Helm will add +support for those use cases. + +The `--dry-run` flag of `helm install` and `helm upgrade` is not currently +supported for CRDs. The purpose of "Dry Run" is to validate that the output of +the chart will actually work if sent to the server. But CRDs are a modification +of the server's behavior. Helm cannot install the CRD on a dry run, so the +discovery client will not know about that Custom Resource (CR), and validation +will fail. You can alternatively move the CRDs to their own chart or use `helm +template` instead. + +Another important point to consider in the discussion around CRD support is how +the rendering of templates is handled. One of the distinct disadvantages of the +`crd-install` method used in Helm 2 was the inability to properly validate +charts due to changing API availability (a CRD is actually adding another +available API to your Kubernetes cluster). If a chart installed a CRD, `helm` no +longer had a valid set of API versions to work against. This is also the reason +behind removing templating support from CRDs. With the new `crds` method of CRD +installation, we now ensure that `helm` has completely valid information about +the current state of the cluster. + +### Method 2: Separate Charts + +Another way to do this is to put the CRD definition in one chart, and then put +any resources that use that CRD in _another_ chart. + +In this method, each chart must be installed separately. However, this workflow +may be more useful for cluster operators who have admin access to a cluster diff --git a/content/en/docs/chart_best_practices/dependencies.md b/content/en/docs/chart_best_practices/dependencies.md new file mode 100644 index 0000000000..e2c495ac8a --- /dev/null +++ b/content/en/docs/chart_best_practices/dependencies.md @@ -0,0 +1,82 @@ +--- +title: "Dependencies" +description: "Covers best practices for Chart dependencies." +weight: 4 +aliases: ["/docs/topics/chart_best_practices/dependencies/"] +--- + +This section of the guide covers best practices for `dependencies` declared in +`Chart.yaml`. + +## Versions + +Where possible, use version ranges instead of pinning to an exact version. The +suggested default is to use a patch-level version match: + +```yaml +version: ~1.2.3 +``` + +This will match version `1.2.3` and any patches to that release. In other +words, `~1.2.3` is equivalent to `>= 1.2.3, < 1.3.0` + +For the complete version matching syntax, please see the [semver +documentation](https://github.com/Masterminds/semver#checking-version-constraints). + +### Prerelease versions + +The above versioning constraints will not match on pre-release versions. +For example `version: ~1.2.3` will match `version: ~1.2.4` but not `version: ~1.2.3-1`. +The following provides a pre-release as well as patch-level matching: + +```yaml +version: ~1.2.3-0 +``` + +### Repository URLs + +Where possible, use `https://` repository URLs, followed by `http://` URLs. + +If the repository has been added to the repository index file, the repository +name can be used as an alias of URL. Use `alias:` or `@` followed by repository +names. + +File URLs (`file://...`) are considered a "special case" for charts that are +assembled by a fixed deployment pipeline. + +When using [downloader plugins]({{< ref "../topics/plugins#downloader-plugins" >}}) +the URL scheme will be specific to the plugin. Note, a user of the chart will +need to have a plugin supporting the scheme installed to update or build the +dependency. + +Helm cannot perform dependency management operations on the dependency when the +`repository` field is left blank. In that case Helm will assume the dependency +is in a sub-directory of the `charts` folder with the name being the same as the +`name` property for the dependency. + +## Conditions and Tags + +Conditions or tags should be added to any dependencies that _are optional_. + +The preferred form of a condition is: + +```yaml +condition: somechart.enabled +``` + +Where `somechart` is the chart name of the dependency. + +When multiple subcharts (dependencies) together provide an optional or swappable +feature, those charts should share the same tags. + +For example, if both `nginx` and `memcached` together provide performance +optimizations for the main app in the chart, and are required to both be present +when that feature is enabled, then they should both have a tags section like +this: + +```yaml +tags: + - webaccelerator +``` + +This allows a user to turn that feature on and off with one tag. diff --git a/content/en/docs/chart_best_practices/labels.md b/content/en/docs/chart_best_practices/labels.md new file mode 100644 index 0000000000..2a413b9886 --- /dev/null +++ b/content/en/docs/chart_best_practices/labels.md @@ -0,0 +1,47 @@ +--- +title: "Labels and Annotations" +description: "Covers best practices for using labels and annotations in your Chart." +weight: 5 +aliases: ["/docs/topics/chart_best_practices/labels/"] +--- + +This part of the Best Practices Guide discusses the best practices for using +labels and annotations in your chart. + +## Is it a Label or an Annotation? + +An item of metadata should be a label under the following conditions: + +- It is used by Kubernetes to identify this resource +- It is useful to expose to operators for the purpose of querying the system. + +For example, we suggest using `helm.sh/chart: NAME-VERSION` as a label so that +operators can conveniently find all of the instances of a particular chart to +use. + +If an item of metadata is not used for querying, it should be set as an +annotation instead. + +Helm hooks are always annotations. + +## Standard Labels + +The following table defines common labels that Helm charts use. Helm itself +never requires that a particular label be present. Labels that are marked REC +are recommended, and _should_ be placed onto a chart for global consistency. +Those marked OPT are optional. These are idiomatic or commonly in use, but are +not relied upon frequently for operational purposes. + +Name|Status|Description +-----|------|---------- +`app.kubernetes.io/name` | REC | This should be the app name, reflecting the entire app. Usually `{{ template "name" . }}` is used for this. This is used by many Kubernetes manifests, and is not Helm-specific. +`helm.sh/chart` | REC | This should be the chart name and version: `{{ .Chart.Name }}-{{ .Chart.Version \| replace "+" "_" }}`. +`app.kubernetes.io/managed-by` | REC | This should always be set to `{{ .Release.Service }}`. It is for finding all things managed by Helm. +`app.kubernetes.io/instance` | REC | This should be the `{{ .Release.Name }}`. It aids in differentiating between different instances of the same application. +`app.kubernetes.io/version` | OPT | The version of the app and can be set to `{{ .Chart.AppVersion }}`. +`app.kubernetes.io/component` | OPT | This is a common label for marking the different roles that pieces may play in an application. For example, `app.kubernetes.io/component: frontend`. +`app.kubernetes.io/part-of` | OPT | When multiple charts or pieces of software are used together to make one application. For example, application software and a database to produce a website. This can be set to the top level application being supported. + +You can find more information on the Kubernetes labels, prefixed with +`app.kubernetes.io`, in the [Kubernetes +documentation](https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/). diff --git a/content/en/docs/chart_best_practices/pods.md b/content/en/docs/chart_best_practices/pods.md new file mode 100644 index 0000000000..4a1e902be6 --- /dev/null +++ b/content/en/docs/chart_best_practices/pods.md @@ -0,0 +1,79 @@ +--- +title: "Pods and PodTemplates" +description: "Discusses formatting the Pod and PodTemplate portions in Chart manifests." +weight: 6 +aliases: ["/docs/topics/chart_best_practices/pods/"] +--- + +This part of the Best Practices Guide discusses formatting the Pod and +PodTemplate portions in chart manifests. + +The following (non-exhaustive) list of resources use PodTemplates: + +- Deployment +- ReplicationController +- ReplicaSet +- DaemonSet +- StatefulSet + +## Images + +A container image should use a fixed tag or the SHA of the image. It should not +use the tags `latest`, `head`, `canary`, or other tags that are designed to be +"floating". + + +Images _may_ be defined in the `values.yaml` file to make it easy to swap out +images. + +```yaml +image: {{ .Values.redisImage | quote }} +``` + +An image and a tag _may_ be defined in `values.yaml` as two separate fields: + +```yaml +image: "{{ .Values.redisImage }}:{{ .Values.redisTag }}" +``` + +## ImagePullPolicy + +`helm create` sets the `imagePullPolicy` to `IfNotPresent` by default by doing +the following in your `deployment.yaml`: + +```yaml +imagePullPolicy: {{ .Values.image.pullPolicy }} +``` + +And `values.yaml`: + +```yaml +image: + pullPolicy: IfNotPresent +``` + +Similarly, Kubernetes defaults the `imagePullPolicy` to `IfNotPresent` if it is +not defined at all. If you want a value other than `IfNotPresent`, simply update +the value in `values.yaml` to your desired value. + + +## PodTemplates Should Declare Selectors + +All PodTemplate sections should specify a selector. For example: + +```yaml +selector: + matchLabels: + app.kubernetes.io/name: MyName +template: + metadata: + labels: + app.kubernetes.io/name: MyName +``` + +This is a good practice because it makes the relationship between the set and +the pod. + +But this is even more important for sets like Deployment. Without this, the +_entire_ set of labels is used to select matching pods, and this will break if +you use labels that change, like version or release date. diff --git a/content/en/docs/chart_best_practices/rbac.md b/content/en/docs/chart_best_practices/rbac.md new file mode 100644 index 0000000000..95baa61df8 --- /dev/null +++ b/content/en/docs/chart_best_practices/rbac.md @@ -0,0 +1,83 @@ +--- +title: "Role-Based Access Control" +description: "Discusses the creation and formatting of RBAC resources in Chart manifests." +weight: 8 +aliases: ["/docs/topics/chart_best_practices/rbac/"] +--- + +This part of the Best Practices Guide discusses the creation and formatting of +RBAC resources in chart manifests. + +RBAC resources are: + +- ServiceAccount (namespaced) +- Role (namespaced) +- ClusterRole +- RoleBinding (namespaced) +- ClusterRoleBinding + +## YAML Configuration + +RBAC and ServiceAccount configuration should happen under separate keys. They +are separate things. Splitting these two concepts out in the YAML disambiguates +them and makes this clearer. + +```yaml +rbac: + # Specifies whether RBAC resources should be created + create: true + +serviceAccount: + # Specifies whether a ServiceAccount should be created + create: true + # The name of the ServiceAccount to use. + # If not set and create is true, a name is generated using the fullname template + name: +``` + +This structure can be extended for more complex charts that require multiple +ServiceAccounts. + +```yaml +someComponent: + serviceAccount: + create: true + name: +anotherComponent: + serviceAccount: + create: true + name: +``` + +## RBAC Resources Should be Created by Default + +`rbac.create` should be a boolean value controlling whether RBAC resources are +created. The default should be `true`. Users who wish to manage RBAC access +controls themselves can set this value to `false` (in which case see below). + +## Using RBAC Resources + +`serviceAccount.name` should be set to the name of the ServiceAccount to be used +by access-controlled resources created by the chart. If `serviceAccount.create` +is true, then a ServiceAccount with this name should be created. If the name is +not set, then a name is generated using the `fullname` template, If +`serviceAccount.create` is false, then it should not be created, but it should +still be associated with the same resources so that manually-created RBAC +resources created later that reference it will function correctly. If +`serviceAccount.create` is false and the name is not specified, then the default +ServiceAccount is used. + +The following helper template should be used for the ServiceAccount. + +```yaml +{{/* +Create the name of the service account to use +*/}} +{{- define "mychart.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "mychart.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} +``` diff --git a/content/en/docs/chart_best_practices/templates.md b/content/en/docs/chart_best_practices/templates.md new file mode 100644 index 0000000000..bdbdc5fd56 --- /dev/null +++ b/content/en/docs/chart_best_practices/templates.md @@ -0,0 +1,210 @@ +--- +title: "Templates" +description: "A closer look at best practices surrounding templates." +weight: 3 +aliases: ["/docs/topics/chart_best_practices/templates/"] +--- + +This part of the Best Practices Guide focuses on templates. + +## Structure of `templates/` + +The `templates/` directory should be structured as follows: + +- Template files should have the extension `.yaml` if they produce YAML output. + The extension `.tpl` may be used for template files that produce no formatted + content. +- Template file names should use dashed notation (`my-example-configmap.yaml`), + not camelcase. +- Each resource definition should be in its own template file. +- Template file names should reflect the resource kind in the name. e.g. + `foo-pod.yaml`, `bar-svc.yaml` + +## Names of Defined Templates + +Defined templates (templates created inside a `{{ define }} ` directive) are +globally accessible. That means that a chart and all of its subcharts will have +access to all of the templates created with `{{ define }}`. + +For that reason, _all defined template names should be namespaced._ + +Correct: + +```yaml +{{- define "nginx.fullname" }} +{{/* ... */}} +{{ end -}} +``` + +Incorrect: + +```yaml +{{- define "fullname" -}} +{{/* ... */}} +{{ end -}} +``` +It is highly recommended that new charts are created via `helm create` command +as the template names are automatically defined as per this best practice. + +## Formatting Templates + +Templates should be indented using _two spaces_ (never tabs). + +Template directives should have whitespace after the opening braces and before +the closing braces: + +Correct: +``` +{{ .foo }} +{{ print "foo" }} +{{- print "bar" -}} +``` + +Incorrect: +``` +{{.foo}} +{{print "foo"}} +{{-print "bar"-}} +``` + +Templates should chomp whitespace where possible: + +```yaml +foo: + {{- range .Values.items }} + {{ . }} + {{ end -}} +``` + +Blocks (such as control structures) may be indented to indicate flow of the +template code. + +``` +{{ if $foo -}} + {{- with .Bar }}Hello{{ end -}} +{{- end -}} +``` + +However, since YAML is a whitespace-oriented language, it is often not possible +for code indentation to follow that convention. + +## Whitespace in Generated Templates + +It is preferable to keep the amount of whitespace in generated templates to a +minimum. In particular, numerous blank lines should not appear adjacent to each +other. But occasional empty lines (particularly between logical sections) is +fine. + +This is best: + +```yaml +apiVersion: batch/v1 +kind: Job +metadata: + name: example + labels: + first: first + second: second +``` + +This is okay: + +```yaml +apiVersion: batch/v1 +kind: Job + +metadata: + name: example + + labels: + first: first + second: second + +``` + +But this should be avoided: + +```yaml +apiVersion: batch/v1 +kind: Job + +metadata: + name: example + + + + + + labels: + first: first + + second: second + +``` + +## Comments (YAML Comments vs. Template Comments) + +Both YAML and Helm Templates have comment markers. + +YAML comments: +```yaml +# This is a comment +type: sprocket +``` + +Template Comments: +```yaml +{{- /* +This is a comment. +*/}} +type: frobnitz +``` + +Template comments should be used when documenting features of a template, such +as explaining a defined template: + +```yaml +{{- /* +mychart.shortname provides a 6 char truncated version of the release name. +*/}} +{{ define "mychart.shortname" -}} +{{ .Release.Name | trunc 6 }} +{{- end -}} + +``` + +Inside of templates, YAML comments may be used when it is useful for Helm users +to (possibly) see the comments during debugging. + +```yaml +# This may cause problems if the value is more than 100Gi +memory: {{ .Values.maxMem | quote }} +``` + +The comment above is visible when the user runs `helm install --debug`, while +comments specified in `{{- /* */}}` sections are not. + +## Use of JSON in Templates and Template Output + +YAML is a superset of JSON. In some cases, using a JSON syntax can be more +readable than other YAML representations. + +For example, this YAML is closer to the normal YAML method of expressing lists: + +```yaml +arguments: + - "--dirname" + - "/foo" +``` + +But it is easier to read when collapsed into a JSON list style: + +```yaml +arguments: ["--dirname", "/foo"] +``` + +Using JSON for increased legibility is good. However, JSON syntax should not be +used for representing more complex constructs. + +When dealing with pure JSON embedded inside of YAML (such as init container +configuration), it is of course appropriate to use the JSON format. diff --git a/content/en/docs/chart_best_practices/values.md b/content/en/docs/chart_best_practices/values.md new file mode 100644 index 0000000000..ec1d2b6970 --- /dev/null +++ b/content/en/docs/chart_best_practices/values.md @@ -0,0 +1,164 @@ +--- +title: "Values" +description: "Focuses on how you should structure and use your values." +weight: 2 +aliases: ["/docs/topics/chart_best_practices/values/"] +--- + +This part of the best practices guide covers using values. In this part of the +guide, we provide recommendations on how you should structure and use your +values, with focus on designing a chart's `values.yaml` file. + +## Naming Conventions + +Variable names should begin with a lowercase letter, and words should be +separated with camelcase: + +Correct: + +```yaml +chicken: true +chickenNoodleSoup: true +``` + +Incorrect: + +```yaml +Chicken: true # initial caps may conflict with built-ins +chicken-noodle-soup: true # do not use hyphens in the name +``` + +Note that all of Helm's built-in variables begin with an uppercase letter to +easily distinguish them from user-defined values: `.Release.Name`, +`.Capabilities.KubeVersion`. + +## Flat or Nested Values + +YAML is a flexible format, and values may be nested deeply or flattened. + +Nested: + +```yaml +server: + name: nginx + port: 80 +``` + +Flat: + +```yaml +serverName: nginx +serverPort: 80 +``` + +In most cases, flat should be favored over nested. The reason for this is that +it is simpler for template developers and users. + + +For optimal safety, a nested value must be checked at every level: + +``` +{{ if .Values.server }} + {{ default "none" .Values.server.name }} +{{ end }} +``` + +For every layer of nesting, an existence check must be done. But for flat +configuration, such checks can be skipped, making the template easier to read +and use. + +``` +{{ default "none" .Values.serverName }} +``` + +When there are a large number of related variables, and at least one of them is +non-optional, nested values may be used to improve readability. + +## Make Types Clear + +YAML's type coercion rules are sometimes counterintuitive. For example, `foo: +false` is not the same as `foo: "false"`. Large integers like `foo: 12345678` +will get converted to scientific notation in some cases. + +The easiest way to avoid type conversion errors is to be explicit about strings, +and implicit about everything else. Or, in short, _quote all strings_. + +Often, to avoid the integer casting issues, it is advantageous to store your +integers as strings as well, and use `{{ int $value }}` in the template to +convert from a string back to an integer. + +In most cases, explicit type tags are respected, so `foo: !!string 1234` should +treat `1234` as a string. _However_, the YAML parser consumes tags, so the type +data is lost after one parse. + +## Consider How Users Will Use Your Values + +There are three potential sources of values: + +- A chart's `values.yaml` file +- A values file supplied by `helm install -f` or `helm upgrade -f` +- The values passed to a `--set` or `--set-string` flag on `helm install` or + `helm upgrade` + +When designing the structure of your values, keep in mind that users of your +chart may want to override them via either the `-f` flag or with the `--set` +option. + +Since `--set` is more limited in expressiveness, the first guidelines for +writing your `values.yaml` file is _make it easy to override from `--set`_. + +For this reason, it's often better to structure your values file using maps. + +Difficult to use with `--set`: + +```yaml +servers: + - name: foo + port: 80 + - name: bar + port: 81 +``` + +The above cannot be expressed with `--set` in Helm `<=2.4`. In Helm 2.5, +accessing the port on foo is `--set servers[0].port=80`. Not only is it harder +for the user to figure out, but it is prone to errors if at some later time the +order of the `servers` is changed. + +Easy to use: + +```yaml +servers: + foo: + port: 80 + bar: + port: 81 +``` + +Accessing foo's port is much more obvious: `--set servers.foo.port=80`. + +## Document `values.yaml` + +Every defined property in `values.yaml` should be documented. The documentation +string should begin with the name of the property that it describes, and then +give at least a one-sentence description. + +Incorrect: + +```yaml +# the host name for the webserver +serverHost: example +serverPort: 9191 +``` + +Correct: + +```yaml +# serverHost is the host name for the webserver +serverHost: example +# serverPort is the HTTP listener port for the webserver +serverPort: 9191 +``` + +Beginning each comment with the name of the parameter it documents makes it easy +to grep out documentation, and will enable documentation tools to reliably +correlate doc strings with the parameters they describe. diff --git a/content/en/docs/chart_template_guide/_index.md b/content/en/docs/chart_template_guide/_index.md new file mode 100644 index 0000000000..fd8ad7be9b --- /dev/null +++ b/content/en/docs/chart_template_guide/_index.md @@ -0,0 +1,25 @@ +--- +title: "Chart Template Guide" +weight: 5 +aliases: ["/topics/chart_template_guide/"] +--- + +# The Chart Template Developer's Guide + +This guide provides an introduction to Helm's chart templates, with emphasis on +the template language. + +Templates generate manifest files, which are YAML-formatted resource +descriptions that Kubernetes can understand. We'll look at how templates are +structured, how they can be used, how to write Go templates, and how to debug +your work. + +This guide focuses on the following concepts: + +- The Helm template language +- Using values +- Techniques for working with templates + +This guide is oriented toward learning the ins and outs of the Helm template +language. Other guides provide introductory material, examples, and best +practices. diff --git a/content/en/docs/chart_template_guide/accessing_files.md b/content/en/docs/chart_template_guide/accessing_files.md new file mode 100644 index 0000000000..9620960e0c --- /dev/null +++ b/content/en/docs/chart_template_guide/accessing_files.md @@ -0,0 +1,246 @@ +--- +title: "Accessing Files Inside Templates" +description: "How to access files from within a template." +weight: 10 +--- + +In the previous section we looked at several ways to create and access named +templates. This makes it easy to import one template from within another +template. But sometimes it is desirable to import a _file that is not a +template_ and inject its contents without sending the contents through the +template renderer. + +Helm provides access to files through the `.Files` object. Before we get going +with the template examples, though, there are a few things to note about how +this works: + +- It is okay to add extra files to your Helm chart. These files will be bundled. + Be careful, though. Charts must be smaller than 1M because of the storage + limitations of Kubernetes objects. +- Some files cannot be accessed through the `.Files` object, usually for + security reasons. + - Files in `templates/` cannot be accessed. + - Files excluded using `.helmignore` cannot be accessed. + - Files outside of a helm application [subchart]({{< ref +"/docs/chart_template_guide/subcharts_and_globals.md" >}}), including those of the parent, cannot be accessed +- Charts do not preserve UNIX mode information, so file-level permissions will + have no impact on the availability of a file when it comes to the `.Files` + object. + + + + + +- [Basic example](#basic-example) +- [Path helpers](#path-helpers) +- [Glob patterns](#glob-patterns) +- [ConfigMap and Secrets utility + functions](#configmap-and-secrets-utility-functions) +- [Encoding](#encoding) +- [Lines](#lines) + + + +## Basic example + +With those caveats behind, let's write a template that reads three files into +our ConfigMap. To get started, we will add three files to the chart, putting all +three directly inside of the `mychart/` directory. + +`config1.toml`: + +```toml +message = Hello from config 1 +``` + +`config2.toml`: + +```toml +message = This is config 2 +``` + +`config3.toml`: + +```toml +message = Goodbye from config 3 +``` + +Each of these is a simple TOML file (think old-school Windows INI files). We +know the names of these files, so we can use a `range` function to loop through +them and inject their contents into our ConfigMap. + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + {{- $files := .Files }} + {{- range tuple "config1.toml" "config2.toml" "config3.toml" }} + {{ . }}: |- + {{ $files.Get . }} + {{- end }} +``` + +This config map uses several of the techniques discussed in previous sections. +For example, we create a `$files` variable to hold a reference to the `.Files` +object. We also use the `tuple` function to create a list of files that we loop +through. Then we print each file name (`{{ . }}: |-`) followed by the contents +of the file `{{ $files.Get . }}`. + +Running this template will produce a single ConfigMap with the contents of all +three files: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: quieting-giraf-configmap +data: + config1.toml: |- + message = Hello from config 1 + + config2.toml: |- + message = This is config 2 + + config3.toml: |- + message = Goodbye from config 3 +``` + +## Path helpers + +When working with files, it can be very useful to perform some standard +operations on the file paths themselves. To help with this, Helm imports many of +the functions from Go's [path](https://golang.org/pkg/path/) package for your +use. They are all accessible with the same names as in the Go package, but with +a lowercase first letter. For example, `Base` becomes `base`, etc. + +The imported functions are: +- Base +- Dir +- Ext +- IsAbs +- Clean + +## Glob patterns + +As your chart grows, you may find you have a greater need to organize your files +more, and so we provide a `Files.Glob(pattern string)` method to assist in +extracting certain files with all the flexibility of [glob +patterns](https://godoc.org/github.com/gobwas/glob). + +`.Glob` returns a `Files` type, so you may call any of the `Files` methods on +the returned object. + +For example, imagine the directory structure: + +``` +foo/: + foo.txt foo.yaml + +bar/: + bar.go bar.conf baz.yaml +``` + +You have multiple options with Globs: + + +```yaml +{{ $currentScope := .}} +{{ range $path, $_ := .Files.Glob "**.yaml" }} + {{- with $currentScope}} + {{ .Files.Get $path }} + {{- end }} +{{ end }} +``` + +Or + +```yaml +{{ range $path, $_ := .Files.Glob "**.yaml" }} + {{ $.Files.Get $path }} +{{ end }} +``` + +## ConfigMap and Secrets utility functions + +(Available Helm 2.0.2 and after) + +It is very common to want to place file content into both ConfigMaps and +Secrets, for mounting into your pods at run time. To help with this, we provide +a couple utility methods on the `Files` type. + +For further organization, it is especially useful to use these methods in +conjunction with the `Glob` method. + +Given the directory structure from the [Glob](#glob-patterns) example above: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: conf +data: +{{ (.Files.Glob "foo/*").AsConfig | indent 2 }} +--- +apiVersion: v1 +kind: Secret +metadata: + name: very-secret +type: Opaque +data: +{{ (.Files.Glob "bar/*").AsSecrets | indent 2 }} +``` + +## Encoding + +You can import a file and have the template base-64 encode it to ensure +successful transmission: + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Release.Name }}-secret +type: Opaque +data: + token: |- + {{ .Files.Get "config1.toml" | b64enc }} +``` + +The above will take the same `config1.toml` file we used before and encode it: + +```yaml +# Source: mychart/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + name: lucky-turkey-secret +type: Opaque +data: + token: |- + bWVzc2FnZSA9IEhlbGxvIGZyb20gY29uZmlnIDEK +``` + +## Lines + +Sometimes it is desirable to access each line of a file in your template. We +provide a convenient `Lines` method for this. + +You can loop through `Lines` using a `range` function: + +```yaml +data: + some-file.txt: {{ range .Files.Lines "foo/bar.txt" }} + {{ . }}{{ end }} +``` + +There is no way to pass files external to the chart during `helm install`. So if +you are asking users to supply data, it must be loaded using `helm install -f` +or `helm install --set`. + +This discussion wraps up our dive into the tools and techniques for writing Helm +templates. In the next section we will see how you can use one special file, +`templates/NOTES.txt`, to send post-installation instructions to the users of +your chart. diff --git a/content/en/docs/chart_template_guide/builtin_objects.md b/content/en/docs/chart_template_guide/builtin_objects.md new file mode 100644 index 0000000000..6d46db29bf --- /dev/null +++ b/content/en/docs/chart_template_guide/builtin_objects.md @@ -0,0 +1,83 @@ +--- +title: "Built-in Objects" +description: "Built-in objects available to templates." +weight: 3 +--- + +Objects are passed into a template from the template engine. And your code can +pass objects around (we'll see examples when we look at the `with` and `range` +statements). There are even a few ways to create new objects within your +templates, like with the `tuple` function we'll see later. + +Objects can be simple, and have just one value. Or they can contain other +objects or functions. For example. the `Release` object contains several objects +(like `Release.Name`) and the `Files` object has a few functions. + +In the previous section, we use `{{ .Release.Name }}` to insert the name of a +release into a template. `Release` is one of the top-level objects that you can +access in your templates. + +- `Release`: This object describes the release itself. It has several objects + inside of it: + - `Release.Name`: The release name + - `Release.Namespace`: The namespace to be released into (if the manifest + doesn’t override) + - `Release.IsUpgrade`: This is set to `true` if the current operation is an + upgrade or rollback. + - `Release.IsInstall`: This is set to `true` if the current operation is an + install. + - `Release.Revision`: The revision number for this release. On install, this + is 1, and it is incremented with each upgrade and rollback. + - `Release.Service`: The service that is rendering the present template. On + Helm, this is always `Helm`. +- `Values`: Values passed into the template from the `values.yaml` file and from + user-supplied files. By default, `Values` is empty. +- `Chart`: The contents of the `Chart.yaml` file. Any data in `Chart.yaml` will + be accessible here. For example `{{ .Chart.Name }}-{{ .Chart.Version }}` will + print out the `mychart-0.1.0`. + - The available fields are listed in the [Charts Guide]({{< ref + "/docs/topics/charts.md#the-chartyaml-file" >}}) +- `Files`: This provides access to all non-special files in a chart. While you + cannot use it to access templates, you can use it to access other files in the + chart. See the section [Accessing Files]({{< ref + "/docs/chart_template_guide/accessing_files.md" >}}) for more. + - `Files.Get` is a function for getting a file by name (`.Files.Get + config.ini`) + - `Files.GetBytes` is a function for getting the contents of a file as an + array of bytes instead of as a string. This is useful for things like + images. + - `Files.Glob` is a function that returns a list of files whose names match + the given shell glob pattern. + - `Files.Lines` is a function that reads a file line-by-line. This is useful + for iterating over each line in a file. + - `Files.AsSecrets` is a function that returns the file bodies as Base 64 + encoded strings. + - `Files.AsConfig` is a function that returns file bodies as a YAML map. +- `Capabilities`: This provides information about what capabilities the + Kubernetes cluster supports. + - `Capabilities.APIVersions` is a set of versions. + - `Capabilities.APIVersions.Has $version` indicates whether a version (e.g., + `batch/v1`) or resource (e.g., `apps/v1/Deployment`) is available on the + cluster. + - `Capabilities.KubeVersion` and `Capabilities.KubeVersion.Version` is the + Kubernetes version. + - `Capabilities.KubeVersion.Major` is the Kubernetes major version. + - `Capabilities.KubeVersion.Minor` is the Kubernetes minor version. + - `Capabilities.HelmVersion` is the object containing the Helm Version details, it is the same output of `helm version` + - `Capabilities.HelmVersion.Version` is the current Helm version in semver format. + - `Capabilities.HelmVersion.GitCommit` is the Helm git sha1. + - `Capabilities.HelmVersion.GitTreeState` is the state of the Helm git tree. + - `Capabilities.HelmVersion.GoVersion` is the version of the Go compiler used. +- `Template`: Contains information about the current template that is being + executed + - `Template.Name`: A namespaced file path to the current template (e.g. + `mychart/templates/mytemplate.yaml`) + - `Template.BasePath`: The namespaced path to the templates directory of the current + chart (e.g. `mychart/templates`). + +The built-in values always begin with a capital letter. This is in keeping with +Go's naming convention. When you create your own names, you are free to use a +convention that suits your team. Some teams, like many whose charts you may see +on [Artifact Hub](https://artifacthub.io/packages/search?kind=0), choose to use +only initial lower case letters in order to distinguish local names from those +built-in. In this guide, we follow that convention. diff --git a/content/en/docs/chart_template_guide/control_structures.md b/content/en/docs/chart_template_guide/control_structures.md new file mode 100644 index 0000000000..c4f7dc4af0 --- /dev/null +++ b/content/en/docs/chart_template_guide/control_structures.md @@ -0,0 +1,460 @@ +--- +title: "Flow Control" +description: "A quick overview on the flow structure within templates." +weight: 7 +--- + +Control structures (called "actions" in template parlance) provide you, the +template author, with the ability to control the flow of a template's +generation. Helm's template language provides the following control structures: + +- `if`/`else` for creating conditional blocks +- `with` to specify a scope +- `range`, which provides a "for each"-style loop + +In addition to these, it provides a few actions for declaring and using named +template segments: + +- `define` declares a new named template inside of your template +- `template` imports a named template +- `block` declares a special kind of fillable template area + +In this section, we'll talk about `if`, `with`, and `range`. The others are +covered in the "Named Templates" section later in this guide. + +## If/Else + +The first control structure we'll look at is for conditionally including blocks +of text in a template. This is the `if`/`else` block. + +The basic structure for a conditional looks like this: + +``` +{{ if PIPELINE }} + # Do something +{{ else if OTHER PIPELINE }} + # Do something else +{{ else }} + # Default case +{{ end }} +``` + +Notice that we're now talking about _pipelines_ instead of values. The reason +for this is to make it clear that control structures can execute an entire +pipeline, not just evaluate a value. + +A pipeline is evaluated as _false_ if the value is: + +- a boolean false +- a numeric zero +- an empty string +- a `nil` (empty or null) +- an empty collection (`map`, `slice`, `tuple`, `dict`, `array`) + +Under all other conditions, the condition is true. + +Let's add a simple conditional to our ConfigMap. We'll add another setting if +the drink is set to coffee: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + drink: {{ .Values.favorite.drink | default "tea" | quote }} + food: {{ .Values.favorite.food | upper | quote }} + {{ if eq .Values.favorite.drink "coffee" }}mug: "true"{{ end }} +``` + +Since we commented out `drink: coffee` in our last example, the output should +not include a `mug: "true"` flag. But if we add that line back into our +`values.yaml` file, the output should look like this: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: eyewitness-elk-configmap +data: + myvalue: "Hello World" + drink: "coffee" + food: "PIZZA" + mug: "true" +``` + +## Controlling Whitespace + +While we're looking at conditionals, we should take a quick look at the way +whitespace is controlled in templates. Let's take the previous example and +format it to be a little easier to read: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + drink: {{ .Values.favorite.drink | default "tea" | quote }} + food: {{ .Values.favorite.food | upper | quote }} + {{ if eq .Values.favorite.drink "coffee" }} + mug: "true" + {{ end }} +``` + +Initially, this looks good. But if we run it through the template engine, we'll +get an unfortunate result: + +```console +$ helm install --dry-run --debug ./mychart +SERVER: "localhost:44134" +CHART PATH: /Users/mattbutcher/Code/Go/src/helm.sh/helm/_scratch/mychart +Error: YAML parse error on mychart/templates/configmap.yaml: error converting YAML to JSON: yaml: line 9: did not find expected key +``` + +What happened? We generated incorrect YAML because of the whitespacing above. + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: eyewitness-elk-configmap +data: + myvalue: "Hello World" + drink: "coffee" + food: "PIZZA" + mug: "true" +``` + +`mug` is incorrectly indented. Let's simply out-dent that one line, and re-run: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + drink: {{ .Values.favorite.drink | default "tea" | quote }} + food: {{ .Values.favorite.food | upper | quote }} + {{ if eq .Values.favorite.drink "coffee" }} + mug: "true" + {{ end }} +``` + +When we sent that, we'll get YAML that is valid, but still looks a little funny: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: telling-chimp-configmap +data: + myvalue: "Hello World" + drink: "coffee" + food: "PIZZA" + + mug: "true" + +``` + +Notice that we received a few empty lines in our YAML. Why? When the template +engine runs, it _removes_ the contents inside of `{{` end `}}`, but it leaves +the remaining whitespace exactly as is. + +YAML ascribes meaning to whitespace, so managing the whitespace becomes pretty +important. Fortunately, Helm templates have a few tools to help. + +First, the curly brace syntax of template declarations can be modified with +special characters to tell the template engine to chomp whitespace. `{{- ` (with +the dash and space added) indicates that whitespace should be chomped left, +while ` -}}` means whitespace to the right should be consumed. _Be careful! +Newlines are whitespace!_ + +> Make sure there is a space between the `-` and the rest of your directive. +> `{{- 3 }}` means "trim left whitespace and print 3" while `{{-3 }}` means +> "print -3". + +Using this syntax, we can modify our template to get rid of those new lines: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + drink: {{ .Values.favorite.drink | default "tea" | quote }} + food: {{ .Values.favorite.food | upper | quote }} + {{- if eq .Values.favorite.drink "coffee" }} + mug: "true" + {{- end }} +``` + +Just for the sake of making this point clear, let's adjust the above, and +substitute an `*` for each whitespace that will be deleted following this rule. +An `*` at the end of the line indicates a newline character that would be +removed + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + drink: {{ .Values.favorite.drink | default "tea" | quote }} + food: {{ .Values.favorite.food | upper | quote }}* +**{{- if eq .Values.favorite.drink "coffee" }} + mug: "true"* +**{{- end }} + +``` + +Keeping that in mind, we can run our template through Helm and see the result: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: clunky-cat-configmap +data: + myvalue: "Hello World" + drink: "coffee" + food: "PIZZA" + mug: "true" +``` + +Be careful with the chomping modifiers. It is easy to accidentally do things +like this: + +```yaml + food: {{ .Values.favorite.food | upper | quote }} + {{- if eq .Values.favorite.drink "coffee" -}} + mug: "true" + {{- end -}} + +``` + +That will produce `food: "PIZZA"mug: "true"` because it consumed newlines on both +sides. + +> For the details on whitespace control in templates, see the [Official Go +> template documentation](https://godoc.org/text/template) + +Finally, sometimes it's easier to tell the template system how to indent for you +instead of trying to master the spacing of template directives. For that reason, +you may sometimes find it useful to use the `indent` function (`{{ indent 2 +"mug:true" }}`). + +## Modifying scope using `with` + +The next control structure to look at is the `with` action. This controls +variable scoping. Recall that `.` is a reference to _the current scope_. So +`.Values` tells the template to find the `Values` object in the current scope. + +The syntax for `with` is similar to a simple `if` statement: + +``` +{{ with PIPELINE }} + # restricted scope +{{ end }} +``` + +Scopes can be changed. `with` can allow you to set the current scope (`.`) to a +particular object. For example, we've been working with `.Values.favorite`. +Let's rewrite our ConfigMap to alter the `.` scope to point to +`.Values.favorite`: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + {{- with .Values.favorite }} + drink: {{ .drink | default "tea" | quote }} + food: {{ .food | upper | quote }} + {{- end }} +``` + +Note that we removed the `if` conditional from the previous exercise +because it is now unnecessary - the block after `with` only executes +if the value of `PIPELINE` is not empty. + +Notice that now we can reference `.drink` and `.food` without qualifying them. +That is because the `with` statement sets `.` to point to `.Values.favorite`. +The `.` is reset to its previous scope after `{{ end }}`. + +But here's a note of caution! Inside of the restricted scope, you will not be +able to access the other objects from the parent scope using `.`. This, for +example, will fail: + +```yaml + {{- with .Values.favorite }} + drink: {{ .drink | default "tea" | quote }} + food: {{ .food | upper | quote }} + release: {{ .Release.Name }} + {{- end }} +``` + +It will produce an error because `Release.Name` is not inside of the restricted +scope for `.`. However, if we swap the last two lines, all will work as expected +because the scope is reset after `{{ end }}`. + +```yaml + {{- with .Values.favorite }} + drink: {{ .drink | default "tea" | quote }} + food: {{ .food | upper | quote }} + {{- end }} + release: {{ .Release.Name }} +``` + +Or, we can use `$` for accessing the object `Release.Name` from the parent +scope. `$` is mapped to the root scope when template execution begins and it +does not change during template execution. The following would work as well: + +```yaml + {{- with .Values.favorite }} + drink: {{ .drink | default "tea" | quote }} + food: {{ .food | upper | quote }} + release: {{ $.Release.Name }} + {{- end }} +``` + +After looking at `range`, we will take a look at template variables, which offer +one solution to the scoping issue above. + +## Looping with the `range` action + +Many programming languages have support for looping using `for` loops, `foreach` +loops, or similar functional mechanisms. In Helm's template language, the way to +iterate through a collection is to use the `range` operator. + +To start, let's add a list of pizza toppings to our `values.yaml` file: + +```yaml +favorite: + drink: coffee + food: pizza +pizzaToppings: + - mushrooms + - cheese + - peppers + - onions +``` + +Now we have a list (called a `slice` in templates) of `pizzaToppings`. We can +modify our template to print this list into our ConfigMap: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + {{- with .Values.favorite }} + drink: {{ .drink | default "tea" | quote }} + food: {{ .food | upper | quote }} + {{- end }} + toppings: |- + {{- range .Values.pizzaToppings }} + - {{ . | title | quote }} + {{- end }} + +``` + +We can use `$` for accessing the list `Values.pizzaToppings` from the parent +scope. `$` is mapped to the root scope when template execution begins and it +does not change during template execution. The following would work as well: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + {{- with .Values.favorite }} + drink: {{ .drink | default "tea" | quote }} + food: {{ .food | upper | quote }} + toppings: |- + {{- range $.Values.pizzaToppings }} + - {{ . | title | quote }} + {{- end }} + {{- end }} +``` + +Let's take a closer look at the `toppings:` list. The `range` function will +"range over" (iterate through) the `pizzaToppings` list. But now something +interesting happens. Just like `with` sets the scope of `.`, so does a `range` +operator. Each time through the loop, `.` is set to the current pizza topping. +That is, the first time, `.` is set to `mushrooms`. The second iteration it is +set to `cheese`, and so on. + +We can send the value of `.` directly down a pipeline, so when we do `{{ . | +title | quote }}`, it sends `.` to `title` (title case function) and then to +`quote`. If we run this template, the output will be: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: edgy-dragonfly-configmap +data: + myvalue: "Hello World" + drink: "coffee" + food: "PIZZA" + toppings: |- + - "Mushrooms" + - "Cheese" + - "Peppers" + - "Onions" +``` + +Now, in this example we've done something tricky. The `toppings: |-` line is +declaring a multi-line string. So our list of toppings is actually not a YAML +list. It's a big string. Why would we do this? Because the data in ConfigMaps +`data` is composed of key/value pairs, where both the key and the value are +simple strings. To understand why this is the case, take a look at the +[Kubernetes ConfigMap docs](https://kubernetes.io/docs/user-guide/configmap/). +For us, though, this detail doesn't matter much. + +> The `|-` marker in YAML takes a multi-line string. This can be a useful +> technique for embedding big blocks of data inside of your manifests, as +> exemplified here. + +Sometimes it's useful to be able to quickly make a list inside of your template, +and then iterate over that list. Helm templates have a function to make this +easy: `tuple`. In computer science, a tuple is a list-like collection of fixed +size, but with arbitrary data types. This roughly conveys the way a `tuple` is +used. + +```yaml + sizes: |- + {{- range tuple "small" "medium" "large" }} + - {{ . }} + {{- end }} +``` + +The above will produce this: + +```yaml + sizes: |- + - small + - medium + - large +``` + +In addition to lists and tuples, `range` can be used to iterate over collections +that have a key and a value (like a `map` or `dict`). We'll see how to do that +in the next section when we introduce template variables. diff --git a/content/en/docs/chart_template_guide/data_types.md b/content/en/docs/chart_template_guide/data_types.md new file mode 100644 index 0000000000..2ed81e56fc --- /dev/null +++ b/content/en/docs/chart_template_guide/data_types.md @@ -0,0 +1,26 @@ +--- +title: "Appendix: Go Data Types and Templates" +description: "A quick overview on variables in templates." +weight: 16 +--- + +The Helm template language is implemented in the strongly typed Go programming +language. For that reason, variables in templates are _typed_. For the most +part, variables will be exposed as one of the following types: + +- string: A string of text +- bool: a `true` or `false` +- int: An integer value (there are also 8, 16, 32, and 64 bit signed and + unsigned variants of this) +- float64: a 64-bit floating point value (there are also 8, 16, and 32 bit + varieties of this) +- a byte slice (`[]byte`), often used to hold (potentially) binary data +- struct: an object with properties and methods +- a slice (indexed list) of one of the previous types +- a string-keyed map (`map[string]interface{}`) where the value is one of the + previous types + +There are many other types in Go, and sometimes you will have to convert between +them in your templates. The easiest way to debug an object's type is to pass it +through `printf "%t"` in a template, which will print the type. Also see the +`typeOf` and `kindOf` functions. diff --git a/content/en/docs/chart_template_guide/debugging.md b/content/en/docs/chart_template_guide/debugging.md new file mode 100644 index 0000000000..72a787fa7d --- /dev/null +++ b/content/en/docs/chart_template_guide/debugging.md @@ -0,0 +1,40 @@ +--- +title: "Debugging Templates" +description: "Troubleshooting charts that are failing to deploy." +weight: 13 +--- + +Debugging templates can be tricky because the rendered templates are sent to the +Kubernetes API server, which may reject the YAML files for reasons other than +formatting. + +There are a few commands that can help you debug. + +- `helm lint` is your go-to tool for verifying that your chart follows best + practices +- `helm template --debug` will test rendering chart templates locally. +- `helm install --dry-run --debug`: We've seen this trick already. It's a great way to have the server render your templates, then + return the resulting manifest file. +- `helm get manifest`: This is a good way to see what templates are installed on + the server. + +When your YAML is failing to parse, but you want to see what is generated, one +easy way to retrieve the YAML is to comment out the problem section in the +template, and then re-run `helm install --dry-run --debug`: + +```yaml +apiVersion: v2 +# some: problem section +# {{ .Values.foo | quote }} +``` + +The above will be rendered and returned with the comments intact: + +```yaml +apiVersion: v2 +# some: problem section +# "bar" +``` + +This provides a quick way of viewing the generated content without YAML parse +errors blocking. diff --git a/content/en/docs/chart_template_guide/function_list.md b/content/en/docs/chart_template_guide/function_list.md new file mode 100644 index 0000000000..69baebd0b5 --- /dev/null +++ b/content/en/docs/chart_template_guide/function_list.md @@ -0,0 +1,2174 @@ +--- +title: "Template Function List" +description: "A list of template functions available in Helm" +weight: 6 +--- + +Helm includes many template functions you can take advantage of in templates. +They are listed here and broken down by the following categories: + +* [Cryptographic and Security](#cryptographic-and-security-functions) +* [Date](#date-functions) +* [Dictionaries](#dictionaries-and-dict-functions) +* [Encoding](#encoding-functions) +* [File Path](#file-path-functions) +* [Kubernetes and Chart](#kubernetes-and-chart-functions) +* [Logic and Flow Control](#logic-and-flow-control-functions) +* [Lists](#lists-and-list-functions) +* [Math](#math-functions) +* [Network](#network-functions) +* [Reflection](#reflection-functions) +* [Regular Expressions](#regular-expressions) +* [Semantic Versions](#semantic-version-functions) +* [String](#string-functions) +* [Type Conversion](#type-conversion-functions) +* [URL](#url-functions) +* [UUID](#uuid-functions) + +## Logic and Flow Control Functions + +Helm includes numerous logic and control flow functions including [and](#and), +[coalesce](#coalesce), [default](#default), [empty](#empty), [eq](#eq), +[fail](#fail), [ge](#ge), [gt](#gt), [le](#le), [lt](#lt), [ne](#ne), +[not](#not), and [or](#or). + +### and + +Returns the boolean AND of two or more arguments +(the first empty argument, or the last argument). + +``` +and .Arg1 .Arg2 +``` + +### or + +Returns the boolean OR of two or more arguments +(the first non-empty argument, or the last argument). + +``` +or .Arg1 .Arg2 +``` + +### not + +Returns the boolean negation of its argument. + +``` +not .Arg +``` + +### eq + +Returns the boolean equality of the arguments (e.g., Arg1 == Arg2). + +``` +eq .Arg1 .Arg2 +``` + +### ne + +Returns the boolean inequality of the arguments (e.g., Arg1 != Arg2) + +``` +ne .Arg1 .Arg2 +``` + +### lt + +Returns a boolean true if the first argument is less than the second. False is +returned otherwise (e.g., Arg1 < Arg2). + +``` +lt .Arg1 .Arg2 +``` + +### le + +Returns a boolean true if the first argument is less than or equal to the +second. False is returned otherwise (e.g., Arg1 <= Arg2). + +``` +le .Arg1 .Arg2 +``` + +### gt + +Returns a boolean true if the first argument is greater than the second. False +is returned otherwise (e.g., Arg1 > Arg2). + +``` +gt .Arg1 .Arg2 +``` + +### ge + +Returns a boolean true if the first argument is greater than or equal to the +second. False is returned otherwise (e.g., Arg1 >= Arg2). + +``` +ge .Arg1 .Arg2 +``` + +### default + +To set a simple default value, use `default`: + +``` +default "foo" .Bar +``` + +In the above, if `.Bar` evaluates to a non-empty value, it will be used. But if +it is empty, `foo` will be returned instead. + +The definition of "empty" depends on type: + +- Numeric: 0 +- String: "" +- Lists: `[]` +- Dicts: `{}` +- Boolean: `false` +- And always `nil` (aka null) + +For structs, there is no definition of empty, so a struct will never return the +default. + +### empty + +The `empty` function returns `true` if the given value is considered empty, and +`false` otherwise. The empty values are listed in the `default` section. + +``` +empty .Foo +``` + +Note that in Go template conditionals, emptiness is calculated for you. Thus, +you rarely need `if not empty .Foo`. Instead, just use `if .Foo`. + +### fail + +Unconditionally returns an empty `string` and an `error` with the specified +text. This is useful in scenarios where other conditionals have determined that +template rendering should fail. + +``` +fail "Please accept the end user license agreement" +``` + +### coalesce + +The `coalesce` function takes a list of values and returns the first non-empty +one. + +``` +coalesce 0 1 2 +``` + +The above returns `1`. + +This function is useful for scanning through multiple variables or values: + +``` +coalesce .name .parent.name "Matt" +``` + +The above will first check to see if `.name` is empty. If it is not, it will +return that value. If it _is_ empty, `coalesce` will evaluate `.parent.name` for +emptiness. Finally, if both `.name` and `.parent.name` are empty, it will return +`Matt`. + +### ternary + +The `ternary` function takes two values, and a test value. If the test value is +true, the first value will be returned. If the test value is empty, the second +value will be returned. This is similar to the ternary operator in C and other programming languages. + +#### true test value + +``` +ternary "foo" "bar" true +``` + +or + +``` +true | ternary "foo" "bar" +``` + +The above returns `"foo"`. + +#### false test value + +``` +ternary "foo" "bar" false +``` + +or + +``` +false | ternary "foo" "bar" +``` + +The above returns `"bar"`. + +## String Functions + +Helm includes the following string functions: [abbrev](#abbrev), +[abbrevboth](#abbrevboth), [camelcase](#camelcase), [cat](#cat), +[contains](#contains), [hasPrefix](#hasprefix-and-hassuffix), +[hasSuffix](#hasprefix-and-hassuffix), [indent](#indent), [initials](#initials), +[kebabcase](#kebabcase), [lower](#lower), [nindent](#nindent), +[nospace](#nospace), [plural](#plural), [print](#print), [printf](#printf), +[println](#println), [quote](#quote-and-squote), +[randAlpha](#randalphanum-randalpha-randnumeric-and-randascii), +[randAlphaNum](#randalphanum-randalpha-randnumeric-and-randascii), +[randAscii](#randalphanum-randalpha-randnumeric-and-randascii), +[randNumeric](#randalphanum-randalpha-randnumeric-and-randascii), +[repeat](#repeat), [replace](#replace), [shuffle](#shuffle), +[snakecase](#snakecase), [squote](#quote-and-squote), [substr](#substr), +[swapcase](#swapcase), [title](#title), [trim](#trim), [trimAll](#trimall), +[trimPrefix](#trimprefix), [trimSuffix](#trimsuffix), [trunc](#trunc), +[untitle](#untitle), [upper](#upper), [wrap](#wrap), and [wrapWith](#wrapwith). + +### print + +Returns a string from the combination of its parts. + +``` +print "Matt has " .Dogs " dogs" +``` + +Types that are not strings are converted to strings where possible. + +Note, when two arguments next to each other are not strings a space is added +between them. + +### println + +Works the same way as [print](#print) but adds a new line at the end. + +### printf + +Returns a string based on a formatting string and the arguments to pass to it in +order. + +``` +printf "%s has %d dogs." .Name .NumberDogs +``` + +The placeholder to use depends on the type for the argument being passed in. +This includes: + +General purpose: + +* `%v` the value in a default format + * when printing dicts, the plus flag (%+v) adds field names +* `%%` a literal percent sign; consumes no value + +Boolean: + +* `%t` the word true or false + +Integer: + +* `%b` base 2 +* `%c` the character represented by the corresponding Unicode code point +* `%d` base 10 +* `%o` base 8 +* `%O` base 8 with 0o prefix +* `%q` a single-quoted character literal safely escaped +* `%x` base 16, with lower-case letters for a-f +* `%X` base 16, with upper-case letters for A-F +* `%U` Unicode format: U+1234; same as "U+%04X" + + Floating-point and complex constituents: + +* `%b` decimal less scientific notation with exponent a power of two, e.g. + -123456p-78 +* `%e` scientific notation, e.g. -1.234456e+78 +* `%E` scientific notation, e.g. -1.234456E+78 +* `%f` decimal point but no exponent, e.g. 123.456 +* `%F` synonym for %f +* `%g` %e for large exponents, %f otherwise. +* `%G` %E for large exponents, %F otherwise +* `%x` hexadecimal notation (with decimal power of two exponent), e.g. + -0x1.23abcp+20 +* `%X` upper-case hexadecimal notation, e.g. -0X1.23ABCP+20 + +String and slice of bytes (treated equivalently with these verbs): + +* `%s` the uninterpreted bytes of the string or slice +* `%q` a double-quoted string safely escaped +* `%x` base 16, lower-case, two characters per byte +* `%X` base 16, upper-case, two characters per byte + +Slice: + +* `%p` address of 0th element in base 16 notation, with leading 0x + +### trim + +The `trim` function removes white space from both sides of a string: + +``` +trim " hello " +``` + +The above produces `hello` + +### trimAll + +Removes the given characters from the front and back of a string: + +``` +trimAll "$" "$5.00" +``` + +The above returns `5.00` (as a string). + +### trimPrefix + +Trim just the prefix from a string: + +``` +trimPrefix "-" "-hello" +``` + +The above returns `hello` + +### trimSuffix + +Trim just the suffix from a string: + +``` +trimSuffix "-" "hello-" +``` + +The above returns `hello` + +### lower + +Convert the entire string to lowercase: + +``` +lower "HELLO" +``` + +The above returns `hello` + +### upper + +Convert the entire string to uppercase: + +``` +upper "hello" +``` + +The above returns `HELLO` + +### title + +Convert to title case: + +``` +title "hello world" +``` + +The above returns `Hello World` + +### untitle + +Remove title casing. `untitle "Hello World"` produces `hello world`. + +### repeat + +Repeat a string multiple times: + +``` +repeat 3 "hello" +``` + +The above returns `hellohellohello` + +### substr + +Get a substring from a string. It takes three parameters: + +- start (int) +- end (int) +- string (string) + +``` +substr 0 5 "hello world" +``` + +The above returns `hello` + +### nospace + +Remove all whitespace from a string. + +``` +nospace "hello w o r l d" +``` + +The above returns `helloworld` + +### trunc + +Truncate a string + +``` +trunc 5 "hello world" +``` + +The above produces `hello`. + +``` +trunc -5 "hello world" +``` + +The above produces `world`. + +### abbrev + +Truncate a string with ellipses (`...`) + +Parameters: + +- max length +- the string + +``` +abbrev 5 "hello world" +``` + +The above returns `he...`, since it counts the width of the ellipses against the +maximum length. + +### abbrevboth + +Abbreviate both sides: + +``` +abbrevboth 5 10 "1234 5678 9123" +``` + +the above produces `...5678...` + +It takes: + +- left offset +- max length +- the string + +### initials + +Given multiple words, take the first letter of each word and combine. + +``` +initials "First Try" +``` + +The above returns `FT` + +### randAlphaNum, randAlpha, randNumeric, and randAscii + +These four functions generate cryptographically secure (uses ```crypto/rand```) +random strings, but with different base character sets: + +- `randAlphaNum` uses `0-9a-zA-Z` +- `randAlpha` uses `a-zA-Z` +- `randNumeric` uses `0-9` +- `randAscii` uses all printable ASCII characters + +Each of them takes one parameter: the integer length of the string. + +``` +randNumeric 3 +``` + +The above will produce a random string with three digits. + +### wrap + +Wrap text at a given column count: + +``` +wrap 80 $someText +``` + +The above will wrap the string in `$someText` at 80 columns. + +### wrapWith + +`wrapWith` works as `wrap`, but lets you specify the string to wrap with. +(`wrap` uses `\n`) + +``` +wrapWith 5 "\t" "Hello World" +``` + +The above produces `hello world` (where the whitespace is an ASCII tab +character) + +### contains + +Test to see if one string is contained inside of another: + +``` +contains "cat" "catch" +``` + +The above returns `true` because `catch` contains `cat`. + +### hasPrefix and hasSuffix + +The `hasPrefix` and `hasSuffix` functions test whether a string has a given +prefix or suffix: + +``` +hasPrefix "cat" "catch" +``` + +The above returns `true` because `catch` has the prefix `cat`. + +### quote and squote + +These functions wrap a string in double quotes (`quote`) or single quotes +(`squote`). + +### cat + +The `cat` function concatenates multiple strings together into one, separating +them with spaces: + +``` +cat "hello" "beautiful" "world" +``` + +The above produces `hello beautiful world` + +### indent + +The `indent` function indents every line in a given string to the specified +indent width. This is useful when aligning multi-line strings: + +``` +indent 4 $lots_of_text +``` + +The above will indent every line of text by 4 space characters. + +### nindent + +The `nindent` function is the same as the indent function, but prepends a new +line to the beginning of the string. + +``` +nindent 4 $lots_of_text +``` + +The above will indent every line of text by 4 space characters and add a new +line to the beginning. + +### replace + +Perform simple string replacement. + +It takes three arguments: + +- string to replace +- string to replace with +- source string + +``` +"I Am Henry VIII" | replace " " "-" +``` + +The above will produce `I-Am-Henry-VIII` + +### plural + +Pluralize a string. + +``` +len $fish | plural "one anchovy" "many anchovies" +``` + +In the above, if the length of the string is 1, the first argument will be +printed (`one anchovy`). Otherwise, the second argument will be printed (`many +anchovies`). + +The arguments are: + +- singular string +- plural string +- length integer + +NOTE: Helm does not currently support languages with more complex pluralization +rules. And `0` is considered a plural because the English language treats it as +such (`zero anchovies`). + +### snakecase + +Convert string from camelCase to snake_case. + +``` +snakecase "FirstName" +``` + +This above will produce `first_name`. + +### camelcase + +Convert string from snake_case to CamelCase + +``` +camelcase "http_server" +``` + +This above will produce `HttpServer`. + +### kebabcase + +Convert string from camelCase to kebab-case. + +``` +kebabcase "FirstName" +``` + +This above will produce `first-name`. + +### swapcase + +Swap the case of a string using a word based algorithm. + +Conversion algorithm: + +- Upper case character converts to Lower case +- Title case character converts to Lower case +- Lower case character after Whitespace or at start converts to Title case +- Other Lower case character converts to Upper case +- Whitespace is defined by unicode.IsSpace(char) + +``` +swapcase "This Is A.Test" +``` + +This above will produce `tHIS iS a.tEST`. + +### shuffle + +Shuffle a string. + +``` +shuffle "hello" +``` + +The above will randomize the letters in `hello`, perhaps producing `oelhl`. + +## Type Conversion Functions + +The following type conversion functions are provided by Helm: + +- `atoi`: Convert a string to an integer. +- `float64`: Convert to a `float64`. +- `int`: Convert to an `int` at the system's width. +- `int64`: Convert to an `int64`. +- `toDecimal`: Convert a unix octal to a `int64`. +- `toString`: Convert to a string. +- `toStrings`: Convert a list, slice, or array to a list of strings. +- `toJson` (`mustToJson`): Convert list, slice, array, dict, or object to JSON. +- `toPrettyJson` (`mustToPrettyJson`): Convert list, slice, array, dict, or + object to indented JSON. +- `toRawJson` (`mustToRawJson`): Convert list, slice, array, dict, or object to + JSON with HTML characters unescaped. +- `fromYaml`: Convert a YAML string to an object. +- `fromJson`: Convert a JSON string to an object. +- `toYaml`: Convert list, slice, array, dict, or object to indented yaml, can be used to copy chunks of yaml from any source. This function is equivalent to GoLang yaml.Marshal function, see docs here: https://pkg.go.dev/gopkg.in/yaml.v2#Marshal + +Only `atoi` requires that the input be a specific type. The others will attempt +to convert from any type to the destination type. For example, `int64` can +convert floats to ints, and it can also convert strings to ints. + +### toStrings + +Given a list-like collection, produce a slice of strings. + +``` +list 1 2 3 | toStrings +``` + +The above converts `1` to `"1"`, `2` to `"2"`, and so on, and then returns them +as a list. + +### toDecimal + +Given a unix octal permission, produce a decimal. + +``` +"0777" | toDecimal +``` + +The above converts `0777` to `511` and returns the value as an int64. + +### toJson, mustToJson + +The `toJson` function encodes an item into a JSON string. If the item cannot be +converted to JSON the function will return an empty string. `mustToJson` will +return an error in case the item cannot be encoded in JSON. + +``` +toJson .Item +``` + +The above returns JSON string representation of `.Item`. + +### toPrettyJson, mustToPrettyJson + +The `toPrettyJson` function encodes an item into a pretty (indented) JSON +string. + +``` +toPrettyJson .Item +``` + +The above returns indented JSON string representation of `.Item`. + +### toRawJson, mustToRawJson + +The `toRawJson` function encodes an item into JSON string with HTML characters +unescaped. + +``` +toRawJson .Item +``` + +The above returns unescaped JSON string representation of `.Item`. + +### fromYaml + +The `fromYaml` function takes a YAML string and returns an object that can be used in templates. + +`File at: yamls/person.yaml` +```yaml +name: Bob +age: 25 +hobbies: + - hiking + - fishing + - cooking +``` +```yaml +{{- $person := .Files.Get "yamls/person.yaml" | fromYaml }} +greeting: | + Hi, my name is {{ $person.name }} and I am {{ $person.age }} years old. + My hobbies are {{ range $person.hobbies }}{{ . }} {{ end }}. +``` + +### fromJson + +The `fromJson` function takes a YAML string and returns an object that can be used in templates. + +`File at: jsons/person.json` +```json +{ + "name": "Bob", + "age": 25, + "hobbies": [ + "hiking", + "fishing", + "cooking" + ] +} +``` +```yaml +{{- $person := .Files.Get "jsons/person.json" | fromJson }} +greeting: | + Hi, my name is {{ $person.name }} and I am {{ $person.age }} years old. + My hobbies are {{ range $person.hobbies }}{{ . }} {{ end }}. +``` + +## Regular Expressions + +Helm includes the following regular expression functions: [regexFind +(mustRegexFind)](#regexfindall-mustregexfindall), [regexFindAll +(mustRegexFindAll)](#regexfind-mustregexfind), [regexMatch +(mustRegexMatch)](#regexmatch-mustregexmatch), [regexReplaceAll +(mustRegexReplaceAll)](#regexreplaceall-mustregexreplaceall), +[regexReplaceAllLiteral +(mustRegexReplaceAllLiteral)](#regexreplaceallliteral-mustregexreplaceallliteral), +[regexSplit (mustRegexSplit)](#regexsplit-mustregexsplit). + +### regexMatch, mustRegexMatch + +Returns true if the input string contains any match of the regular expression. + +``` +regexMatch "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$" "test@acme.com" +``` + +The above produces `true` + +`regexMatch` panics if there is a problem and `mustRegexMatch` returns an error +to the template engine if there is a problem. + +### regexFindAll, mustRegexFindAll + +Returns a slice of all matches of the regular expression in the input string. +The last parameter n determines the number of substrings to return, where -1 +means return all matches + +``` +regexFindAll "[2,4,6,8]" "123456789" -1 +``` + +The above produces `[2 4 6 8]` + +`regexFindAll` panics if there is a problem and `mustRegexFindAll` returns an +error to the template engine if there is a problem. + +### regexFind, mustRegexFind + +Return the first (left most) match of the regular expression in the input string + +``` +regexFind "[a-zA-Z][1-9]" "abcd1234" +``` + +The above produces `d1` + +`regexFind` panics if there is a problem and `mustRegexFind` returns an error to +the template engine if there is a problem. + +### regexReplaceAll, mustRegexReplaceAll + +Returns a copy of the input string, replacing matches of the Regexp with the +replacement string replacement. Inside string replacement, $ signs are +interpreted as in Expand, so for instance $1 represents the text of the first +submatch + +``` +regexReplaceAll "a(x*)b" "-ab-axxb-" "${1}W" +``` + +The above produces `-W-xxW-` + +`regexReplaceAll` panics if there is a problem and `mustRegexReplaceAll` returns +an error to the template engine if there is a problem. + +### regexReplaceAllLiteral, mustRegexReplaceAllLiteral + +Returns a copy of the input string, replacing matches of the Regexp with the +replacement string replacement. The replacement string is substituted directly, +without using Expand + +``` +regexReplaceAllLiteral "a(x*)b" "-ab-axxb-" "${1}" +``` + +The above produces `-${1}-${1}-` + +`regexReplaceAllLiteral` panics if there is a problem and +`mustRegexReplaceAllLiteral` returns an error to the template engine if there is +a problem. + +### regexSplit, mustRegexSplit + +Slices the input string into substrings separated by the expression and returns +a slice of the substrings between those expression matches. The last parameter +`n` determines the number of substrings to return, where `-1` means return all +matches + +``` +regexSplit "z+" "pizza" -1 +``` + +The above produces `[pi a]` + +`regexSplit` panics if there is a problem and `mustRegexSplit` returns an error +to the template engine if there is a problem. + +## Cryptographic and Security Functions + +Helm provides some advanced cryptographic functions. They include +[adler32sum](#adler32sum), [buildCustomCert](#buildcustomcert), +[decryptAES](#decryptaes), [derivePassword](#derivepassword), +[encryptAES](#encryptaes), [genCA](#genca), [genPrivateKey](#genprivatekey), +[genSelfSignedCert](#genselfsignedcert), [genSignedCert](#gensignedcert), +[htpasswd](#htpasswd), [sha1sum](#sha1sum), and [sha256sum](#sha256sum). + +### sha1sum + +The `sha1sum` function receives a string, and computes it's SHA1 digest. + +``` +sha1sum "Hello world!" +``` + +### sha256sum + +The `sha256sum` function receives a string, and computes it's SHA256 digest. + +``` +sha256sum "Hello world!" +``` + +The above will compute the SHA 256 sum in an "ASCII armored" format that is safe +to print. + +### adler32sum + +The `adler32sum` function receives a string, and computes its Adler-32 checksum. + +``` +adler32sum "Hello world!" +``` + +### htpasswd + +The `htpasswd` function takes a `username` and `password` and generates a +`bcrypt` hash of the password. The result can be used for basic authentication +on an [Apache HTTP +Server](https://httpd.apache.org/docs/2.4/misc/password_encryptions.html#basic). + +``` +htpasswd "myUser" "myPassword" +``` + +Note that it is insecure to store the password directly in the template. + +### derivePassword + +The `derivePassword` function can be used to derive a specific password based on +some shared "master password" constraints. The algorithm for this is [well +specified](https://masterpassword.app/masterpassword-algorithm.pdf). + +``` +derivePassword 1 "long" "password" "user" "example.com" +``` + +Note that it is considered insecure to store the parts directly in the template. + +### genPrivateKey + +The `genPrivateKey` function generates a new private key encoded into a PEM +block. + +It takes one of the values for its first param: + +- `ecdsa`: Generate an elliptic curve DSA key (P256) +- `dsa`: Generate a DSA key (L2048N256) +- `rsa`: Generate an RSA 4096 key + +### buildCustomCert + +The `buildCustomCert` function allows customizing the certificate. + +It takes the following string parameters: + +- A base64 encoded PEM format certificate +- A base64 encoded PEM format private key + +It returns a certificate object with the following attributes: + +- `Cert`: A PEM-encoded certificate +- `Key`: A PEM-encoded private key + +Example: + +``` +$ca := buildCustomCert "base64-encoded-ca-crt" "base64-encoded-ca-key" +``` + +Note that the returned object can be passed to the `genSignedCert` function to +sign a certificate using this CA. + +### genCA + +The `genCA` function generates a new, self-signed x509 certificate authority. + +It takes the following parameters: + +- Subject's common name (cn) +- Cert validity duration in days + +It returns an object with the following attributes: + +- `Cert`: A PEM-encoded certificate +- `Key`: A PEM-encoded private key + +Example: + +``` +$ca := genCA "foo-ca" 365 +``` + +Note that the returned object can be passed to the `genSignedCert` function to +sign a certificate using this CA. + +### genSelfSignedCert + +The `genSelfSignedCert` function generates a new, self-signed x509 certificate. + +It takes the following parameters: + +- Subject's common name (cn) +- Optional list of IPs; may be nil +- Optional list of alternate DNS names; may be nil +- Cert validity duration in days + +It returns an object with the following attributes: + +- `Cert`: A PEM-encoded certificate +- `Key`: A PEM-encoded private key + +Example: + +``` +$cert := genSelfSignedCert "foo.com" (list "10.0.0.1" "10.0.0.2") (list "bar.com" "bat.com") 365 +``` + +### genSignedCert + +The `genSignedCert` function generates a new, x509 certificate signed by the +specified CA. + +It takes the following parameters: + +- Subject's common name (cn) +- Optional list of IPs; may be nil +- Optional list of alternate DNS names; may be nil +- Cert validity duration in days +- CA (see `genCA`) + +Example: + +``` +$ca := genCA "foo-ca" 365 +$cert := genSignedCert "foo.com" (list "10.0.0.1" "10.0.0.2") (list "bar.com" "bat.com") 365 $ca +``` + +### encryptAES + +The `encryptAES` function encrypts text with AES-256 CBC and returns a base64 +encoded string. + +``` +encryptAES "secretkey" "plaintext" +``` + +### decryptAES + +The `decryptAES` function receives a base64 string encoded by the AES-256 CBC +algorithm and returns the decoded text. + +``` +"30tEfhuJSVRhpG97XCuWgz2okj7L8vQ1s6V9zVUPeDQ=" | decryptAES "secretkey" +``` + +## Date Functions + +Helm includes the following date functions you can use in templates: +[ago](#ago), [date](#date), [dateInZone](#dateinzone), [dateModify +(mustDateModify)](#datemodify-mustdatemodify), [duration](#duration), +[durationRound](#durationround), [htmlDate](#htmldate), +[htmlDateInZone](#htmldateinzone), [now](#now), [toDate +(mustToDate)](#todate-musttodate), and [unixEpoch](#unixepoch). + +### now + +The current date/time. Use this in conjunction with other date functions. + +### ago + +The `ago` function returns duration from time.Now in seconds resolution. + +``` +ago .CreatedAt +``` + +returns in `time.Duration` String() format + +``` +2h34m7s +``` + +### date + +The `date` function formats a date. + +Format the date to YEAR-MONTH-DAY: + +``` +now | date "2006-01-02" +``` + +Date formatting in Go is a [little bit +different](https://pauladamsmith.com/blog/2011/05/go_time.html). + +In short, take this as the base date: + +``` +Mon Jan 2 15:04:05 MST 2006 +``` + +Write it in the format you want. Above, `2006-01-02` is the same date, but in +the format we want. + +### dateInZone + +Same as `date`, but with a timezone. + +``` +dateInZone "2006-01-02" (now) "UTC" +``` + +### duration + +Formats a given amount of seconds as a `time.Duration`. + +This returns 1m35s + +``` +duration 95 +``` + +### durationRound + +Rounds a given duration to the most significant unit. Strings and +`time.Duration` gets parsed as a duration, while a `time.Time` is calculated as +the duration since. + +This return 2h + +``` +durationRound "2h10m5s" +``` + +This returns 3mo + +``` +durationRound "2400h10m5s" +``` + +### unixEpoch + +Returns the seconds since the unix epoch for a `time.Time`. + +``` +now | unixEpoch +``` + +### dateModify, mustDateModify + +The `dateModify` takes a modification and a date and returns the timestamp. + +Subtract an hour and thirty minutes from the current time: + +``` +now | date_modify "-1.5h" +``` + +If the modification format is wrong `dateModify` will return the date +unmodified. `mustDateModify` will return an error otherwise. + +### htmlDate + +The `htmlDate` function formats a date for inserting into an HTML date picker +input field. + +``` +now | htmlDate +``` + +### htmlDateInZone + +Same as htmlDate, but with a timezone. + +``` +htmlDateInZone (now) "UTC" +``` + +### toDate, mustToDate + +`toDate` converts a string to a date. The first argument is the date layout and +the second the date string. If the string can't be convert it returns the zero +value. `mustToDate` will return an error in case the string cannot be converted. + +This is useful when you want to convert a string date to another format (using +pipe). The example below converts "2017-12-31" to "31/12/2017". + +``` +toDate "2006-01-02" "2017-12-31" | date "02/01/2006" +``` + +## Dictionaries and Dict Functions + +Helm provides a key/value storage type called a `dict` (short for "dictionary", +as in Python). A `dict` is an _unordered_ type. + +The key to a dictionary **must be a string**. However, the value can be any +type, even another `dict` or `list`. + +Unlike `list`s, `dict`s are not immutable. The `set` and `unset` functions will +modify the contents of a dictionary. + +Helm provides the following functions to support working with dicts: [deepCopy +(mustDeepCopy)](#deepcopy-mustdeepcopy), [dict](#dict), [dig](#dig), [get](#get), +[hasKey](#haskey), [keys](#keys), [merge (mustMerge)](#merge-mustmerge), +[mergeOverwrite (mustMergeOverwrite)](#mergeoverwrite-mustmergeoverwrite), +[omit](#omit), [pick](#pick), [pluck](#pluck), [set](#set), [unset](#unset), and +[values](#values). + +### dict + +Creating dictionaries is done by calling the `dict` function and passing it a +list of pairs. + +The following creates a dictionary with three items: + +``` +$myDict := dict "name1" "value1" "name2" "value2" "name3" "value 3" +``` + +### get + +Given a map and a key, get the value from the map. + +``` +get $myDict "name1" +``` + +The above returns `"value1"` + +Note that if the key is not found, this operation will simply return `""`. No +error will be generated. + +### set + +Use `set` to add a new key/value pair to a dictionary. + +``` +$_ := set $myDict "name4" "value4" +``` + +Note that `set` _returns the dictionary_ (a requirement of Go template +functions), so you may need to trap the value as done above with the `$_` +assignment. + +### unset + +Given a map and a key, delete the key from the map. + +``` +$_ := unset $myDict "name4" +``` + +As with `set`, this returns the dictionary. + +Note that if the key is not found, this operation will simply return. No error +will be generated. + +### hasKey + +The `hasKey` function returns `true` if the given dict contains the given key. + +``` +hasKey $myDict "name1" +``` + +If the key is not found, this returns `false`. + +### pluck + +The `pluck` function makes it possible to give one key and multiple maps, and +get a list of all of the matches: + +``` +pluck "name1" $myDict $myOtherDict +``` + +The above will return a `list` containing every found value (`[value1 +otherValue1]`). + +If the given key is _not found_ in a map, that map will not have an item in the +list (and the length of the returned list will be less than the number of dicts +in the call to `pluck`). + +If the key is _found_ but the value is an empty value, that value will be +inserted. + +A common idiom in Helm templates is to use `pluck... | first` to get the first +matching key out of a collection of dictionaries. + +### dig + +The `dig` function traverses a nested set of dicts, selecting keys from a list +of values. It returns a default value if any of the keys are not found at the +associated dict. + +``` +dig "user" "role" "humanName" "guest" $dict +``` + +Given a dict structured like +``` +{ + user: { + role: { + humanName: "curator" + } + } +} +``` + +the above would return `"curator"`. If the dict lacked even a `user` field, +the result would be `"guest"`. + +Dig can be very useful in cases where you'd like to avoid guard clauses, +especially since Go's template package's `and` doesn't shortcut. For instance +`and a.maybeNil a.maybeNil.iNeedThis` will always evaluate +`a.maybeNil.iNeedThis`, and panic if `a` lacks a `maybeNil` field.) + +`dig` accepts its dict argument last in order to support pipelining. For instance: +``` +merge a b c | dig "one" "two" "three" "" +``` + +### merge, mustMerge + +Merge two or more dictionaries into one, giving precedence to the dest +dictionary: + +Given: + +``` +dst: + default: default + overwrite: me + key: true + +src: + overwrite: overwritten + key: false +``` + +will result in: + +``` +newdict: + default: default + overwrite: me + key: true +``` +``` +$newdict := merge $dest $source1 $source2 +``` + +This is a deep merge operation but not a deep copy operation. Nested objects +that are merged are the same instance on both dicts. If you want a deep copy +along with the merge, then use the `deepCopy` function along with merging. For +example, + +``` +deepCopy $source | merge $dest +``` + +`mustMerge` will return an error in case of unsuccessful merge. + +### mergeOverwrite, mustMergeOverwrite + +Merge two or more dictionaries into one, giving precedence from **right to +left**, effectively overwriting values in the dest dictionary: + +Given: + +``` +dst: + default: default + overwrite: me + key: true + +src: + overwrite: overwritten + key: false +``` + +will result in: + +``` +newdict: + default: default + overwrite: overwritten + key: false +``` + +``` +$newdict := mergeOverwrite $dest $source1 $source2 +``` + +This is a deep merge operation but not a deep copy operation. Nested objects +that are merged are the same instance on both dicts. If you want a deep copy +along with the merge then use the `deepCopy` function along with merging. For +example, + +``` +deepCopy $source | mergeOverwrite $dest +``` + +`mustMergeOverwrite` will return an error in case of unsuccessful merge. + +### keys + +The `keys` function will return a `list` of all of the keys in one or more +`dict` types. Since a dictionary is _unordered_, the keys will not be in a +predictable order. They can be sorted with `sortAlpha`. + +``` +keys $myDict | sortAlpha +``` + +When supplying multiple dictionaries, the keys will be concatenated. Use the +`uniq` function along with `sortAlpha` to get a unique, sorted list of keys. + +``` +keys $myDict $myOtherDict | uniq | sortAlpha +``` + +### pick + +The `pick` function selects just the given keys out of a dictionary, creating a +new `dict`. + +``` +$new := pick $myDict "name1" "name2" +``` + +The above returns `{name1: value1, name2: value2}` + +### omit + +The `omit` function is similar to `pick`, except it returns a new `dict` with +all the keys that _do not_ match the given keys. + +``` +$new := omit $myDict "name1" "name3" +``` + +The above returns `{name2: value2}` + +### values + +The `values` function is similar to `keys`, except it returns a new `list` with +all the values of the source `dict` (only one dictionary is supported). + +``` +$vals := values $myDict +``` + +The above returns `list["value1", "value2", "value 3"]`. Note that the `values` +function gives no guarantees about the result ordering; if you care about this, +then use `sortAlpha`. + +### deepCopy, mustDeepCopy + +The `deepCopy` and `mustDeepCopy` functions take a value and make a deep copy +of the value. This includes dicts and other structures. `deepCopy` panics when +there is a problem, while `mustDeepCopy` returns an error to the template system +when there is an error. + +``` +dict "a" 1 "b" 2 | deepCopy +``` + +### A Note on Dict Internals + +A `dict` is implemented in Go as a `map[string]interface{}`. Go developers can +pass `map[string]interface{}` values into the context to make them available to +templates as `dict`s. + +## Encoding Functions + +Helm has the following encoding and decoding functions: + +- `b64enc`/`b64dec`: Encode or decode with Base64 +- `b32enc`/`b32dec`: Encode or decode with Base32 + +## Lists and List Functions + +Helm provides a simple `list` type that can contain arbitrary sequential lists +of data. This is similar to arrays or slices, but lists are designed to be used +as immutable data types. + +Create a list of integers: + +``` +$myList := list 1 2 3 4 5 +``` + +The above creates a list of `[1 2 3 4 5]`. + +Helm provides the following list functions: [append +(mustAppend)](#append-mustappend), [compact +(mustCompact)](#compact-mustcompact), [concat](#concat), [first +(mustFirst)](#first-mustfirst), [has (mustHas)](#has-musthas), [initial +(mustInitial)](#initial-mustinitial), [last (mustLast)](#last-mustlast), +[prepend (mustPrepend)](#prepend-mustprepend), [rest +(mustRest)](#rest-mustrest), [reverse (mustReverse)](#reverse-mustreverse), +[seq](#seq), [index](#index), [slice (mustSlice)](#slice-mustslice), [uniq +(mustUniq)](#uniq-mustuniq), [until](#until), [untilStep](#untilstep), and +[without (mustWithout)](#without-mustwithout). + +### first, mustFirst + +To get the head item on a list, use `first`. + +`first $myList` returns `1` + +`first` panics if there is a problem, while `mustFirst` returns an error to the +template engine if there is a problem. + +### rest, mustRest + +To get the tail of the list (everything but the first item), use `rest`. + +`rest $myList` returns `[2 3 4 5]` + +`rest` panics if there is a problem, while `mustRest` returns an error to the +template engine if there is a problem. + +### last, mustLast + +To get the last item on a list, use `last`: + +`last $myList` returns `5`. This is roughly analogous to reversing a list and +then calling `first`. + +### initial, mustInitial + +This compliments `last` by returning all _but_ the last element. `initial +$myList` returns `[1 2 3 4]`. + +`initial` panics if there is a problem, while `mustInitial` returns an error to +the template engine if there is a problem. + +### append, mustAppend + +Append a new item to an existing list, creating a new list. + +``` +$new = append $myList 6 +``` + +The above would set `$new` to `[1 2 3 4 5 6]`. `$myList` would remain unaltered. + +`append` panics if there is a problem, while `mustAppend` returns an error to the +template engine if there is a problem. + +### prepend, mustPrepend + +Push an element onto the front of a list, creating a new list. + +``` +prepend $myList 0 +``` + +The above would produce `[0 1 2 3 4 5]`. `$myList` would remain unaltered. + +`prepend` panics if there is a problem, while `mustPrepend` returns an error to +the template engine if there is a problem. + +### concat + +Concatenate arbitrary number of lists into one. + +``` +concat $myList ( list 6 7 ) ( list 8 ) +``` + +The above would produce `[1 2 3 4 5 6 7 8]`. `$myList` would remain unaltered. + +### reverse, mustReverse + +Produce a new list with the reversed elements of the given list. + +``` +reverse $myList +``` + +The above would generate the list `[5 4 3 2 1]`. + +`reverse` panics if there is a problem, while `mustReverse` returns an error to +the template engine if there is a problem. + +### uniq, mustUniq + +Generate a list with all of the duplicates removed. + +``` +list 1 1 1 2 | uniq +``` + +The above would produce `[1 2]` + +`uniq` panics if there is a problem, while `mustUniq` returns an error to the +template engine if there is a problem. + +### without, mustWithout + +The `without` function filters items out of a list. + +``` +without $myList 3 +``` + +The above would produce `[1 2 4 5]` + +`without` can take more than one filter: + +``` +without $myList 1 3 5 +``` + +That would produce `[2 4]` + +`without` panics if there is a problem, while `mustWithout` returns an error to +the template engine if there is a problem. + +### has, mustHas + +Test to see if a list has a particular element. + +``` +has 4 $myList +``` + +The above would return `true`, while `has "hello" $myList` would return false. + +`has` panics if there is a problem, while `mustHas` returns an error to the +template engine if there is a problem. + +### compact, mustCompact + +Accepts a list and removes entries with empty values. + +``` +$list := list 1 "a" "foo" "" +$copy := compact $list +``` + +`compact` will return a new list with the empty (i.e., "") item removed. + +`compact` panics if there is a problem and `mustCompact` returns an error to the +template engine if there is a problem. + +### index + +To get the nth element of a list, use `index list [n]`. To index into +multi-dimensional lists, use `index list [n] [m] ...` +- `index $myList 0` returns `1`. It is the same as `myList[0]` +- `index $myList 0 1` would be the same as `myList[0][1]` + +### slice, mustSlice + +To get partial elements of a list, use `slice list [n] [m]`. It is equivalent of +`list[n:m]`. + +- `slice $myList` returns `[1 2 3 4 5]`. It is same as `myList[:]`. +- `slice $myList 3` returns `[4 5]`. It is same as `myList[3:]`. +- `slice $myList 1 3` returns `[2 3]`. It is same as `myList[1:3]`. +- `slice $myList 0 3` returns `[1 2 3]`. It is same as `myList[:3]`. + +`slice` panics if there is a problem, while `mustSlice` returns an error to the +template engine if there is a problem. + +### until + +The `until` function builds a range of integers. + +``` +until 5 +``` + +The above generates the list `[0, 1, 2, 3, 4]`. + +This is useful for looping with `range $i, $e := until 5`. + +### untilStep + +Like `until`, `untilStep` generates a list of counting integers. But it allows +you to define a start, stop, and step: + +``` +untilStep 3 6 2 +``` + +The above will produce `[3 5]` by starting with 3, and adding 2 until it is +equal or greater than 6. This is similar to Python's `range` function. + +### seq + +Works like the bash `seq` command. + +* 1 parameter (end) - will generate all counting integers between 1 and `end` + inclusive. +* 2 parameters (start, end) - will generate all counting integers between + `start` and `end` inclusive incrementing or decrementing by 1. +* 3 parameters (start, step, end) - will generate all counting integers between + `start` and `end` inclusive incrementing or decrementing by `step`. + +``` +seq 5 => 1 2 3 4 5 +seq -3 => 1 0 -1 -2 -3 +seq 0 2 => 0 1 2 +seq 2 -2 => 2 1 0 -1 -2 +seq 0 2 10 => 0 2 4 6 8 10 +seq 0 -2 -5 => 0 -2 -4 +``` + +## Math Functions + +All math functions operate on `int64` values unless specified otherwise. + +The following math functions are available: [add](#add), [add1](#add1), +[ceil](#ceil), [div](#div), [floor](#floor), [len](#len), [max](#max), +[min](#min), [mod](#mod), [mul](#mul), [round](#round), and [sub](#sub). + +### add + +Sum numbers with `add`. Accepts two or more inputs. + +``` +add 1 2 3 +``` + +### add1 + +To increment by 1, use `add1`. + +### sub + +To subtract, use `sub`. + +### div + +Perform integer division with `div`. + +### mod + +Modulo with `mod`. + +### mul + +Multiply with `mul`. Accepts two or more inputs. + +``` +mul 1 2 3 +``` + +### max + +Return the largest of a series of integers. + +This will return `3`: + +``` +max 1 2 3 +``` + +### min + +Return the smallest of a series of integers. + +`min 1 2 3` will return `1`. + +### floor + +Returns the greatest float value less than or equal to input value. + +`floor 123.9999` will return `123.0`. + +### ceil + +Returns the greatest float value greater than or equal to input value. + +`ceil 123.001` will return `124.0`. + +### round + +Returns a float value with the remainder rounded to the given number to digits +after the decimal point. + +`round 123.555555 3` will return `123.556`. + +### len + +Returns the length of the argument as an integer. + +``` +len .Arg +``` + +## Network Functions + +Helm has a single network function, `getHostByName`. + +The `getHostByName` receives a domain name and returns the ip address. + +`getHostByName "www.google.com"` would return the corresponding ip address of `www.google.com`. + +## File Path Functions + +While Helm template functions do not grant access to the filesystem, they do +provide functions for working with strings that follow file path conventions. +Those include [base](#base), [clean](#clean), [dir](#dir), [ext](#ext), and +[isAbs](#isabs). + +### base + +Return the last element of a path. + +``` +base "foo/bar/baz" +``` + +The above prints "baz". + +### dir + +Return the directory, stripping the last part of the path. So `dir +"foo/bar/baz"` returns `foo/bar`. + +### clean + +Clean up a path. + +``` +clean "foo/bar/../baz" +``` + +The above resolves the `..` and returns `foo/baz`. + +### ext + +Return the file extension. + +``` +ext "foo.bar" +``` + +The above returns `.bar`. + +### isAbs + +To check whether a file path is absolute, use `isAbs`. + +## Reflection Functions + +Helm provides rudimentary reflection tools. These help advanced template +developers understand the underlying Go type information for a particular value. +Helm is written in Go and is strongly typed. The type system applies within +templates. + +Go has several primitive _kinds_, like `string`, `slice`, `int64`, and `bool`. + +Go has an open _type_ system that allows developers to create their own types. + +Helm provides a set of functions for each via [kind functions](#kind-functions) +and [type functions](#type-functions). A [deepEqual](#deepequal) function is +also provided to compare to values. + +### Kind Functions + +There are two Kind functions: `kindOf` returns the kind of an object. + +``` +kindOf "hello" +``` + +The above would return `string`. For simple tests (like in `if` blocks), the +`kindIs` function will let you verify that a value is a particular kind: + +``` +kindIs "int" 123 +``` + +The above will return `true`. + +### Type Functions + +Types are slightly harder to work with, so there are three different functions: + +- `typeOf` returns the underlying type of a value: `typeOf $foo` +- `typeIs` is like `kindIs`, but for types: `typeIs "*io.Buffer" $myVal` +- `typeIsLike` works as `typeIs`, except that it also dereferences pointers + +**Note:** None of these can test whether or not something implements a given +interface, since doing so would require compiling the interface in ahead of +time. + +### deepEqual + +`deepEqual` returns true if two values are ["deeply +equal"](https://golang.org/pkg/reflect/#DeepEqual) + +Works for non-primitive types as well (compared to the built-in `eq`). + +``` +deepEqual (list 1 2 3) (list 1 2 3) +``` + +The above will return `true`. + +## Semantic Version Functions + +Some version schemes are easily parseable and comparable. Helm provides +functions for working with [SemVer 2](http://semver.org) versions. These include +[semver](#semver) and [semverCompare](#semvercompare). Below you will also find +details on using ranges for comparisons. + +### semver + +The `semver` function parses a string into a Semantic Version: + +``` +$version := semver "1.2.3-alpha.1+123" +``` + +_If the parser fails, it will cause template execution to halt with an error._ + +At this point, `$version` is a pointer to a `Version` object with the following +properties: + +- `$version.Major`: The major number (`1` above) +- `$version.Minor`: The minor number (`2` above) +- `$version.Patch`: The patch number (`3` above) +- `$version.Prerelease`: The prerelease (`alpha.1` above) +- `$version.Metadata`: The build metadata (`123` above) +- `$version.Original`: The original version as a string + +Additionally, you can compare a `Version` to another `version` using the +`Compare` function: + +``` +semver "1.4.3" | (semver "1.2.3").Compare +``` + +The above will return `-1`. + +The return values are: + +- `-1` if the given semver is greater than the semver whose `Compare` method was + called +- `1` if the version who's `Compare` function was called is greater. +- `0` if they are the same version + +(Note that in SemVer, the `Metadata` field is not compared during version +comparison operations.) + +### semverCompare + +A more robust comparison function is provided as `semverCompare`. This version +supports version ranges: + +- `semverCompare "1.2.3" "1.2.3"` checks for an exact match +- `semverCompare "~1.2.0" "1.2.3"` checks that the major and minor versions + match, and that the patch number of the second version is _greater than or + equal to_ the first parameter. + +The SemVer functions use the [Masterminds semver +library](https://github.com/Masterminds/semver), from the creators of Sprig. + +### Basic Comparisons + +There are two elements to the comparisons. First, a comparison string is a list +of space or comma separated AND comparisons. These are then separated by || (OR) +comparisons. For example, `">= 1.2 < 3.0.0 || >= 4.2.3"` is looking for a +comparison that's greater than or equal to 1.2 and less than 3.0.0 or is greater +than or equal to 4.2.3. + +The basic comparisons are: + +- `=`: equal (aliased to no operator) +- `!=`: not equal +- `>`: greater than +- `<`: less than +- `>=`: greater than or equal to +- `<=`: less than or equal to + +### Working With Prerelease Versions + +Pre-releases, for those not familiar with them, are used for software releases +prior to stable or generally available releases. Examples of prereleases include +development, alpha, beta, and release candidate releases. A prerelease may be a +version such as `1.2.3-beta.1`, while the stable release would be `1.2.3`. In the +order of precedence, prereleases come before their associated releases. In this +example `1.2.3-beta.1 < 1.2.3`. + +According to the Semantic Version specification prereleases may not be API +compliant with their release counterpart. It says, + +> A pre-release version indicates that the version is unstable and might not +> satisfy the intended compatibility requirements as denoted by its associated +> normal version. + +SemVer comparisons using constraints without a prerelease comparator will skip +prerelease versions. For example, `>=1.2.3` will skip prereleases when looking +at a list of releases, while `>=1.2.3-0` will evaluate and find prereleases. + +The reason for the `0` as a pre-release version in the example comparison is +because pre-releases can only contain ASCII alphanumerics and hyphens (along +with `.` separators), per the spec. Sorting happens in ASCII sort order, again +per the spec. The lowest character is a `0` in ASCII sort order (see an [ASCII +Table](http://www.asciitable.com/)) + +Understanding ASCII sort ordering is important because A-Z comes before a-z. +That means `>=1.2.3-BETA` will return `1.2.3-alpha`. What you might expect from +case sensitivity doesn't apply here. This is due to ASCII sort ordering which is +what the spec specifies. + +### Hyphen Range Comparisons + +There are multiple methods to handle ranges and the first is hyphens ranges. +These look like: + +- `1.2 - 1.4.5` which is equivalent to `>= 1.2 <= 1.4.5` +- `2.3.4 - 4.5` which is equivalent to `>= 2.3.4 <= 4.5` + +### Wildcards In Comparisons + +The `x`, `X`, and `*` characters can be used as a wildcard character. This works +for all comparison operators. When used on the `=` operator it falls back to the +patch level comparison (see tilde below). For example, + +- `1.2.x` is equivalent to `>= 1.2.0, < 1.3.0` +- `>= 1.2.x` is equivalent to `>= 1.2.0` +- `<= 2.x` is equivalent to `< 3` +- `*` is equivalent to `>= 0.0.0` + +### Tilde Range Comparisons (Patch) + +The tilde (`~`) comparison operator is for patch level ranges when a minor +version is specified and major level changes when the minor number is missing. +For example, + +- `~1.2.3` is equivalent to `>= 1.2.3, < 1.3.0` +- `~1` is equivalent to `>= 1, < 2` +- `~2.3` is equivalent to `>= 2.3, < 2.4` +- `~1.2.x` is equivalent to `>= 1.2.0, < 1.3.0` +- `~1.x` is equivalent to `>= 1, < 2` + +### Caret Range Comparisons (Major) + +The caret (`^`) comparison operator is for major level changes once a stable +(1.0.0) release has occurred. Prior to a 1.0.0 release the minor versions acts +as the API stability level. This is useful when comparisons of API versions as a +major change is API breaking. For example, + +- `^1.2.3` is equivalent to `>= 1.2.3, < 2.0.0` +- `^1.2.x` is equivalent to `>= 1.2.0, < 2.0.0` +- `^2.3` is equivalent to `>= 2.3, < 3` +- `^2.x` is equivalent to `>= 2.0.0, < 3` +- `^0.2.3` is equivalent to `>=0.2.3 <0.3.0` +- `^0.2` is equivalent to `>=0.2.0 <0.3.0` +- `^0.0.3` is equivalent to `>=0.0.3 <0.0.4` +- `^0.0` is equivalent to `>=0.0.0 <0.1.0` +- `^0` is equivalent to `>=0.0.0 <1.0.0` + +## URL Functions + +Helm includes the [urlParse](#urlparse), [urlJoin](#urljoin), and +[urlquery](#urlquery) functions enabling you to work with URL parts. + +### urlParse + +Parses string for URL and produces dict with URL parts + +``` +urlParse "http://admin:secret@server.com:8080/api?list=false#anchor" +``` + +The above returns a dict, containing URL object: + +```yaml +scheme: 'http' +host: 'server.com:8080' +path: '/api' +query: 'list=false' +opaque: nil +fragment: 'anchor' +userinfo: 'admin:secret' +``` + +This is implemented used the URL packages from the Go standard library. For more +info, check https://golang.org/pkg/net/url/#URL + +### urlJoin + +Joins map (produced by `urlParse`) to produce URL string + +``` +urlJoin (dict "fragment" "fragment" "host" "host:80" "path" "/path" "query" "query" "scheme" "http") +``` + +The above returns the following string: +``` +http://host:80/path?query#fragment +``` + +### urlquery + +Returns the escaped version of the value passed in as an argument so that it is +suitable for embedding in the query portion of a URL. + +``` +$var := urlquery "string for query" +``` + +## UUID Functions + +Helm can generate UUID v4 universally unique IDs. + +``` +uuidv4 +``` + +The above returns a new UUID of the v4 (randomly generated) type. + +## Kubernetes and Chart Functions + +Helm includes functions for working with Kubernetes including +[.Capabilities.APIVersions.Has](#capabilitiesapiversionshas), +[Files](#file-functions), and [lookup](#lookup). + +### lookup + +`lookup` is used to look up resource in a running cluster. When used with the +`helm template` command it always returns an empty response. + +You can find more detail in the [documentation on the lookup +function](functions_and_pipelines.md/#using-the-lookup-function). + +### .Capabilities.APIVersions.Has + +Returns if an API version or resource is available in a cluster. + +``` +.Capabilities.APIVersions.Has "apps/v1" +.Capabilities.APIVersions.Has "apps/v1/Deployment" +``` + +More information is available on the [built-in object +documentation](builtin_objects.md). + +### File Functions + +There are several functions that enable you to get to non-special files within a +chart. For example, to access application configuration files. These are +documented in [Accessing Files Inside Templates](accessing_files.md). + +_Note, the documentation for many of these functions come from +[Sprig](https://github.com/Masterminds/sprig). Sprig is a template function +library available to Go applications._ diff --git a/content/en/docs/chart_template_guide/functions_and_pipelines.md b/content/en/docs/chart_template_guide/functions_and_pipelines.md new file mode 100644 index 0000000000..1694cc199d --- /dev/null +++ b/content/en/docs/chart_template_guide/functions_and_pipelines.md @@ -0,0 +1,256 @@ +--- +title: "Template Functions and Pipelines" +description: "Using functions in templates." +weight: 5 +--- + +So far, we've seen how to place information into a template. But that +information is placed into the template unmodified. Sometimes we want to +transform the supplied data in a way that makes it more useable to us. + +Let's start with a best practice: When injecting strings from the `.Values` +object into the template, we ought to quote these strings. We can do that by +calling the `quote` function in the template directive: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + drink: {{ quote .Values.favorite.drink }} + food: {{ quote .Values.favorite.food }} +``` + +Template functions follow the syntax `functionName arg1 arg2...`. In the snippet +above, `quote .Values.favorite.drink` calls the `quote` function and passes it a +single argument. + +Helm has over 60 available functions. Some of them are defined by the [Go +template language](https://godoc.org/text/template) itself. Most of the others +are part of the [Sprig template library](https://masterminds.github.io/sprig/). +We'll see many of them as we progress through the examples. + +> While we talk about the "Helm template language" as if it is Helm-specific, it +> is actually a combination of the Go template language, some extra functions, +> and a variety of wrappers to expose certain objects to the templates. Many +> resources on Go templates may be helpful as you learn about templating. + +## Pipelines + +One of the powerful features of the template language is its concept of +_pipelines_. Drawing on a concept from UNIX, pipelines are a tool for chaining +together a series of template commands to compactly express a series of +transformations. In other words, pipelines are an efficient way of getting +several things done in sequence. Let's rewrite the above example using a +pipeline. + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + drink: {{ .Values.favorite.drink | quote }} + food: {{ .Values.favorite.food | quote }} +``` + +In this example, instead of calling `quote ARGUMENT`, we inverted the order. We +"sent" the argument to the function using a pipeline (`|`): +`.Values.favorite.drink | quote`. Using pipelines, we can chain several +functions together: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + drink: {{ .Values.favorite.drink | quote }} + food: {{ .Values.favorite.food | upper | quote }} +``` + +> Inverting the order is a common practice in templates. You will see `.val | +> quote` more often than `quote .val`. Either practice is fine. + +When evaluated, that template will produce this: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: trendsetting-p-configmap +data: + myvalue: "Hello World" + drink: "coffee" + food: "PIZZA" +``` + +Note that our original `pizza` has now been transformed to `"PIZZA"`. + +When pipelining arguments like this, the result of the first evaluation +(`.Values.favorite.drink`) is sent as the _last argument to the function_. We +can modify the drink example above to illustrate with a function that takes two +arguments: `repeat COUNT STRING`: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + drink: {{ .Values.favorite.drink | repeat 5 | quote }} + food: {{ .Values.favorite.food | upper | quote }} +``` + +The `repeat` function will echo the given string the given number of times, so +we will get this for output: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: melting-porcup-configmap +data: + myvalue: "Hello World" + drink: "coffeecoffeecoffeecoffeecoffee" + food: "PIZZA" +``` + +## Using the `default` function + +One function frequently used in templates is the `default` function: `default +DEFAULT_VALUE GIVEN_VALUE`. This function allows you to specify a default value +inside of the template, in case the value is omitted. Let's use it to modify the +drink example above: + +```yaml +drink: {{ .Values.favorite.drink | default "tea" | quote }} +``` + +If we run this as normal, we'll get our `coffee`: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: virtuous-mink-configmap +data: + myvalue: "Hello World" + drink: "coffee" + food: "PIZZA" +``` + +Now, we will remove the favorite drink setting from `values.yaml`: + +```yaml +favorite: + #drink: coffee + food: pizza +``` + +Now re-running `helm install --dry-run --debug fair-worm ./mychart` will produce +this YAML: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: fair-worm-configmap +data: + myvalue: "Hello World" + drink: "tea" + food: "PIZZA" +``` + +In an actual chart, all static default values should live in the `values.yaml`, +and should not be repeated using the `default` command (otherwise they would be +redundant). However, the `default` command is perfect for computed values, which +cannot be declared inside `values.yaml`. For example: + +```yaml +drink: {{ .Values.favorite.drink | default (printf "%s-tea" (include "fullname" .)) }} +``` + +In some places, an `if` conditional guard may be better suited than `default`. +We'll see those in the next section. + +Template functions and pipelines are a powerful way to transform information and +then insert it into your YAML. But sometimes it's necessary to add some template +logic that is a little more sophisticated than just inserting a string. In the +next section we will look at the control structures provided by the template +language. + +## Using the `lookup` function + +The `lookup` function can be used to _look up_ resources in a running cluster. +The synopsis of the lookup function is `lookup apiVersion, kind, namespace, name +-> resource or resource list`. + +| parameter | type | +|------------|--------| +| apiVersion | string | +| kind | string | +| namespace | string | +| name | string | + +Both `name` and `namespace` are optional and can be passed as an empty string +(`""`). + +The following combination of parameters are possible: + +| Behavior | Lookup function | +|----------------------------------------|--------------------------------------------| +| `kubectl get pod mypod -n mynamespace` | `lookup "v1" "Pod" "mynamespace" "mypod"` | +| `kubectl get pods -n mynamespace` | `lookup "v1" "Pod" "mynamespace" ""` | +| `kubectl get pods --all-namespaces` | `lookup "v1" "Pod" "" ""` | +| `kubectl get namespace mynamespace` | `lookup "v1" "Namespace" "" "mynamespace"` | +| `kubectl get namespaces` | `lookup "v1" "Namespace" "" ""` | + +When `lookup` returns an object, it will return a dictionary. This dictionary +can be further navigated to extract specific values. + +The following example will return the annotations present for the `mynamespace` +object: + +```go +(lookup "v1" "Namespace" "" "mynamespace").metadata.annotations +``` + +When `lookup` returns a list of objects, it is possible to access the object +list via the `items` field: + +```go +{{ range $index, $service := (lookup "v1" "Service" "mynamespace" "").items }} + {{/* do something with each service */}} +{{ end }} +``` + +When no object is found, an empty value is returned. This can be used to check +for the existence of an object. + +The `lookup` function uses Helm's existing Kubernetes connection configuration +to query Kubernetes. If any error is returned when interacting with calling the +API server (for example due to lack of permission to access a resource), helm's +template processing will fail. + +Keep in mind that Helm is not supposed to contact the Kubernetes API Server +during a `helm template` or a `helm install|upgrade|delete|rollback --dry-run`, +so the `lookup` function will return an empty list (i.e. dict) in such a case. + +## Operators are functions + +For templates, the operators (`eq`, `ne`, `lt`, `gt`, `and`, `or` and so on) are +all implemented as functions. In pipelines, operations can be grouped with +parentheses (`(`, and `)`). + +Now we can turn from functions and pipelines to flow control with conditions, +loops, and scope modifiers. diff --git a/content/en/docs/chart_template_guide/getting_started.md b/content/en/docs/chart_template_guide/getting_started.md new file mode 100644 index 0000000000..079c2841fa --- /dev/null +++ b/content/en/docs/chart_template_guide/getting_started.md @@ -0,0 +1,278 @@ +--- +title: "Getting Started" +weight: 2 +description: "A quick guide on Chart templates." +aliases: ["/intro/getting_started/"] +--- + +In this section of the guide, we'll create a chart and then add a first +template. The chart we created here will be used throughout the rest of the +guide. + +To get going, let's take a brief look at a Helm chart. + +## Charts + +As described in the [Charts Guide](../../topics/charts), Helm charts are +structured like this: + +``` +mychart/ + Chart.yaml + values.yaml + charts/ + templates/ + ... +``` + +The `templates/` directory is for template files. When Helm evaluates a chart, +it will send all of the files in the `templates/` directory through the template +rendering engine. It then collects the results of those templates and sends them +on to Kubernetes. + +The `values.yaml` file is also important to templates. This file contains the +_default values_ for a chart. These values may be overridden by users during +`helm install` or `helm upgrade`. + +The `Chart.yaml` file contains a description of the chart. You can access it +from within a template. + +The `charts/` directory _may_ contain other charts +(which we call _subcharts_). Later in this guide we will see how those work when +it comes to template rendering. + +## A Starter Chart + +For this guide, we'll create a simple chart called `mychart`, and then we'll +create some templates inside of the chart. + +```console +$ helm create mychart +Creating mychart +``` + +### A Quick Glimpse of `mychart/templates/` + +If you take a look at the `mychart/templates/` directory, you'll notice a few +files already there. + +- `NOTES.txt`: The "help text" for your chart. This will be displayed to your + users when they run `helm install`. +- `deployment.yaml`: A basic manifest for creating a Kubernetes + [deployment](https://kubernetes.io/docs/user-guide/deployments/) +- `service.yaml`: A basic manifest for creating a [service + endpoint](https://kubernetes.io/docs/user-guide/services/) for your deployment +- `_helpers.tpl`: A place to put template helpers that you can re-use throughout + the chart + +And what we're going to do is... _remove them all!_ That way we can work through +our tutorial from scratch. We'll actually create our own `NOTES.txt` and +`_helpers.tpl` as we go. + +```console +$ rm -rf mychart/templates/* +``` + +When you're writing production grade charts, having basic versions of these +charts can be really useful. So in your day-to-day chart authoring, you probably +won't want to remove them. + +## A First Template + +The first template we are going to create will be a `ConfigMap`. In Kubernetes, +a ConfigMap is simply an object for storing configuration data. Other things, +like pods, can access the data in a ConfigMap. + +Because ConfigMaps are basic resources, they make a great starting point for us. + +Let's begin by creating a file called `mychart/templates/configmap.yaml`: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: mychart-configmap +data: + myvalue: "Hello World" +``` + +**TIP:** Template names do not follow a rigid naming pattern. However, we +recommend using the suffix `.yaml` for YAML files and `.tpl` for helpers. + +The YAML file above is a bare-bones ConfigMap, having the minimal necessary +fields. In virtue of the fact that this file is in the `mychart/templates/` +directory, it will be sent through the template engine. + +It is just fine to put a plain YAML file like this in the `mychart/templates/` +directory. When Helm reads this template, it will simply send it to Kubernetes +as-is. + +With this simple template, we now have an installable chart. And we can install +it like this: + +```console +$ helm install full-coral ./mychart +NAME: full-coral +LAST DEPLOYED: Tue Nov 1 17:36:01 2016 +NAMESPACE: default +STATUS: DEPLOYED +REVISION: 1 +TEST SUITE: None +``` + +Using Helm, we can retrieve the release and see the actual template that was +loaded. + +```console +$ helm get manifest full-coral + +--- +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: mychart-configmap +data: + myvalue: "Hello World" +``` + +The `helm get manifest` command takes a release name (`full-coral`) and prints +out all of the Kubernetes resources that were uploaded to the server. Each file +begins with `---` to indicate the start of a YAML document, and then is followed +by an automatically generated comment line that tells us what template file +generated this YAML document. + +From there on, we can see that the YAML data is exactly what we put in our +`configmap.yaml` file. + +Now we can uninstall our release: `helm uninstall full-coral`. + +### Adding a Simple Template Call + +Hard-coding the `name:` into a resource is usually considered to be bad +practice. Names should be unique to a release. So we might want to generate a +name field by inserting the release name. + +**TIP:** The `name:` field is limited to 63 characters because of limitations to +the DNS system. For that reason, release names are limited to 53 characters. +Kubernetes 1.3 and earlier limited to only 24 characters (thus 14 character +names). + +Let's alter `configmap.yaml` accordingly. + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" +``` + +The big change comes in the value of the `name:` field, which is now +`{{ .Release.Name }}-configmap`. + +> A template directive is enclosed in `{{` and `}}` blocks. + +The template directive `{{ .Release.Name }}` injects the release name into the +template. The values that are passed into a template can be thought of as +_namespaced objects_, where a dot (`.`) separates each namespaced element. + +The leading dot before `Release` indicates that we start with the top-most +namespace for this scope (we'll talk about scope in a bit). So we could read +`.Release.Name` as "start at the top namespace, find the `Release` object, then +look inside of it for an object called `Name`". + +The `Release` object is one of the built-in objects for Helm, and we'll cover it +in more depth later. But for now, it is sufficient to say that this will display +the release name that the library assigns to our release. + +Now when we install our resource, we'll immediately see the result of using this +template directive: + +```console +$ helm install clunky-serval ./mychart +NAME: clunky-serval +LAST DEPLOYED: Tue Nov 1 17:45:37 2016 +NAMESPACE: default +STATUS: DEPLOYED +REVISION: 1 +TEST SUITE: None +``` + +You can run `helm get manifest clunky-serval` to see the entire generated YAML. + +Note that the config map inside kubernetes name is `clunky-serval-configmap` +instead of `mychart-configmap` previously. + +At this point, we've seen templates at their most basic: YAML files that have +template directives embedded in `{{` and `}}`. In the next part, we'll take a +deeper look into templates. But before moving on, there's one quick trick that +can make building templates faster: When you want to test the template +rendering, but not actually install anything, you can use `helm install --debug +--dry-run goodly-guppy ./mychart`. This will render the templates. But instead +of installing the chart, it will return the rendered template to you so you can +see the output: + +```console +$ helm install --debug --dry-run goodly-guppy ./mychart +install.go:149: [debug] Original chart version: "" +install.go:166: [debug] CHART PATH: /Users/ninja/mychart + +NAME: goodly-guppy +LAST DEPLOYED: Thu Dec 26 17:24:13 2019 +NAMESPACE: default +STATUS: pending-install +REVISION: 1 +TEST SUITE: None +USER-SUPPLIED VALUES: +{} + +COMPUTED VALUES: +affinity: {} +fullnameOverride: "" +image: + pullPolicy: IfNotPresent + repository: nginx +imagePullSecrets: [] +ingress: + annotations: {} + enabled: false + hosts: + - host: chart-example.local + paths: [] + tls: [] +nameOverride: "" +nodeSelector: {} +podSecurityContext: {} +replicaCount: 1 +resources: {} +securityContext: {} +service: + port: 80 + type: ClusterIP +serviceAccount: + create: true + name: null +tolerations: [] + +HOOKS: +MANIFEST: +--- +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: goodly-guppy-configmap +data: + myvalue: "Hello World" + +``` + +Using `--dry-run` will make it easier to test your code, but it won't ensure +that Kubernetes itself will accept the templates you generate. It's best not to +assume that your chart will install just because `--dry-run` works. + +In the [Chart Template Guide](_index.md), we take the basic chart we defined +here and explore the Helm template language in detail. And we'll get started +with built-in objects. diff --git a/content/en/docs/chart_template_guide/helm_ignore_file.md b/content/en/docs/chart_template_guide/helm_ignore_file.md new file mode 100644 index 0000000000..623d428e63 --- /dev/null +++ b/content/en/docs/chart_template_guide/helm_ignore_file.md @@ -0,0 +1,64 @@ +--- +title: "The .helmignore file" +description: "The `.helmignore` file is used to specify files you don't want to include in your helm chart." +weight: 12 +--- + +The `.helmignore` file is used to specify files you don't want to include in +your helm chart. + +If this file exists, the `helm package` command will ignore all the files that +match the pattern specified in the `.helmignore` file while packaging your +application. + +This can help in avoiding unnecessary or sensitive files or directories from +being added in your helm chart. + +The `.helmignore` file supports Unix shell glob matching, relative path +matching, and negation (prefixed with !). Only one pattern per line is +considered. + +Here is an example `.helmignore` file: + +``` +# comment + +# Match any file or path named .helmignore +.helmignore + +# Match any file or path named .git +.git + +# Match any text file +*.txt + +# Match only directories named mydir +mydir/ + +# Match only text files in the top-level directory +/*.txt + +# Match only the file foo.txt in the top-level directory +/foo.txt + +# Match any file named ab.txt, ac.txt, or ad.txt +a[b-d].txt + +# Match any file under subdir matching temp* +*/temp* + +*/*/temp* +temp? +``` + +Some notable differences from .gitignore: +- The '**' syntax is not supported. +- The globbing library is Go's 'filepath.Match', not fnmatch(3) +- Trailing spaces are always ignored (there is no supported escape sequence) +- There is no support for '\!' as a special leading sequence. +- It does not exclude itself by default, you have to add an explicit entry for `.helmignore` + + +**We'd love your help** making this document better. To add, correct, or remove +information, [file an issue](https://github.com/helm/helm-www/issues) or send us a +pull request. diff --git a/content/en/docs/chart_template_guide/named_templates.md b/content/en/docs/chart_template_guide/named_templates.md new file mode 100644 index 0000000000..38a2aa68c9 --- /dev/null +++ b/content/en/docs/chart_template_guide/named_templates.md @@ -0,0 +1,351 @@ +--- +title: "Named Templates" +description: "How to define named templates." +weight: 9 +--- + +It is time to move beyond one template, and begin to create others. In this +section, we will see how to define _named templates_ in one file, and then use +them elsewhere. A _named template_ (sometimes called a _partial_ or a +_subtemplate_) is simply a template defined inside of a file, and given a name. +We'll see two ways to create them, and a few different ways to use them. + +In the [Flow Control](../control_structures) section we introduced three actions +for declaring and managing templates: `define`, `template`, and `block`. In this +section, we'll cover those three actions, and also introduce a special-purpose +`include` function that works similarly to the `template` action. + +An important detail to keep in mind when naming templates: **template names are +global**. If you declare two templates with the same name, whichever one is +loaded last will be the one used. Because templates in subcharts are compiled +together with top-level templates, you should be careful to name your templates +with _chart-specific names_. + +One popular naming convention is to prefix each defined template with the name +of the chart: `{{ define "mychart.labels" }}`. By using the specific chart name +as a prefix we can avoid any conflicts that may arise due to two different +charts that implement templates of the same name. + +This behavior also applies to different versions of a chart. If you have +`mychart` version `1.0.0` that defines a template one way, and a `mychart` +version `2.0.0` that modifies the existing named template, it will use the one +that was loaded last. You can work around this issue by also adding a version +in the name of the chart: `{{ define "mychart.v1.labels" }}` and +`{{ define "mychart.v2.labels" }}`. + +## Partials and `_` files + +So far, we've used one file, and that one file has contained a single template. +But Helm's template language allows you to create named embedded templates, that +can be accessed by name elsewhere. + +Before we get to the nuts-and-bolts of writing those templates, there is file +naming convention that deserves mention: + +* Most files in `templates/` are treated as if they contain Kubernetes manifests +* The `NOTES.txt` is one exception +* But files whose name begins with an underscore (`_`) are assumed to _not_ have + a manifest inside. These files are not rendered to Kubernetes object + definitions, but are available everywhere within other chart templates for + use. + +These files are used to store partials and helpers. In fact, when we first +created `mychart`, we saw a file called `_helpers.tpl`. That file is the default +location for template partials. + +## Declaring and using templates with `define` and `template` + +The `define` action allows us to create a named template inside of a template +file. Its syntax goes like this: + +```yaml +{{- define "MY.NAME" }} + # body of template here +{{- end }} +``` + +For example, we can define a template to encapsulate a Kubernetes block of +labels: + +```yaml +{{- define "mychart.labels" }} + labels: + generator: helm + date: {{ now | htmlDate }} +{{- end }} +``` + +Now we can embed this template inside of our existing ConfigMap, and then +include it with the `template` action: + +```yaml +{{- define "mychart.labels" }} + labels: + generator: helm + date: {{ now | htmlDate }} +{{- end }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap + {{- template "mychart.labels" }} +data: + myvalue: "Hello World" + {{- range $key, $val := .Values.favorite }} + {{ $key }}: {{ $val | quote }} + {{- end }} +``` + +When the template engine reads this file, it will store away the reference to +`mychart.labels` until `template "mychart.labels"` is called. Then it will +render that template inline. So the result will look like this: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: running-panda-configmap + labels: + generator: helm + date: 2016-11-02 +data: + myvalue: "Hello World" + drink: "coffee" + food: "pizza" +``` + +Note: a `define` does not produce output unless it is called with a template, +as in this example. + +Conventionally, Helm charts put these templates inside of a partials file, +usually `_helpers.tpl`. Let's move this function there: + +```yaml +{{/* Generate basic labels */}} +{{- define "mychart.labels" }} + labels: + generator: helm + date: {{ now | htmlDate }} +{{- end }} +``` + +By convention, `define` functions should have a simple documentation block +(`{{/* ... */}}`) describing what they do. + +Even though this definition is in `_helpers.tpl`, it can still be accessed in +`configmap.yaml`: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap + {{- template "mychart.labels" }} +data: + myvalue: "Hello World" + {{- range $key, $val := .Values.favorite }} + {{ $key }}: {{ $val | quote }} + {{- end }} +``` + +As mentioned above, **template names are global**. As a result of this, if two +templates are declared with the same name the last occurrence will be the one +that is used. Since templates in subcharts are compiled together with top-level +templates, it is best to name your templates with _chart specific names_. A +popular naming convention is to prefix each defined template with the name of +the chart: `{{ define "mychart.labels" }}`. + +## Setting the scope of a template + +In the template we defined above, we did not use any objects. We just used +functions. Let's modify our defined template to include the chart name and chart +version: + +```yaml +{{/* Generate basic labels */}} +{{- define "mychart.labels" }} + labels: + generator: helm + date: {{ now | htmlDate }} + chart: {{ .Chart.Name }} + version: {{ .Chart.Version }} +{{- end }} +``` + +If we render this, we will get an error like this: + +```console +$ helm install --dry-run moldy-jaguar ./mychart +Error: unable to build kubernetes objects from release manifest: error validating "": error validating data: [unknown object type "nil" in ConfigMap.metadata.labels.chart, unknown object type "nil" in ConfigMap.metadata.labels.version] +``` + +To see what rendered, re-run with `--disable-openapi-validation`: +`helm install --dry-run --disable-openapi-validation moldy-jaguar ./mychart`. +The result will not be what we expect: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: moldy-jaguar-configmap + labels: + generator: helm + date: 2021-03-06 + chart: + version: +``` + +What happened to the name and version? They weren't in the scope for our defined +template. When a named template (created with `define`) is rendered, it will +receive the scope passed in by the `template` call. In our example, we included +the template like this: + +```yaml +{{- template "mychart.labels" }} +``` + +No scope was passed in, so within the template we cannot access anything in `.`. +This is easy enough to fix, though. We simply pass a scope to the template: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap + {{- template "mychart.labels" . }} +``` + +Note that we pass `.` at the end of the `template` call. We could just as easily +pass `.Values` or `.Values.favorite` or whatever scope we want. But what we want +is the top-level scope. + +Now when we execute this template with `helm install --dry-run --debug +plinking-anaco ./mychart`, we get this: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: plinking-anaco-configmap + labels: + generator: helm + date: 2021-03-06 + chart: mychart + version: 0.1.0 +``` + +Now `{{ .Chart.Name }}` resolves to `mychart`, and `{{ .Chart.Version }}` +resolves to `0.1.0`. + +## The `include` function + +Say we've defined a simple template that looks like this: + +```yaml +{{- define "mychart.app" -}} +app_name: {{ .Chart.Name }} +app_version: "{{ .Chart.Version }}" +{{- end -}} +``` + +Now say I want to insert this both into the `labels:` section of my template, +and also the `data:` section: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap + labels: + {{ template "mychart.app" . }} +data: + myvalue: "Hello World" + {{- range $key, $val := .Values.favorite }} + {{ $key }}: {{ $val | quote }} + {{- end }} +{{ template "mychart.app" . }} +``` + +If we render this, we will get an error like this: + +```console +$ helm install --dry-run measly-whippet ./mychart +Error: unable to build kubernetes objects from release manifest: error validating "": error validating data: [ValidationError(ConfigMap): unknown field "app_name" in io.k8s.api.core.v1.ConfigMap, ValidationError(ConfigMap): unknown field "app_version" in io.k8s.api.core.v1.ConfigMap] +``` + +To see what rendered, re-run with `--disable-openapi-validation`: +`helm install --dry-run --disable-openapi-validation measly-whippet ./mychart`. +The output will not be what we expect: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: measly-whippet-configmap + labels: + app_name: mychart +app_version: "0.1.0" +data: + myvalue: "Hello World" + drink: "coffee" + food: "pizza" +app_name: mychart +app_version: "0.1.0" +``` + +Note that the indentation on `app_version` is wrong in both places. Why? Because +the template that is substituted in has the text aligned to the left. Because +`template` is an action, and not a function, there is no way to pass the output +of a `template` call to other functions; the data is simply inserted inline. + +To work around this case, Helm provides an alternative to `template` that will +import the contents of a template into the present pipeline where it can be +passed along to other functions in the pipeline. + +Here's the example above, corrected to use `indent` to indent the `mychart.app` +template correctly: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap + labels: +{{ include "mychart.app" . | indent 4 }} +data: + myvalue: "Hello World" + {{- range $key, $val := .Values.favorite }} + {{ $key }}: {{ $val | quote }} + {{- end }} +{{ include "mychart.app" . | indent 2 }} +``` + +Now the produced YAML is correctly indented for each section: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: edgy-mole-configmap + labels: + app_name: mychart + app_version: "0.1.0" +data: + myvalue: "Hello World" + drink: "coffee" + food: "pizza" + app_name: mychart + app_version: "0.1.0" +``` + +> It is considered preferable to use `include` over `template` in Helm templates +> simply so that the output formatting can be handled better for YAML documents. + +Sometimes we want to import content, but not as templates. That is, we want to +import files verbatim. We can achieve this by accessing files through the +`.Files` object described in the next section. diff --git a/content/en/docs/chart_template_guide/notes_files.md b/content/en/docs/chart_template_guide/notes_files.md new file mode 100644 index 0000000000..f319f92151 --- /dev/null +++ b/content/en/docs/chart_template_guide/notes_files.md @@ -0,0 +1,57 @@ +--- +title: "Creating a NOTES.txt File" +description: "How to provide instructions to your Chart users." +weight: 10 +--- + +In this section we are going to look at Helm's tool for providing instructions +to your chart users. At the end of a `helm install` or `helm upgrade`, Helm can +print out a block of helpful information for users. This information is highly +customizable using templates. + +To add installation notes to your chart, simply create a `templates/NOTES.txt` +file. This file is plain text, but it is processed like a template, and has +all the normal template functions and objects available. + +Let's create a simple `NOTES.txt` file: + +``` +Thank you for installing {{ .Chart.Name }}. + +Your release is named {{ .Release.Name }}. + +To learn more about the release, try: + + $ helm status {{ .Release.Name }} + $ helm get all {{ .Release.Name }} + +``` + +Now if we run `helm install rude-cardinal ./mychart` we will see this message at +the bottom: + +``` +RESOURCES: +==> v1/Secret +NAME TYPE DATA AGE +rude-cardinal-secret Opaque 1 0s + +==> v1/ConfigMap +NAME DATA AGE +rude-cardinal-configmap 3 0s + + +NOTES: +Thank you for installing mychart. + +Your release is named rude-cardinal. + +To learn more about the release, try: + + $ helm status rude-cardinal + $ helm get all rude-cardinal +``` + +Using `NOTES.txt` this way is a great way to give your users detailed +information about how to use their newly installed chart. Creating a `NOTES.txt` +file is strongly recommended, though it is not required. diff --git a/content/en/docs/chart_template_guide/subcharts_and_globals.md b/content/en/docs/chart_template_guide/subcharts_and_globals.md new file mode 100644 index 0000000000..2f9e8300b7 --- /dev/null +++ b/content/en/docs/chart_template_guide/subcharts_and_globals.md @@ -0,0 +1,246 @@ +--- +title: "Subcharts and Global Values" +description: "Interacting with a subchart's and global values." +weight: 11 +--- + +To this point we have been working only with one chart. But charts can have +dependencies, called _subcharts_, that also have their own values and templates. +In this section we will create a subchart and see the different ways we can +access values from within templates. + +Before we dive into the code, there are a few important details to learn about application subcharts. + +1. A subchart is considered "stand-alone", which means a subchart can never + explicitly depend on its parent chart. +2. For that reason, a subchart cannot access the values of its parent. +3. A parent chart can override values for subcharts. +4. Helm has a concept of _global values_ that can be accessed by all charts. + +> These limitations do not all necessarily apply to [library charts]({{< ref +"/docs/topics/library_charts.md" >}}), which are designed to provide standardized helper functionality. + +As we walk through the examples in this section, many of these concepts will +become clearer. + +## Creating a Subchart + +For these exercises, we'll start with the `mychart/` chart we created at the +beginning of this guide, and we'll add a new chart inside of it. + +```console +$ cd mychart/charts +$ helm create mysubchart +Creating mysubchart +$ rm -rf mysubchart/templates/* +``` + +Notice that just as before, we deleted all of the base templates so that we can +start from scratch. In this guide, we are focused on how templates work, not on +managing dependencies. But the [Charts Guide]({{< ref "../topics/charts.md" >}}) +has more information on how subcharts work. + +## Adding Values and a Template to the Subchart + +Next, let's create a simple template and values file for our `mysubchart` chart. +There should already be a `values.yaml` in `mychart/charts/mysubchart`. We'll +set it up like this: + +```yaml +dessert: cake +``` + +Next, we'll create a new ConfigMap template in +`mychart/charts/mysubchart/templates/configmap.yaml`: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-cfgmap2 +data: + dessert: {{ .Values.dessert }} +``` + +Because every subchart is a _stand-alone chart_, we can test `mysubchart` on its +own: + +```console +$ helm install --generate-name --dry-run --debug mychart/charts/mysubchart +SERVER: "localhost:44134" +CHART PATH: /Users/mattbutcher/Code/Go/src/helm.sh/helm/_scratch/mychart/charts/mysubchart +NAME: newbie-elk +TARGET NAMESPACE: default +CHART: mysubchart 0.1.0 +MANIFEST: +--- +# Source: mysubchart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: newbie-elk-cfgmap2 +data: + dessert: cake +``` + +## Overriding Values from a Parent Chart + +Our original chart, `mychart` is now the _parent_ chart of `mysubchart`. This +relationship is based entirely on the fact that `mysubchart` is within +`mychart/charts`. + +Because `mychart` is a parent, we can specify configuration in `mychart` and +have that configuration pushed into `mysubchart`. For example, we can modify +`mychart/values.yaml` like this: + +```yaml +favorite: + drink: coffee + food: pizza +pizzaToppings: + - mushrooms + - cheese + - peppers + - onions + +mysubchart: + dessert: ice cream +``` + +Note the last two lines. Any directives inside of the `mysubchart` section will +be sent to the `mysubchart` chart. So if we run `helm install --dry-run --debug +mychart`, one of the things we will see is the `mysubchart` ConfigMap: + +```yaml +# Source: mychart/charts/mysubchart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: unhinged-bee-cfgmap2 +data: + dessert: ice cream +``` + +The value at the top level has now overridden the value of the subchart. + +There's an important detail to notice here. We didn't change the template of +`mychart/charts/mysubchart/templates/configmap.yaml` to point to +`.Values.mysubchart.dessert`. From that template's perspective, the value is +still located at `.Values.dessert`. As the template engine passes values along, +it sets the scope. So for the `mysubchart` templates, only values specifically +for `mysubchart` will be available in `.Values`. + +Sometimes, though, you do want certain values to be available to all of the +templates. This is accomplished using global chart values. + +## Global Chart Values + +Global values are values that can be accessed from any chart or subchart by +exactly the same name. Globals require explicit declaration. You can't use an +existing non-global as if it were a global. + +The Values data type has a reserved section called `Values.global` where global +values can be set. Let's set one in our `mychart/values.yaml` file. + +```yaml +favorite: + drink: coffee + food: pizza +pizzaToppings: + - mushrooms + - cheese + - peppers + - onions + +mysubchart: + dessert: ice cream + +global: + salad: caesar +``` + +Because of the way globals work, both `mychart/templates/configmap.yaml` and +`mysubchart/templates/configmap.yaml` should be able to access that value as +`{{ .Values.global.salad }}`. + +`mychart/templates/configmap.yaml`: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + salad: {{ .Values.global.salad }} +``` + +`mysubchart/templates/configmap.yaml`: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-cfgmap2 +data: + dessert: {{ .Values.dessert }} + salad: {{ .Values.global.salad }} +``` + +Now if we run a dry run install, we'll see the same value in both outputs: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: silly-snake-configmap +data: + salad: caesar + +--- +# Source: mychart/charts/mysubchart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: silly-snake-cfgmap2 +data: + dessert: ice cream + salad: caesar +``` + +Globals are useful for passing information like this, though it does take some +planning to make sure the right templates are configured to use globals. + +## Sharing Templates with Subcharts + +Parent charts and subcharts can share templates. Any defined block in any chart +is available to other charts. + +For example, we can define a simple template like this: + +```yaml +{{- define "labels" }}from: mychart{{ end }} +``` + +Recall how the labels on templates are _globally shared_. Thus, the `labels` +chart can be included from any other chart. + +While chart developers have a choice between `include` and `template`, one +advantage of using `include` is that `include` can dynamically reference +templates: + +```yaml +{{ include $mytemplate }} +``` + +The above will dereference `$mytemplate`. The `template` function, in contrast, +will only accept a string literal. + +## Avoid Using Blocks + +The Go template language provides a `block` keyword that allows developers to +provide a default implementation which is overridden later. In Helm charts, +blocks are not the best tool for overriding because if multiple implementations +of the same block are provided, the one selected is unpredictable. + +The suggestion is to instead use `include`. diff --git a/content/en/docs/chart_template_guide/values_files.md b/content/en/docs/chart_template_guide/values_files.md new file mode 100644 index 0000000000..f8e6fc54e4 --- /dev/null +++ b/content/en/docs/chart_template_guide/values_files.md @@ -0,0 +1,184 @@ +--- +title: "Values Files" +description: "Instructions on how to use the --values flag." +weight: 4 +--- + +In the previous section we looked at the built-in objects that Helm templates +offer. One of the built-in objects is `Values`. This object provides access to +values passed into the chart. Its contents come from multiple sources: + +- The `values.yaml` file in the chart +- If this is a subchart, the `values.yaml` file of a parent chart +- A values file if passed into `helm install` or `helm upgrade` with the `-f` + flag (`helm install -f myvals.yaml ./mychart`) +- Individual parameters passed with `--set` (such as `helm install --set foo=bar + ./mychart`) + +The list above is in order of specificity: `values.yaml` is the default, which +can be overridden by a parent chart's `values.yaml`, which can in turn be +overridden by a user-supplied values file, which can in turn be overridden by +`--set` parameters. + +Values files are plain YAML files. Let's edit `mychart/values.yaml` and then +edit our ConfigMap template. + +Removing the defaults in `values.yaml`, we'll set just one parameter: + +```yaml +favoriteDrink: coffee +``` + +Now we can use this inside of a template: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + drink: {{ .Values.favoriteDrink }} +``` + +Notice on the last line we access `favoriteDrink` as an attribute of `Values`: +`{{ .Values.favoriteDrink }}`. + +Let's see how this renders. + +```console +$ helm install geared-marsupi ./mychart --dry-run --debug +install.go:158: [debug] Original chart version: "" +install.go:175: [debug] CHART PATH: /home/bagratte/src/playground/mychart + +NAME: geared-marsupi +LAST DEPLOYED: Wed Feb 19 23:21:13 2020 +NAMESPACE: default +STATUS: pending-install +REVISION: 1 +TEST SUITE: None +USER-SUPPLIED VALUES: +{} + +COMPUTED VALUES: +favoriteDrink: coffee + +HOOKS: +MANIFEST: +--- +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: geared-marsupi-configmap +data: + myvalue: "Hello World" + drink: coffee +``` + +Because `favoriteDrink` is set in the default `values.yaml` file to `coffee`, +that's the value displayed in the template. We can easily override that by +adding a `--set` flag in our call to `helm install`: + +```console +$ helm install solid-vulture ./mychart --dry-run --debug --set favoriteDrink=slurm +install.go:158: [debug] Original chart version: "" +install.go:175: [debug] CHART PATH: /home/bagratte/src/playground/mychart + +NAME: solid-vulture +LAST DEPLOYED: Wed Feb 19 23:25:54 2020 +NAMESPACE: default +STATUS: pending-install +REVISION: 1 +TEST SUITE: None +USER-SUPPLIED VALUES: +favoriteDrink: slurm + +COMPUTED VALUES: +favoriteDrink: slurm + +HOOKS: +MANIFEST: +--- +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: solid-vulture-configmap +data: + myvalue: "Hello World" + drink: slurm +``` + +Since `--set` has a higher precedence than the default `values.yaml` file, our +template generates `drink: slurm`. + +Values files can contain more structured content, too. For example, we could +create a `favorite` section in our `values.yaml` file, and then add several keys +there: + +```yaml +favorite: + drink: coffee + food: pizza +``` + +Now we would have to modify the template slightly: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + drink: {{ .Values.favorite.drink }} + food: {{ .Values.favorite.food }} +``` + +While structuring data this way is possible, the recommendation is that you keep +your values trees shallow, favoring flatness. When we look at assigning values +to subcharts, we'll see how values are named using a tree structure. + +## Deleting a default key + +If you need to delete a key from the default values, you may override the value +of the key to be `null`, in which case Helm will remove the key from the +overridden values merge. + +For example, the stable Drupal chart allows configuring the liveness probe, in +case you configure a custom image. Here are the default values: +```yaml +livenessProbe: + httpGet: + path: /user/login + port: http + initialDelaySeconds: 120 +``` + +If you try to override the livenessProbe handler to `exec` instead of `httpGet` +using `--set livenessProbe.exec.command=[cat,docroot/CHANGELOG.txt]`, Helm will +coalesce the default and overridden keys together, resulting in the following +YAML: +```yaml +livenessProbe: + httpGet: + path: /user/login + port: http + exec: + command: + - cat + - docroot/CHANGELOG.txt + initialDelaySeconds: 120 +``` + +However, Kubernetes would then fail because you can not declare more than one +livenessProbe handler. To overcome this, you may instruct Helm to delete the +`livenessProbe.httpGet` by setting it to null: +```sh +helm install stable/drupal --set image=my-registry/drupal:0.1.0 --set livenessProbe.exec.command=[cat,docroot/CHANGELOG.txt] --set livenessProbe.httpGet=null +``` + +At this point, we've seen several built-in objects, and used them to inject +information into a template. Now we will take a look at another aspect of the +template engine: functions and pipelines. diff --git a/content/en/docs/chart_template_guide/variables.md b/content/en/docs/chart_template_guide/variables.md new file mode 100644 index 0000000000..2cf611e6ff --- /dev/null +++ b/content/en/docs/chart_template_guide/variables.md @@ -0,0 +1,156 @@ +--- +title: "Variables" +description: "Using variables in templates." +weight: 8 +--- + +With functions, pipelines, objects, and control structures under our belts, we +can turn to one of the more basic ideas in many programming languages: +variables. In templates, they are less frequently used. But we will see how to +use them to simplify code, and to make better use of `with` and `range`. + +In an earlier example, we saw that this code will fail: + +```yaml + {{- with .Values.favorite }} + drink: {{ .drink | default "tea" | quote }} + food: {{ .food | upper | quote }} + release: {{ .Release.Name }} + {{- end }} +``` + +`Release.Name` is not inside of the scope that's restricted in the `with` block. +One way to work around scoping issues is to assign objects to variables that can +be accessed without respect to the present scope. + +In Helm templates, a variable is a named reference to another object. It follows +the form `$name`. Variables are assigned with a special assignment operator: +`:=`. We can rewrite the above to use a variable for `Release.Name`. + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + {{- $relname := .Release.Name -}} + {{- with .Values.favorite }} + drink: {{ .drink | default "tea" | quote }} + food: {{ .food | upper | quote }} + release: {{ $relname }} + {{- end }} +``` + +Notice that before we start the `with` block, we assign `$relname := +.Release.Name`. Now inside of the `with` block, the `$relname` variable still +points to the release name. + +Running that will produce this: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: viable-badger-configmap +data: + myvalue: "Hello World" + drink: "coffee" + food: "PIZZA" + release: viable-badger +``` + +Variables are particularly useful in `range` loops. They can be used on +list-like objects to capture both the index and the value: + +```yaml + toppings: |- + {{- range $index, $topping := .Values.pizzaToppings }} + {{ $index }}: {{ $topping }} + {{- end }} + +``` + +Note that `range` comes first, then the variables, then the assignment operator, +then the list. This will assign the integer index (starting from zero) to +`$index` and the value to `$topping`. Running it will produce: + +```yaml + toppings: |- + 0: mushrooms + 1: cheese + 2: peppers + 3: onions +``` + +For data structures that have both a key and a value, we can use `range` to get +both. For example, we can loop through `.Values.favorite` like this: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + {{- range $key, $val := .Values.favorite }} + {{ $key }}: {{ $val | quote }} + {{- end }} +``` + +Now on the first iteration, `$key` will be `drink` and `$val` will be `coffee`, +and on the second, `$key` will be `food` and `$val` will be `pizza`. Running the +above will generate this: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: eager-rabbit-configmap +data: + myvalue: "Hello World" + drink: "coffee" + food: "pizza" +``` + +Variables are normally not "global". They are scoped to the block in which they +are declared. Earlier, we assigned `$relname` in the top level of the template. +That variable will be in scope for the entire template. But in our last example, +`$key` and `$val` will only be in scope inside of the `{{ range... }}{{ end }}` +block. + +However, there is one variable that is always global - `$` - this variable will +always point to the root context. This can be very useful when you are looping +in a range and you need to know the chart's release name. + +An example illustrating this: +```yaml +{{- range .Values.tlsSecrets }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ .name }} + labels: + # Many helm templates would use `.` below, but that will not work, + # however `$` will work here + app.kubernetes.io/name: {{ template "fullname" $ }} + # I cannot reference .Chart.Name, but I can do $.Chart.Name + helm.sh/chart: "{{ $.Chart.Name }}-{{ $.Chart.Version }}" + app.kubernetes.io/instance: "{{ $.Release.Name }}" + # Value from appVersion in Chart.yaml + app.kubernetes.io/version: "{{ $.Chart.AppVersion }}" + app.kubernetes.io/managed-by: "{{ $.Release.Service }}" +type: kubernetes.io/tls +data: + tls.crt: {{ .certificate }} + tls.key: {{ .key }} +--- +{{- end }} +``` + +So far we have looked at just one template declared in just one file. But one of +the powerful features of the Helm template language is its ability to declare +multiple templates and use them together. We'll turn to that in the next +section. diff --git a/content/en/docs/chart_template_guide/wrapping_up.md b/content/en/docs/chart_template_guide/wrapping_up.md new file mode 100644 index 0000000000..d481a697a8 --- /dev/null +++ b/content/en/docs/chart_template_guide/wrapping_up.md @@ -0,0 +1,43 @@ +--- +title: "Next Steps" +description: "Wrapping up - some useful pointers to other documentation that will help you." +weight: 14 +--- + +This guide is intended to give you, the chart developer, a strong understanding +of how to use Helm's template language. The guide focuses on the technical +aspects of template development. + +But there are many things this guide has not covered when it comes to the +practical day-to-day development of charts. Here are some useful pointers to +other documentation that will help you as you create new charts: + +- The CNCF [Artifact Hub](https://artifacthub.io/packages/search?kind=0) is an + indispensable source of charts. +- The Kubernetes [Documentation](https://kubernetes.io/docs/home/) provides + detailed examples of the various resource kinds that you can use, from + ConfigMaps and Secrets to DaemonSets and Deployments. +- The Helm [Charts Guide](../../topics/charts/) explains the workflow of using + charts. +- The Helm [Chart Hooks Guide](../../topics/charts_hooks/) explains how to + create lifecycle hooks. +- The Helm [Charts Tips and Tricks](../../howto/charts_tips_and_tricks/) article + provides some useful tips for writing charts. +- The [Sprig documentation](https://github.com/Masterminds/sprig) documents more + than sixty of the template functions. +- The [Go template docs](https://godoc.org/text/template) explain the template + syntax in detail. +- The [Schelm tool](https://github.com/databus23/schelm) is a nice helper + utility for debugging charts. + +Sometimes it's easier to ask a few questions and get answers from experienced +developers. The best place to do this is in the [Kubernetes +Slack](https://kubernetes.slack.com) Helm channels: + +- [#helm-users](https://kubernetes.slack.com/messages/helm-users) +- [#helm-dev](https://kubernetes.slack.com/messages/helm-dev) +- [#charts](https://kubernetes.slack.com/messages/charts) + +Finally, if you find errors or omissions in this document, want to suggest some +new content, or would like to contribute, visit [The Helm +Project](https://github.com/helm/helm-www). diff --git a/content/en/docs/chart_template_guide/yaml_techniques.md b/content/en/docs/chart_template_guide/yaml_techniques.md new file mode 100644 index 0000000000..c697fbab9a --- /dev/null +++ b/content/en/docs/chart_template_guide/yaml_techniques.md @@ -0,0 +1,355 @@ +--- +title: "Appendix: YAML Techniques" +description: "A closer look at the YAML specification and how it applies to Helm." +weight: 15 +--- + +Most of this guide has been focused on writing the template language. Here, +we'll look at the YAML format. YAML has some useful features that we, as +template authors, can use to make our templates less error prone and easier to +read. + +## Scalars and Collections + +According to the [YAML spec](https://yaml.org/spec/1.2/spec.html), there are two +types of collections, and many scalar types. + +The two types of collections are maps and sequences: + +```yaml +map: + one: 1 + two: 2 + three: 3 + +sequence: + - one + - two + - three +``` + +Scalar values are individual values (as opposed to collections) + +### Scalar Types in YAML + +In Helm's dialect of YAML, the scalar data type of a value is determined by a +complex set of rules, including the Kubernetes schema for resource definitions. +But when inferring types, the following rules tend to hold true. + +If an integer or float is an unquoted bare word, it is typically treated as a +numeric type: + +```yaml +count: 1 +size: 2.34 +``` + +But if they are quoted, they are treated as strings: + +```yaml +count: "1" # <-- string, not int +size: '2.34' # <-- string, not float +``` + +The same is true of booleans: + +```yaml +isGood: true # bool +answer: "true" # string +``` + +The word for an empty value is `null` (not `nil`). + +Note that `port: "80"` is valid YAML, and will pass through both the template +engine and the YAML parser, but will fail if Kubernetes expects `port` to be an +integer. + +In some cases, you can force a particular type inference using YAML node tags: + +```yaml +coffee: "yes, please" +age: !!str 21 +port: !!int "80" +``` + +In the above, `!!str` tells the parser that `age` is a string, even if it looks +like an int. And `port` is treated as an int, even though it is quoted. + + +## Strings in YAML + +Much of the data that we place in YAML documents are strings. YAML has more than +one way to represent a string. This section explains the ways and demonstrates +how to use some of them. + +There are three "inline" ways of declaring a string: + +```yaml +way1: bare words +way2: "double-quoted strings" +way3: 'single-quoted strings' +``` + +All inline styles must be on one line. + +- Bare words are unquoted, and are not escaped. For this reason, you have to be + careful what characters you use. +- Double-quoted strings can have specific characters escaped with `\`. For + example `"\"Hello\", she said"`. You can escape line breaks with `\n`. +- Single-quoted strings are "literal" strings, and do not use the `\` to escape + characters. The only escape sequence is `''`, which is decoded as a single + `'`. + +In addition to the one-line strings, you can declare multi-line strings: + +```yaml +coffee: | + Latte + Cappuccino + Espresso +``` + +The above will treat the value of `coffee` as a single string equivalent to +`Latte\nCappuccino\nEspresso\n`. + +Note that the first line after the `|` must be correctly indented. So we could +break the example above by doing this: + +```yaml +coffee: | + Latte + Cappuccino + Espresso + +``` + +Because `Latte` is incorrectly indented, we'd get an error like this: + +``` +Error parsing file: error converting YAML to JSON: yaml: line 7: did not find expected key +``` + +In templates, it is sometimes safer to put a fake "first line" of content in a +multi-line document just for protection from the above error: + +```yaml +coffee: | + # Commented first line + Latte + Cappuccino + Espresso + +``` + +Note that whatever that first line is, it will be preserved in the output of the +string. So if you are, for example, using this technique to inject a file's +contents into a ConfigMap, the comment should be of the type expected by +whatever is reading that entry. + +### Controlling Spaces in Multi-line Strings + +In the example above, we used `|` to indicate a multi-line string. But notice +that the content of our string was followed with a trailing `\n`. If we want the +YAML processor to strip off the trailing newline, we can add a `-` after the +`|`: + +```yaml +coffee: |- + Latte + Cappuccino + Espresso +``` + +Now the `coffee` value will be: `Latte\nCappuccino\nEspresso` (with no trailing +`\n`). + +Other times, we might want all trailing whitespace to be preserved. We can do +this with the `|+` notation: + +```yaml +coffee: |+ + Latte + Cappuccino + Espresso + + +another: value +``` + +Now the value of `coffee` will be `Latte\nCappuccino\nEspresso\n\n\n`. + +Indentation inside of a text block is preserved, and results in the preservation +of line breaks, too: + +```yaml +coffee: |- + Latte + 12 oz + 16 oz + Cappuccino + Espresso +``` + +In the above case, `coffee` will be `Latte\n 12 oz\n 16 +oz\nCappuccino\nEspresso`. + +### Indenting and Templates + +When writing templates, you may find yourself wanting to inject the contents of +a file into the template. As we saw in previous chapters, there are two ways of +doing this: + +- Use `{{ .Files.Get "FILENAME" }}` to get the contents of a file in the chart. +- Use `{{ include "TEMPLATE" . }}` to render a template and then place its + contents into the chart. + +When inserting files into YAML, it's good to understand the multi-line rules +above. Often times, the easiest way to insert a static file is to do something +like this: + +```yaml +myfile: | +{{ .Files.Get "myfile.txt" | indent 2 }} +``` + +Note how we do the indentation above: `indent 2` tells the template engine to +indent every line in "myfile.txt" with two spaces. Note that we do not indent +that template line. That's because if we did, the file content of the first line +would be indented twice. + +### Folded Multi-line Strings + +Sometimes you want to represent a string in your YAML with multiple lines, but +want it to be treated as one long line when it is interpreted. This is called +"folding". To declare a folded block, use `>` instead of `|`: + +```yaml +coffee: > + Latte + Cappuccino + Espresso + + +``` + +The value of `coffee` above will be `Latte Cappuccino Espresso\n`. Note that all +but the last line feed will be converted to spaces. You can combine the +whitespace controls with the folded text marker, so `>-` will replace or trim +all newlines. + +Note that in the folded syntax, indenting text will cause lines to be preserved. + +```yaml +coffee: >- + Latte + 12 oz + 16 oz + Cappuccino + Espresso +``` + +The above will produce `Latte\n 12 oz\n 16 oz\nCappuccino Espresso`. Note that +both the spacing and the newlines are still there. + +## Embedding Multiple Documents in One File + +It is possible to place more than one YAML documents into a single file. This is +done by prefixing a new document with `---` and ending the document with +`...` + +```yaml + +--- +document:1 +... +--- +document: 2 +... +``` + +In many cases, either the `---` or the `...` may be omitted. + +Some files in Helm cannot contain more than one doc. If, for example, more than +one document is provided inside of a `values.yaml` file, only the first will be +used. + +Template files, however, may have more than one document. When this happens, the +file (and all of its documents) is treated as one object during template +rendering. But then the resulting YAML is split into multiple documents before +it is fed to Kubernetes. + +We recommend only using multiple documents per file when it is absolutely +necessary. Having multiple documents in a file can be difficult to debug. + +## YAML is a Superset of JSON + +Because YAML is a superset of JSON, any valid JSON document _should_ be valid +YAML. + +```json +{ + "coffee": "yes, please", + "coffees": [ + "Latte", "Cappuccino", "Espresso" + ] +} +``` + +The above is another way of representing this: + +```yaml +coffee: yes, please +coffees: +- Latte +- Cappuccino +- Espresso +``` + +And the two can be mixed (with care): + +```yaml +coffee: "yes, please" +coffees: [ "Latte", "Cappuccino", "Espresso"] +``` + +All three of these should parse into the same internal representation. + +While this means that files such as `values.yaml` may contain JSON data, Helm +does not treat the file extension `.json` as a valid suffix. + +## YAML Anchors + +The YAML spec provides a way to store a reference to a value, and later refer to +that value by reference. YAML refers to this as "anchoring": + +```yaml +coffee: "yes, please" +favorite: &favoriteCoffee "Cappuccino" +coffees: + - Latte + - *favoriteCoffee + - Espresso +``` + +In the above, `&favoriteCoffee` sets a reference to `Cappuccino`. Later, that +reference is used as `*favoriteCoffee`. So `coffees` becomes `Latte, Cappuccino, +Espresso`. + +While there are a few cases where anchors are useful, there is one aspect of +them that can cause subtle bugs: The first time the YAML is consumed, the +reference is expanded and then discarded. + +So if we were to decode and then re-encode the example above, the resulting YAML +would be: + +```yaml +coffee: yes, please +favorite: Cappuccino +coffees: +- Latte +- Cappuccino +- Espresso +``` + +Because Helm and Kubernetes often read, modify, and then rewrite YAML files, the +anchors will be lost. diff --git a/content/en/docs/community/_index.md b/content/en/docs/community/_index.md new file mode 100644 index 0000000000..fb391d6b4a --- /dev/null +++ b/content/en/docs/community/_index.md @@ -0,0 +1,9 @@ +--- +title: "Community" +weight: 7 +--- + +# Community Guides + +Learn here about the development process for the Helm project itself and how you +can contribute. diff --git a/content/en/docs/community/developers.md b/content/en/docs/community/developers.md new file mode 100644 index 0000000000..8c77a37360 --- /dev/null +++ b/content/en/docs/community/developers.md @@ -0,0 +1,144 @@ +--- +title: "Developer Guide" +description: "Instructions for setting up your environment for developing Helm." +weight: 1 +aliases: ["/docs/developers/"] +--- + +This guide explains how to set up your environment for developing on Helm. + +## Prerequisites + +- The latest version of Go +- A Kubernetes cluster w/ kubectl (optional) +- Git + +## Building Helm + +We use Make to build our programs. The simplest way to get started is: + +```console +$ make +``` + +If required, this will first install dependencies and validate configuration. It will then compile `helm` and place it in +`bin/helm`. + +To run Helm locally, you can run `bin/helm`. + +- Helm is known to run on macOS and most Linux distributions, including Alpine. + +## Running tests + +To run all the tests, run `make test`. +As a pre-requisite, you would need to have +[golangci-lint](https://golangci-lint.run) +installed. + +## Contribution Guidelines + +We welcome contributions. This project has set up some guidelines in order to +ensure that (a) code quality remains high, (b) the project remains consistent, +and (c) contributions follow the open source legal requirements. Our intent is +not to burden contributors, but to build elegant and high-quality open source +code so that our users will benefit. + +Make sure you have read and understood the main CONTRIBUTING guide: + + + +### Structure of the Code + +The code for the Helm project is organized as follows: + +- The individual programs are located in `cmd/`. Code inside of `cmd/` is not + designed for library re-use. +- Shared libraries are stored in `pkg/`. +- The `scripts/` directory contains a number of utility scripts. Most of these + are used by the CI/CD pipeline. + +Go dependency management is in flux, and it is likely to change during the +course of Helm's lifecycle. We encourage developers to _not_ try to manually +manage dependencies. Instead, we suggest relying upon the project's `Makefile` +to do that for you. With Helm 3, it is recommended that you are on Go version +1.13 or later. + +### Writing Documentation + +Since Helm 3, documentation has been moved to its own repository. When writing +new features, please write accompanying documentation and submit it to the +[helm-www](https://github.com/helm/helm-www) repository. + +One exception: [Helm CLI output (in English)](https://helm.sh/docs/helm/) is +generated from the `helm` binary itself. See [Updating the Helm CLI Reference Docs](https://github.com/helm/helm-www#updating-the-helm-cli-reference-docs) +for instructions on how to generate this output. When translated, the CLI +output is not generated and can be found in `/content//docs/helm`. + +### Git Conventions + +We use Git for our version control system. The `main` branch is the home of +the current development candidate. Releases are tagged. + +We accept changes to the code via GitHub Pull Requests (PRs). One workflow for +doing this is as follows: + +1. Fork the `github.com/helm/helm` repository into your GitHub account +2. `git clone` the forked repository into your desired directory +3. Create a new working branch (`git checkout -b feat/my-feature`) and do your + work on that branch. +4. When you are ready for us to review, push your branch to GitHub, and then + open a new pull request with us. + +For Git commit messages, we follow the [Semantic Commit +Messages](https://karma-runner.github.io/0.13/dev/git-commit-msg.html): + +``` +fix(helm): add --foo flag to 'helm install' + +When 'helm install --foo bar' is run, this will print "foo" in the +output regardless of the outcome of the installation. + +Closes #1234 +``` + +Common commit types: + +- fix: Fix a bug or error +- feat: Add a new feature +- docs: Change documentation +- test: Improve testing +- ref: refactor existing code + +Common scopes: + +- helm: The Helm CLI +- pkg/lint: The lint package. Follow a similar convention for any package +- `*`: two or more scopes + +Read more: + +- The [Deis + Guidelines](https://github.com/deis/workflow/blob/master/src/contributing/submitting-a-pull-request.md) + were the inspiration for this section. +- Karma Runner + [defines](https://karma-runner.github.io/0.13/dev/git-commit-msg.html) the + semantic commit message idea. + +### Go Conventions + +We follow the Go coding style standards very closely. Typically, running `go +fmt` will make your code beautiful for you. + +We also typically follow the conventions recommended by `go lint` and +`gometalinter`. Run `make test-style` to test the style conformance. + +Read more: + +- Effective Go [introduces + formatting](https://golang.org/doc/effective_go.html#formatting). +- The Go Wiki has a great article on + [formatting](https://github.com/golang/go/wiki/CodeReviewComments). + +If you run the `make test` target, not only will unit tests be run, but so will +style tests. If the `make test` target fails, even for stylistic reasons, your +PR will not be considered ready for merging. diff --git a/content/en/docs/community/history.md b/content/en/docs/community/history.md new file mode 100644 index 0000000000..b92066cd9f --- /dev/null +++ b/content/en/docs/community/history.md @@ -0,0 +1,35 @@ +--- +title: "The History of the Project" +description: "Provides a high-level overview of the project's history." +aliases: ["/docs/history/"] +weight: 4 +--- + +Helm is a [graduated](https://helm.sh/blog/celebrating-helms-cncf-graduation/) +[CNCF project](https://www.cncf.io/projects/). + +Helm began as what is now known as [Helm +Classic](https://github.com/helm/helm-classic), a Deis project begun in 2015 and +introduced at the inaugural KubeCon. + +In January of 2016, the project merged with a GCS tool called Kubernetes +Deployment Manager, and the project was moved under +[Kubernetes](https://kubernetes.io). As a result of the merging of codebases, +Helm 2.0 was released later that year. The key feature of Deployment Manager +that survived in Helm 2 was the server-side component, renamed from DM to Tiller +for the final Helm 2.0 release. + +Helm was promoted from a Kubernetes subproject to a full-fledged CNCF project in +June, 2018. Helm formed a top-level governing body and several projects were +subsumed under the Helm project, including Monocular, the Helm Chart Repo, Chart +Museum, and later the Helm Hub. + +When the Helm 3 development cycle began, Tiller was removed, bringing Helm +closer to its original vision of being a client tool. But Helm 3 continues to +track releases inside of the Kubernetes cluster, making it possible for teams to +work together on a common set of Helm releases. Helm 3 was released in November 2019. + +Helm [graduated as a CNCF project in April 2020](https://www.cncf.io/announcement/2020/04/30/cloud-native-computing-foundation-announces-helm-graduation/). + +The CNCF [Artifact Hub](https://artifacthub.io) replaced the [Helm Hub](https://hub.helm.sh) +in October 2020. diff --git a/content/en/docs/community/localization.md b/content/en/docs/community/localization.md new file mode 100644 index 0000000000..efe92703a3 --- /dev/null +++ b/content/en/docs/community/localization.md @@ -0,0 +1,165 @@ +--- +title: "Localizing Helm Documentation" +description: "Instructions for localizing the Helm documentation." +aliases: ["/docs/localization/"] +weight: 5 +--- + +This guide explains how to localize the Helm documentation. + +## Getting Started + +Contributions for translations use the same process as contributions for +documentation. Translations are supplied through [pull +requests](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests) +to the [helm-www](https://github.com/helm/helm-www) git repository and pull +requests are reviewed by the team that manages the website. + +### Two-letter Language Code + +Documentation is organized by the [ISO 639-1 +standard](https://www.loc.gov/standards/iso639-2/php/code_list.php) for the +language codes. For example, the two-letter code for Korean is `ko`. + +In content and configuration you will find the language code in use. Here are 3 +examples: + +- In the `content` directory the language codes are the subdirectories and the + localized content for the language is in each directory. Primarily in the + `docs` subdirectory of each language code directory. +- The `i18n` directory contains a configuration file for each language with + phrases used on the website. The files are named with the pattern `[LANG].toml` + where `[LANG]` is the two letter language code. +- In the top level `config.toml` file there is configuration for navigation and + other details organized by language code. + +English, with a language code of `en`, is the default language and source for +translations. + +### Fork, Branch, Change, Pull Request + +To contribute translations start by [creating a +fork](https://help.github.com/en/github/getting-started-with-github/fork-a-repo) +of the [helm-www repository](https://github.com/helm/helm-www) on GitHub. You +will start by committing the changes to your fork. + +By default your fork will be set to work on the default branch known as `main`. +Please use branches to develop your changes and create pull requests. If you are +unfamiliar with branches you can [read about them in the GitHub +documentation](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-branches). + +Once you have a branch make changes to add translations and localize the content +to a language. + +Note, Helm uses a [Developers Certificate of +Origin](https://developercertificate.org/). All commits need to have signoff. +When making a commit you can use the `-s` or `--signoff` flag to use your Git +configured name and email address to signoff on the commit. More details are +available in the +[CONTRIBUTING.md](https://github.com/helm/helm-www/blob/main/CONTRIBUTING.md#sign-your-work) +file. + +When you are ready, create a [pull +request](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests) +with the translation back to the helm-www repository. + +Once a pull request has been created one of the maintainers will review it. +Details on that process are in the +[CONTRIBUTING.md](https://github.com/helm/helm-www/blob/main/CONTRIBUTING.md) +file. + +## Translating Content + +Localizing all of the Helm content is a large task. It is ok to start small. The +translations can be expanded over time. + +### Starting A New Language + +When starting a new language there is a minimum needed. This includes: + +- Adding a `content/[LANG]/docs` directory containing an `_index.md` file. This + is the top level documentation landing page. +- Creating a `[LANG].toml` file in the `i18n` directory. Initially you can copy + the `en.toml` file as a starting point. +- Adding a section for the language to the `config.toml` file to expose the new + language. An existing language section can serve as a starting point. + +### Translating + +Translated content needs to reside in the `content/[LANG]/docs` directory. It +should have the same URL as the English source. For example, to translate the +intro into Korean it can be useful to copy the english source like: + +```sh +mkdir -p content/ko/docs/intro +cp content/en/docs/intro/install.md content/ko/docs/intro/install.md +``` + +The content in the new file can then be translated into the other language. + +Do not add an untranslated copy of an English file to `content/[LANG]/`. +Once a language exists on the site, any untranslated pages will redirect to +English automatically. Translation takes time, and you always want to be +translating the most current version of the docs, not an outdated fork. + +Make sure you remove any `aliases` lines from the header section. A line like +`aliases: ["/docs/using_helm/"]` does not belong in the translations. Those +are redirections for old links which don't exist for new pages. + +Note, translation tools can help with the process. This includes machine +generated translations. Machine generated translations should be edited or +otherwise reviewing for grammar and meaning by a native language speaker before +publishing. + + +## Navigating Between Languages + +![Screen Shot 2020-05-11 at 11 24 22 +AM](https://user-images.githubusercontent.com/686194/81597103-035de600-937a-11ea-9834-cd9dcef4e914.png) + +The site global +[config.toml](https://github.com/helm/helm-www/blob/main/config.toml#L83L89) +file is where language navigation is configured. + +To add a new language, add a new set of parameters using the [two-letter +language code](./localization/#two-letter-language-code) defined above. Example: + +``` +# Korean +[languages.ko] +title = "Helm" +description = "Helm - The Kubernetes Package Manager." +contentDir = "content/ko" +languageName = "한국어 Korean" +weight = 1 +``` + +## Resolving Internal Links + +Translated content will sometimes include links to pages that only exist in +another language. This will result in site [build +errors](https://app.netlify.com/sites/helm-merge/deploys). Example: + +``` +12:45:31 PM: htmltest started at 12:45:30 on app +12:45:31 PM: ======================================================================== +12:45:31 PM: ko/docs/chart_template_guide/accessing_files/index.html +12:45:31 PM: hash does not exist --- ko/docs/chart_template_guide/accessing_files/index.html --> #basic-example +12:45:31 PM: ✘✘✘ failed in 197.566561ms +12:45:31 PM: 1 error in 212 documents +``` + +To resolve this, you need to check your content for internal links. + +* anchor links need to reflect the translated `id` value +* internal page links need to be fixed + +For internal pages that do not exist _(or have not been translated yet)_, the +site will not build until a correction is made. As a fallback, the url can point +to another language where that content _does_ exist as follows: + +`< relref path="/docs/topics/library_charts.md" lang="en" >` + +See the [Hugo Docs on cross references between +languages](https://gohugo.io/content-management/cross-references/#link-to-another-language-version) +for more info. diff --git a/content/en/docs/community/related.md b/content/en/docs/community/related.md new file mode 100644 index 0000000000..e4cab621a3 --- /dev/null +++ b/content/en/docs/community/related.md @@ -0,0 +1,124 @@ +--- +title: "Related Projects and Documentation" +description: "third-party tools, plugins and documentation provided by the community!" +weight: 3 +aliases: ["/docs/related/"] +--- + +The Helm community has produced many extra tools, plugins, and documentation +about Helm. We love to hear about these projects. + +If you have anything you'd like to add to this list, please open an +[issue](https://github.com/helm/helm-www/issues) or [pull +request](https://github.com/helm/helm-www/pulls). + +## Helm Plugins + +- [helm-adopt](https://github.com/HamzaZo/helm-adopt) - A helm v3 plugin to adopt + existing k8s resources into a new generated helm chart. +- [Helm Diff](https://github.com/databus23/helm-diff) - Preview `helm upgrade` + as a coloured diff +- [Helm Dashboard](https://github.com/komodorio/helm-dashboard) - GUI for Helm, visualize releases and repositories, manifest diffs +- [helm-gcs](https://github.com/hayorov/helm-gcs) - Plugin to manage repositories + on Google Cloud Storage +- [helm-git](https://github.com/aslafy-z/helm-git) - Install charts and retrieve + values files from your Git repositories +- [helm-k8comp](https://github.com/cststack/k8comp) - Plugin to create Helm + Charts from hiera using k8comp +- [helm-mapkubeapis](https://github.com/helm/helm-mapkubeapis) - Update helm release + metadata to replace deprecated or removed Kubernetes APIs +- [helm-monitor](https://github.com/ContainerSolutions/helm-monitor) - Plugin to + monitor a release and rollback based on Prometheus/ElasticSearch query +- [helm-release-plugin](https://github.com/JovianX/helm-release-plugin) - Plugin for Release management, Update release values, pulls(re-creates) helm Charts from deployed releases, set helm release TTL. +- [helm-s3](https://github.com/hypnoglow/helm-s3) - Helm plugin that allows to + use AWS S3 as a [private] chart repository +- [helm-schema-gen](https://github.com/karuppiah7890/helm-schema-gen) - Helm + Plugin that generates values yaml schema for your Helm 3 charts +- [helm-secrets](https://github.com/jkroepke/helm-secrets) - Plugin to manage + and store secrets safely (based on [sops](https://github.com/mozilla/sops)) +- [helm-sigstore](https://github.com/sigstore/helm-sigstore) - + Plugin for Helm to integrate the [sigstore](https://sigstore.dev/) ecosystem. Search, upload and verify signed Helm charts. +- [helm-tanka](https://github.com/Duologic/helm-tanka) - A Helm plugin for + rendering Tanka/Jsonnet inside Helm charts. +- [hc-unit](https://github.com/xchapter7x/hcunit) - Plugin for unit testing + charts locally using OPA (Open Policy Agent) & Rego +- [helm-unittest](https://github.com/quintush/helm-unittest) - Plugin for unit + testing chart locally with YAML +- [helm-val](https://github.com/HamzaZo/helm-val) - A plugin to get + values from a previous release. +- [helm-external-val](https://github.com/kuuji/helm-external-val) - A plugin that fetches helm values from external sources (configMaps, Secrets, etc) + +We also encourage GitHub authors to use the +[helm-plugin](https://github.com/search?q=topic%3Ahelm-plugin&type=Repositories) +tag on their plugin repositories. + +## Additional Tools + +Tools layered on top of Helm. + +- [Armada](https://airshipit.readthedocs.io/projects/armada/en/latest/) - Manage + prefixed releases throughout various Kubernetes namespaces, and removes + completed jobs for complex deployments +- [avionix](https://github.com/zbrookle/avionix) - + Python interface for generating Helm + charts and Kubernetes yaml, allowing for inheritance and less duplication of code +- [Botkube](https://botkube.io) - Run Helm commands directly from Slack, + Discord, Microsoft Teams, and Mattermost. +- [Captain](https://github.com/alauda/captain) - A Helm3 Controller using + HelmRequest and Release CRD +- [Chartify](https://github.com/appscode/chartify) - Generate Helm charts from + existing Kubernetes resources. +- [ChartMuseum](https://github.com/helm/chartmuseum) - Helm Chart Repository + with support for Amazon S3 and Google Cloud Storage +- [chart-registry](https://github.com/hangyan/chart-registry) - Helm Charts + Hosts on OCI Registry +- [Codefresh](https://codefresh.io) - Kubernetes native CI/CD and management + platform with UI dashboards for managing Helm charts and releases +- [Flux](https://fluxcd.io/docs/components/helm/) - + Continuous and progressive delivery from Git to Kubernetes. +- [Helmfile](https://github.com/helmfile/helmfile) - Helmfile is a declarative + spec for deploying helm charts +- [Helmsman](https://github.com/Praqma/helmsman) - Helmsman is a + helm-charts-as-code tool which enables + installing/upgrading/protecting/moving/deleting releases from version + controlled desired state files (described in a simple TOML format) +- [Konveyor Move2Kube](https://konveyor.io/move2kube/) - + Generate Helm charts for your + existing projects. +- [Landscaper](https://github.com/Eneco/landscaper/) - "Landscaper takes a set + of Helm Chart references with values (a desired state), and realizes this in a + Kubernetes cluster." +- [Monocular](https://github.com/helm/monocular) - Web UI for Helm Chart + repositories +- [Monokle](https://monokle.io) - Desktop tool for creating, debugging and deploying Kubernetes resources and Helm Charts +- [Orkestra](https://azure.github.io/orkestra/) - A cloud-native Release + Orchestration and Lifecycle Management (LCM) platform for a related group of + Helm releases and their subcharts +- [Tanka](https://tanka.dev/helm) - Grafana Tanka configures Kubernetes + resources through Jsonnet with the ability to consume Helm Charts +- [Terraform Helm + Provider](https://github.com/hashicorp/terraform-provider-helm) - The Helm + provider for HashiCorp Terraform enables lifecycle management of Helm Charts + with a declarative infrastructure-as-code syntax. The Helm provider is often + paired the other Terraform providers, like the Kubernetes provider, to create + a common workflow across all infrastructure services. +- [VIM-Kubernetes](https://github.com/andrewstuart/vim-kubernetes) - VIM plugin + for Kubernetes and Helm + +## Helm Included + +Platforms, distributions, and services that include Helm support. + +- [Kubernetic](https://kubernetic.com/) - Kubernetes Desktop Client +- [Jenkins X](https://jenkins-x.io/) - open source automated CI/CD for + Kubernetes which uses Helm for + [promoting](https://jenkins-x.io/docs/getting-started/promotion/) applications + through environments via GitOps + +## Misc + +Grab bag of useful things for Chart authors and Helm users. + +- [Await](https://github.com/saltside/await) - Docker image to "await" different + conditions--especially useful for init containers. [More + Info](https://blog.slashdeploy.com/2017/02/16/introducing-await/) diff --git a/content/en/docs/community/release_checklist.md b/content/en/docs/community/release_checklist.md new file mode 100644 index 0000000000..b0a42cee76 --- /dev/null +++ b/content/en/docs/community/release_checklist.md @@ -0,0 +1,490 @@ +--- +title: "Release Checklist" +description: "Checklist for maintainers when releasing the next version of Helm." +weight: 2 +--- + +# A Maintainer's Guide to Releasing Helm + +Time for a new Helm release! As a Helm maintainer cutting a release, you are +the best person to [update this +release checklist](https://github.com/helm/helm-www/blob/main/content/en/docs/community/release_checklist.md) +should your experiences vary from what's documented here. + +All releases will be of the form vX.Y.Z where X is the major version number, Y +is the minor version number and Z is the patch release number. This project +strictly follows [semantic versioning](https://semver.org/) so following this +step is critical. + +Helm announces in advance the date of its next minor release. Every effort +should be made to respect the announced date. Furthermore, when starting +the release process, the date for the next release should have been selected +as it will be used in the release process. + +These directions will cover initial configuration followed by the release +process for three different kinds of releases: + +* Major Releases - released less frequently - have breaking changes +* Minor Releases - released every 3 to 4 months - no breaking changes +* Patch Releases - released monthly - do not require all steps in this guide + +[Initial Configuration](#initial-configuration) + +1. [Create the Release Branch](#1-create-the-release-branch) +2. [Major/Minor releases: Change the Version Number in Git](#2-majorminor-releases-change-the-version-number-in-git) +3. [Major/Minor releases: Commit and Push the Release Branch](#3-majorminor-releases-commit-and-push-the-release-branch) +4. [Major/Minor releases: Create a Release Candidate](#4-majorminor-releases-create-a-release-candidate) +5. [Major/Minor releases: Iterate on Successive Release Candidates](#5-majorminor-releases-iterate-on-successive-release-candidates) +6. [Finalize the Release](#6-finalize-the-release) +7. [Write the Release Notes](#7-write-the-release-notes) +8. [PGP Sign the downloads](#8-pgp-sign-the-downloads) +9. [Publish Release](#9-publish-release) +10. [Update Docs](#10-update-docs) +11. [Tell the Community](#11-tell-the-community) + +## Initial Configuration + +### Set Up Git Remote + +It is important to note that this document assumes that the git remote in your +repository that corresponds to is named +"upstream". If yours is not (for example, if you've chosen to name it "origin" +or something similar instead), be sure to adjust the listed snippets for your +local environment accordingly. If you are not sure what your upstream remote is +named, use a command like `git remote -v` to find out. + +If you don't have an [upstream +remote](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/configuring-a-remote-for-a-fork) +, you can add one using something like: + +```shell +git remote add upstream git@github.com:helm/helm.git +``` + +### Set Up Environment Variables + +In this doc, we are going to reference a few environment variables as well, +which you may want to set for convenience. For major/minor releases, use the +following: + +```shell +export RELEASE_NAME=vX.Y.0 +export RELEASE_BRANCH_NAME="release-X.Y" +export RELEASE_CANDIDATE_NAME="$RELEASE_NAME-rc.1" +``` + +If you are creating a patch release, use the following instead: + +```shell +export PREVIOUS_PATCH_RELEASE=vX.Y.Z +export RELEASE_NAME=vX.Y.Z+1 +export RELEASE_BRANCH_NAME="release-X.Y" +``` + +### Set Up Signing Key + +We are also going to be adding security and verification of the release process +by hashing the binaries and providing signature files. We perform this using +[GitHub and +GPG](https://help.github.com/en/articles/about-commit-signature-verification). +If you do not have GPG already setup you can follow these steps: + +1. [Install GPG](https://gnupg.org/index.html) +2. [Generate GPG + key](https://help.github.com/en/articles/generating-a-new-gpg-key) +3. [Add key to GitHub + account](https://help.github.com/en/articles/adding-a-new-gpg-key-to-your-github-account) +4. [Set signing key in + Git](https://help.github.com/en/articles/telling-git-about-your-signing-key) + +Once you have a signing key you need to add it to the KEYS file at the root of +the repository. The instructions for adding it to the KEYS file are in the file. +If you have not done so already, you need to add your public key to the +keyserver network. If you use GnuPG you can follow the [instructions provided by +Debian](https://debian-administration.org/article/451/Submitting_your_GPG_key_to_a_keyserver). + +## 1. Create the Release Branch + +### Major/Minor Releases + +Major releases are for new feature additions and behavioral changes *that break +backwards compatibility*. Minor releases are for new feature additions that do +not break backwards compatibility. To create a major or minor release, start by +creating a `release-X.Y` branch from main. + +```shell +git fetch upstream +git checkout upstream/main +git checkout -b $RELEASE_BRANCH_NAME +``` + +This new branch is going to be the base for the release, which we are going to +iterate upon later. + +Verify that a [helm/helm milestone](https://github.com/helm/helm/milestones) +for the release exists on GitHub (creating it if necessary). Make sure PRs and +issues for this release are in this milestone. + +For major & minor releases, move on to step 2: [Major/Minor releases: Change +the Version Number in Git](#2-majorminor-releases-change-the-version-number-in-git). + +### Patch releases + +Patch releases are a few critical cherry-picked fixes to existing releases. +Start by creating a `release-X.Y` branch: + +```shell +git fetch upstream +git checkout -b $RELEASE_BRANCH_NAME upstream/$RELEASE_BRANCH_NAME +``` + +From here, we can cherry-pick the commits we want to bring into the patch +release: + +```shell +# get the commits ids we want to cherry-pick +git log --oneline +# cherry-pick the commits starting from the oldest one, without including merge commits +git cherry-pick -x +``` + +After the commits have been cherry picked the release branch needs to be pushed. + +```shell +git push upstream $RELEASE_BRANCH_NAME +``` + +Pushing the branch will cause the tests to run. Make sure they pass prior to +creating the tag. This new tag is going to be the base for the patch release. + +Creating a [helm/helm +milestone](https://github.com/helm/helm/milestones) is optional for patch +releases. + +Make sure to check [helm on CircleCI](https://circleci.com/gh/helm/helm) to see +that the release passed CI before proceeding. Patch releases can skip steps 2-5 +and proceed to step 6 to [Finalize the Release](#6-finalize-the-release). + +## 2. Major/Minor releases: Change the Version Number in Git + +When doing a major or minor release, make sure to update +`internal/version/version.go` with the new release version. + +```shell +$ git diff internal/version/version.go +diff --git a/internal/version/version.go b/internal/version/version.go +index 712aae64..c1ed191e 100644 +--- a/internal/version/version.go ++++ b/internal/version/version.go +@@ -30,7 +30,7 @@ var ( + // Increment major number for new feature additions and behavioral changes. + // Increment minor number for bug fixes and performance enhancements. + // Increment patch number for critical fixes to existing releases. +- version = "v3.3" ++ version = "v3.4" + + // metadata is extra build time data + metadata = "" +``` + +In addition to updating the version within the `version.go` file, you will also +need to update corresponding tests that are using that version number. + +* `cmd/helm/testdata/output/version.txt` +* `cmd/helm/testdata/output/version-client.txt` +* `cmd/helm/testdata/output/version-client-shorthand.txt` +* `cmd/helm/testdata/output/version-short.txt` +* `cmd/helm/testdata/output/version-template.txt` +* `pkg/chartutil/capabilities_test.go` + +```shell +git add . +git commit -m "bump version to $RELEASE_NAME" +``` + +This will update it for the $RELEASE_BRANCH_NAME only. You will also need to +pull this change into the main branch for when the next release is being +created, as in [this example of 3.2 to +3.3](https://github.com/helm/helm/pull/8411/files), and add it to the milestone +for the next release. + +```shell +# get the last commit id i.e. commit to bump the version +git log --format="%H" -n 1 + +# create new branch off main +git checkout main +git checkout -b bump-version- + +# cherry pick the commit using id from first command +git cherry-pick -x + +# commit the change +git push origin bump-version- +``` + +## 3. Major/Minor releases: Commit and Push the Release Branch + +In order for others to start testing, we can now push the release branch +upstream and start the test process. + +```shell +git push upstream $RELEASE_BRANCH_NAME +``` + +Make sure to check [helm on CircleCI](https://circleci.com/gh/helm/helm) to see +that the release passed CI before proceeding. + +If anyone is available, let others peer-review the branch before continuing to +ensure that all the proper changes have been made and all of the commits for the +release are there. + +## 4. Major/Minor releases: Create a Release Candidate + +Now that the release branch is out and ready, it is time to start creating and +iterating on release candidates. + +```shell +git tag --sign --annotate "${RELEASE_CANDIDATE_NAME}" --message "Helm release ${RELEASE_CANDIDATE_NAME}" +git push upstream $RELEASE_CANDIDATE_NAME +``` + +CircleCI will automatically create a tagged release image and client binary to +test with. + +For testers, the process to start testing after CircleCI finishes building the +artifacts involves the following steps to grab the client: + +linux/amd64, using /bin/bash: + +```shell +wget https://get.helm.sh/helm-$RELEASE_CANDIDATE_NAME-linux-amd64.tar.gz +``` + +darwin/amd64, using Terminal.app: + +```shell +wget https://get.helm.sh/helm-$RELEASE_CANDIDATE_NAME-darwin-amd64.tar.gz +``` + +windows/amd64, using PowerShell: + +```shell +PS C:\> Invoke-WebRequest -Uri "https://get.helm.sh/helm-$RELEASE_CANDIDATE_NAME-windows-amd64.tar.gz" -OutFile "helm-$ReleaseCandidateName-windows-amd64.tar.gz" +``` + +Then, unpack and move the binary to somewhere on your $PATH, or move it +somewhere and add it to your $PATH (e.g. /usr/local/bin/helm for linux/macOS, +C:\Program Files\helm\helm.exe for Windows). + +## 5. Major/Minor releases: Iterate on Successive Release Candidates + +Spend several days explicitly investing time and resources to try and break helm +in every possible way, documenting any findings pertinent to the release. This +time should be spent testing and finding ways in which the release might have +caused various features or upgrade environments to have issues, not coding. +During this time, the release is in code freeze, and any additional code changes +will be pushed out to the next release. + +During this phase, the $RELEASE_BRANCH_NAME branch will keep evolving as you +will produce new release candidates. The frequency of new candidates is up to +the release manager: use your best judgement taking into account the severity of +reported issues, testers' availability, and the release deadline date. Generally +speaking, it is better to let a release roll over the deadline than to ship a +broken release. + +Each time you'll want to produce a new release candidate, you will start by +adding commits to the branch by cherry-picking from main: + +```shell +git cherry-pick -x +``` + +You will also want to push the branch to GitHub and ensure it passes CI. + +After that, tag it and notify users of the new release candidate: + +```shell +export RELEASE_CANDIDATE_NAME="$RELEASE_NAME-rc.2" +git tag --sign --annotate "${RELEASE_CANDIDATE_NAME}" --message "Helm release ${RELEASE_CANDIDATE_NAME}" +git push upstream $RELEASE_CANDIDATE_NAME +``` + +Once pushed to GitHub, check to ensure the branch with this tag builds in CI. + +From here on just repeat this process, continuously testing until you're happy +with the release candidate. For a release candidate, we don't write the full notes, +but you can scaffold out some [release notes](#7-write-the-release-notes). + +## 6. Finalize the Release + +When you're finally happy with the quality of a release candidate, you can move +on and create the real thing. Double-check one last time to make sure everything +is in order, then finally push the release tag. + +```shell +git checkout $RELEASE_BRANCH_NAME +git tag --sign --annotate "${RELEASE_NAME}" --message "Helm release ${RELEASE_NAME}" +git push upstream $RELEASE_NAME +``` + +Verify that the release succeeded in +[CircleCI](https://circleci.com/gh/helm/helm). If not, you will need to fix the +release and push the release again. + +As the CI job will take some time to run, you can move on to writing release +notes while you wait for it to complete. + +## 7. Write the Release Notes + +We will auto-generate a changelog based on the commits that occurred during a +release cycle, but it is usually more beneficial to the end-user if the release +notes are hand-written by a human being/marketing team/dog. + +If you're releasing a major/minor release, listing notable user-facing features +is usually sufficient. For patch releases, do the same, but make note of the +symptoms and who is affected. + +The release notes should include the version and planned date of the next release. + +An example release note for a minor release would look like this: + +```markdown +## vX.Y.Z + +Helm vX.Y.Z is a feature release. This release, we focused on . Users are encouraged to upgrade for the best experience. + +The community keeps growing, and we'd love to see you there! + +- Join the discussion in [Kubernetes Slack](https://kubernetes.slack.com): + - `#helm-users` for questions and just to hang out + - `#helm-dev` for discussing PRs, code, and bugs +- Hang out at the Public Developer Call: Thursday, 9:30 Pacific via [Zoom](https://zoom.us/j/696660622) +- Test, debug, and contribute charts: [Artifact Hub helm charts](https://artifacthub.io/packages/search?kind=0) + +## Notable Changes + +- Kubernetes 1.16 is now supported including new manifest apiVersions +- Sprig was upgraded to 2.22 + +## Installation and Upgrading + +Download Helm X.Y. The common platform binaries are here: + +- [MacOS amd64](https://get.helm.sh/helm-vX.Y.Z-darwin-amd64.tar.gz) ([checksum](https://get.helm.sh/helm-vX.Y.Z-darwin-amd64.tar.gz.sha256sum) / CHECKSUM_VAL) +- [Linux amd64](https://get.helm.sh/helm-vX.Y.Z-linux-amd64.tar.gz) ([checksum](https://get.helm.sh/helm-vX.Y.Z-linux-amd64.tar.gz.sha256sum) / CHECKSUM_VAL) +- [Linux arm](https://get.helm.sh/helm-vX.Y.Z-linux-arm.tar.gz) ([checksum](https://get.helm.sh/helm-vX.Y.Z-linux-arm.tar.gz.sha256) / CHECKSUM_VAL) +- [Linux arm64](https://get.helm.sh/helm-vX.Y.Z-linux-arm64.tar.gz) ([checksum](https://get.helm.sh/helm-vX.Y.Z-linux-arm64.tar.gz.sha256sum) / CHECKSUM_VAL) +- [Linux i386](https://get.helm.sh/helm-vX.Y.Z-linux-386.tar.gz) ([checksum](https://get.helm.sh/helm-vX.Y.Z-linux-386.tar.gz.sha256) / CHECKSUM_VAL) +- [Linux ppc64le](https://get.helm.sh/helm-vX.Y.Z-linux-ppc64le.tar.gz) ([checksum](https://get.helm.sh/helm-vX.Y.Z-linux-ppc64le.tar.gz.sha256sum) / CHECKSUM_VAL) +- [Linux s390x](https://get.helm.sh/helm-vX.Y.Z-linux-s390x.tar.gz) ([checksum](https://get.helm.sh/helm-vX.Y.Z-linux-s390x.tar.gz.sha256sum) / CHECKSUM_VAL) +- [Windows amd64](https://get.helm.sh/helm-vX.Y.Z-windows-amd64.zip) ([checksum](https://get.helm.sh/helm-vX.Y.Z-windows-amd64.zip.sha256sum) / CHECKSUM_VAL) + +The [Quickstart Guide](https://docs.helm.sh/using_helm/#quickstart-guide) will get you going from there. For **upgrade instructions** or detailed installation notes, check the [install guide](https://docs.helm.sh/using_helm/#installing-helm). You can also use a [script to install](https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3) on any system with `bash`. + +## What's Next + +- vX.Y.Z+1 will contain only bug fixes and is planned for . +- vX.Y+1.0 is the next feature release and is planned for . This release will focus on ... + +## Changelog + +- chore(*): bump version to v2.7.0 08c1144f5eb3e3b636d9775617287cc26e53dba4 (Adam Reese) +- fix circle not building tags f4f932fabd197f7e6d608c8672b33a483b4b76fa (Matthew Fisher) +``` + +A partially completed set of release notes including the changelog can be +created by running the following command: + +```shell +export VERSION="$RELEASE_NAME" +export PREVIOUS_RELEASE=vX.Y.Z +make clean +make fetch-dist +make release-notes +``` + +This will create a good baseline set of release notes to which you should just +need to fill out the **Notable Changes** and **What's next** sections. + +Feel free to add your voice to the release notes; it's nice for people to think +we're not all robots. + +You should also double check the URLs and checksums are correct in the +auto-generated release notes. + +Once finished, go into GitHub to [helm/helm +releases](https://github.com/helm/helm/releases) and edit the release notes for +the tagged release with the notes written here. +For target branch, set to $RELEASE_BRANCH_NAME. + +It is now worth getting other people to take a look at the release notes before +the release is published. Send a request out to +[#helm-dev](https://kubernetes.slack.com/messages/C51E88VDG) for review. It is +always beneficial as it can be easy to miss something. + +## 8. PGP Sign the downloads + +While hashes provide a signature that the content of the downloads is what it +was generated, signed packages provide traceability of where the package came +from. + +To do this, run the following `make` commands: + +```shell +export VERSION="$RELEASE_NAME" +make clean # if not already run +make fetch-dist # if not already run +make sign +``` + +This will generate ascii armored signature files for each of the files pushed by +CI. + +All of the signature files (`*.asc`) need to be uploaded to the release on +GitHub (attach binaries). + +## 9. Publish Release + +Time to make the release official! + +After the release notes are saved on GitHub, the CI build is completed, and +you've added the signature files to the release, you can hit "Publish" on +the release. This publishes the release, listing it as "latest", and shows this +release on the front page of the [helm/helm](https://github.com/helm/helm) repo. + +## 10. Update Docs + +The [Helm website docs section](https://helm.sh/docs) lists the Helm versions +for the docs. Major, minor, and patch versions need to be updated on the site. +The date for the next minor release is also published on the site and must be +updated. +To do that create a pull request against the [helm-www +repository](https://github.com/helm/helm-www). In the `config.toml` file find +the proper `params.versions` section and update the Helm version, like in this +example of [updating the current +version](https://github.com/helm/helm-www/pull/676/files). In the same +`config.toml` file, update the `params.nextversion` section. + +Close the [helm/helm milestone](https://github.com/helm/helm/milestones) for +the release, if applicable. + +Update the [version +skew](https://github.com/helm/helm-www/blob/main/content/en/docs/topics/version_skew.md) +for major and minor releases. + +Update the release calendar [here](https://helm.sh/calendar/release): +* create an entry for the next minor release with a reminder for that day at 5pm GMT +* create an entry for the RC1 of the next minor release on the Monday of the week before the planned release, with a reminder for that day at 5pm GMT + +## 11. Tell the Community + +Congratulations! You're done. Go grab yourself a $DRINK_OF_CHOICE. You've earned +it. + +After enjoying a nice $DRINK_OF_CHOICE, go forth and announce the new release +in Slack and on Twitter with a link to the [release on +GitHub](https://github.com/helm/helm/releases). + +Optionally, write a blog post about the new release and showcase some of the new +features on there! diff --git a/content/en/docs/faq/_index.md b/content/en/docs/faq/_index.md new file mode 100644 index 0000000000..db3817f510 --- /dev/null +++ b/content/en/docs/faq/_index.md @@ -0,0 +1,17 @@ +--- +title: "Frequently Asked Questions" +weight: 8 +aliases: [ + "/docs/topics/faq/", + "/docs/faq/" +] +--- + +# Frequently Asked Questions + +> This section provides help with the most common questions. + +**We'd love your help** making this document better. To add, correct, or remove +information, [file an issue](https://github.com/helm/helm-www/issues) or send us +a pull request. + diff --git a/content/en/docs/faq/changes_since_helm2.md b/content/en/docs/faq/changes_since_helm2.md new file mode 100644 index 0000000000..53cd7e2c26 --- /dev/null +++ b/content/en/docs/faq/changes_since_helm2.md @@ -0,0 +1,428 @@ +--- +title: "Changes Since Helm 2" +weight: 1 +--- + +## Changes since Helm 2 + +Here's an exhaustive list of all the major changes introduced in Helm 3. + +### Removal of Tiller + +During the Helm 2 development cycle, we introduced Tiller. Tiller played an +important role for teams working on a shared cluster - it made it possible for +multiple different operators to interact with the same set of releases. + +With role-based access controls (RBAC) enabled by default in Kubernetes 1.6, +locking down Tiller for use in a production scenario became more difficult to +manage. Due to the vast number of possible security policies, our stance was to +provide a permissive default configuration. This allowed first-time users to +start experimenting with Helm and Kubernetes without having to dive headfirst +into the security controls. Unfortunately, this permissive configuration could +grant a user a broad range of permissions they weren’t intended to have. DevOps +and SREs had to learn additional operational steps when installing Tiller into a +multi-tenant cluster. + +After hearing how community members were using Helm in certain scenarios, we +found that Tiller’s release management system did not need to rely upon an +in-cluster operator to maintain state or act as a central hub for Helm release +information. Instead, we could simply fetch information from the Kubernetes API +server, render the Charts client-side, and store a record of the installation in +Kubernetes. + +Tiller’s primary goal could be accomplished without Tiller, so one of the first +decisions we made regarding Helm 3 was to completely remove Tiller. + +With Tiller gone, the security model for Helm is radically simplified. Helm 3 +now supports all the modern security, identity, and authorization features of +modern Kubernetes. Helm’s permissions are evaluated using your [kubeconfig +file](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/). +Cluster administrators can restrict user permissions at whatever granularity +they see fit. Releases are still recorded in-cluster, and the rest of Helm’s +functionality remains. + +### Improved Upgrade Strategy: 3-way Strategic Merge Patches + +Helm 2 used a two-way strategic merge patch. During an upgrade, it compared the +most recent chart's manifest against the proposed chart's manifest (the one +supplied during `helm upgrade`). It compared the differences between these two +charts to determine what changes needed to be applied to the resources in +Kubernetes. If changes were applied to the cluster out-of-band (such as during a +`kubectl edit`), those changes were not considered. This resulted in resources +being unable to roll back to its previous state: because Helm only considered +the last applied chart's manifest as its current state, if there were no changes +in the chart's state, the live state was left unchanged. + +In Helm 3, we now use a three-way strategic merge patch. Helm considers the old +manifest, its live state, and the new manifest when generating a patch. + +#### Examples + +Let's go through a few common examples what this change impacts. + +##### Rolling back where live state has changed + +Your team just deployed their application to production on Kubernetes using +Helm. The chart contains a Deployment object where the number of replicas is set +to three: + +```console +$ helm install myapp ./myapp +``` + +A new developer joins the team. On their first day while observing the +production cluster, a horrible coffee-spilling-on-the-keyboard accident happens +and they `kubectl scale` the production deployment from three replicas down to +zero. + +```console +$ kubectl scale --replicas=0 deployment/myapp +``` + +Another developer on your team notices that the production site is down and +decides to rollback the release to its previous state: + +```console +$ helm rollback myapp +``` + +What happens? + +In Helm 2, it would generate a patch, comparing the old manifest against the new +manifest. Because this is a rollback, it's the same manifest. Helm would +determine that there is nothing to change because there is no difference between +the old manifest and the new manifest. The replica count continues to stay at +zero. Panic ensues. + +In Helm 3, the patch is generated using the old manifest, the live state, and +the new manifest. Helm recognizes that the old state was at three, the live +state is at zero and the new manifest wishes to change it back to three, so it +generates a patch to change the state back to three. + +##### Upgrades where live state has changed + +Many service meshes and other controller-based applications inject data into +Kubernetes objects. This can be something like a sidecar, labels, or other +information. Previously if you had the given manifest rendered from a Chart: + +```yaml +containers: +- name: server + image: nginx:2.0.0 +``` + +And the live state was modified by another application to + +```yaml +containers: +- name: server + image: nginx:2.0.0 +- name: my-injected-sidecar + image: my-cool-mesh:1.0.0 +``` + +Now, you want to upgrade the `nginx` image tag to `2.1.0`. So, you upgrade to a +chart with the given manifest: + +```yaml +containers: +- name: server + image: nginx:2.1.0 +``` + +What happens? + +In Helm 2, Helm generates a patch of the `containers` object between the old +manifest and the new manifest. The cluster's live state is not considered during +the patch generation. + +The cluster's live state is modified to look like the following: + +```yaml +containers: +- name: server + image: nginx:2.1.0 +``` + +The sidecar pod is removed from live state. More panic ensues. + +In Helm 3, Helm generates a patch of the `containers` object between the old +manifest, the live state, and the new manifest. It notices that the new manifest +changes the image tag to `2.1.0`, but live state contains a sidecar container. + +The cluster's live state is modified to look like the following: + +```yaml +containers: +- name: server + image: nginx:2.1.0 +- name: my-injected-sidecar + image: my-cool-mesh:1.0.0 +``` + +### Release Names are now scoped to the Namespace + +With the removal of Tiller, the information about each release had to go +somewhere. In Helm 2, this was stored in the same namespace as Tiller. In +practice, this meant that once a name was used by a release, no other release +could use that same name, even if it was deployed in a different namespace. + +In Helm 3, information about a particular release is now stored in the same +namespace as the release itself. This means that users can now `helm install +wordpress stable/wordpress` in two separate namespaces, and each can be referred +with `helm list` by changing the current namespace context (e.g. `helm list +--namespace foo`). + +With this greater alignment to native cluster namespaces, the `helm list` +command no longer lists all releases by default. Instead, it will list only the +releases in the namespace of your current kubernetes context (i.e. the namespace +shown when you run `kubectl config view --minify`). It also means you must +supply the `--all-namespaces` flag to `helm list` to get behaviour similar to +Helm 2. + +### Secrets as the default storage driver + +In Helm 3, Secrets are now used as the [default storage +driver](/docs/topics/advanced/#storage-backends). Helm 2 used ConfigMaps by +default to store release information. In Helm 2.7.0, a new storage backend that +uses Secrets for storing release information was implemented, and it is now the +default starting in Helm 3. + +Changing to Secrets as the Helm 3 default allows for additional security in +protecting charts in conjunction with the release of Secret encryption in +Kubernetes. + +[Encrypting secrets at +rest](https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/) became +available as an alpha feature in Kubernetes 1.7 and became stable as of +Kubernetes 1.13. This allows users to encrypt Helm release metadata at rest, and +so it is a good starting point that can be expanded later into using something +like Vault. + +### Go import path changes + +In Helm 3, Helm switched the Go import path over from `k8s.io/helm` to +`helm.sh/helm/v3`. If you intend to upgrade to the Helm 3 Go client libraries, +make sure to change your import paths. + +### Capabilities + +The `.Capabilities` built-in object available during the rendering stage has +been simplified. + +[Built-in Objects](/docs/chart_template_guide/builtin_objects/) + +### Validating Chart Values with JSONSchema + +A JSON Schema can now be imposed upon chart values. This ensures that values +provided by the user follow the schema laid out by the chart maintainer, +providing better error reporting when the user provides an incorrect set of +values for a chart. + +Validation occurs when any of the following commands are invoked: + +* `helm install` +* `helm upgrade` +* `helm template` +* `helm lint` + +See the documentation on [Schema files](/docs/topics/charts#schema-files) for +more information. + +### Consolidation of `requirements.yaml` into `Chart.yaml` + +The Chart dependency management system moved from requirements.yaml and +requirements.lock to Chart.yaml and Chart.lock. We recommend that new charts +meant for Helm 3 use the new format. However, Helm 3 still understands Chart API +version 1 (`v1`) and will load existing `requirements.yaml` files + +In Helm 2, this is how a `requirements.yaml` looked: + +```yaml +dependencies: +- name: mariadb + version: 5.x.x + repository: https://charts.helm.sh/stable + condition: mariadb.enabled + tags: + - database +``` + +In Helm 3, the dependency is expressed the same way, but now from your +`Chart.yaml`: + +```yaml +dependencies: +- name: mariadb + version: 5.x.x + repository: https://charts.helm.sh/stable + condition: mariadb.enabled + tags: + - database +``` + +Charts are still downloaded and placed in the `charts/` directory, so subcharts +vendored into the `charts/` directory will continue to work without +modification. + +### Name (or --generate-name) is now required on install + +In Helm 2, if no name was provided, an auto-generated name would be given. In +production, this proved to be more of a nuisance than a helpful feature. In Helm +3, Helm will throw an error if no name is provided with `helm install`. + +For those who still wish to have a name auto-generated for you, you can use the +`--generate-name` flag to create one for you. + +### Pushing Charts to OCI Registries + +This is an experimental feature introduced in Helm 3. To use, set the +environment variable `HELM_EXPERIMENTAL_OCI=1`. + +At a high level, a Chart Repository is a location where Charts can be stored and +shared. The Helm client packs and ships Helm Charts to a Chart Repository. +Simply put, a Chart Repository is a basic HTTP server that houses an index.yaml +file and some packaged charts. + +While there are several benefits to the Chart Repository API meeting the most +basic storage requirements, a few drawbacks have started to show: + +- Chart Repositories have a very hard time abstracting most of the security + implementations required in a production environment. Having a standard API + for authentication and authorization is very important in production + scenarios. +- Helm’s Chart provenance tools used for signing and verifying the integrity and + origin of a chart are an optional piece of the Chart publishing process. +- In multi-tenant scenarios, the same Chart can be uploaded by another tenant, + costing twice the storage cost to store the same content. Smarter chart + repositories have been designed to handle this, but it’s not a part of the + formal specification. +- Using a single index file for search, metadata information, and fetching + Charts has made it difficult or clunky to design around in secure multi-tenant + implementations. + +Docker’s Distribution project (also known as Docker Registry v2) is the +successor to the Docker Registry project. Many major cloud vendors have a +product offering of the Distribution project, and with so many vendors offering +the same product, the Distribution project has benefited from many years of +hardening, security best practices, and battle-testing. + +Please have a look at `helm help chart` and `helm help registry` for more +information on how to package a chart and push it to a Docker registry. + +For more info, please see [this page](/docs/topics/registries/). + +### Removal of `helm serve` + +`helm serve` ran a local Chart Repository on your machine for development +purposes. However, it didn't receive much uptake as a development tool and had +numerous issues with its design. In the end, we decided to remove it and split +it out as a plugin. + +For a similar experience to `helm serve`, have a look at the local filesystem +storage option in +[ChartMuseum](https://chartmuseum.com/docs/#using-with-local-filesystem-storage) +and the [servecm plugin](https://github.com/jdolitsky/helm-servecm). + + +### Library chart support + +Helm 3 supports a class of chart called a “library chart”. This is a chart that +is shared by other charts, but does not create any release artifacts of its own. +A library chart’s templates can only declare `define` elements. Globally scoped +non-`define` content is simply ignored. This allows users to re-use and share +snippets of code that can be re-used across many charts, avoiding redundancy and +keeping charts [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself). + +Library charts are declared in the dependencies directive in Chart.yaml, and are +installed and managed like any other chart. + +```yaml +dependencies: + - name: mylib + version: 1.x.x + repository: quay.io +``` + +We’re very excited to see the use cases this feature opens up for chart +developers, as well as any best practices that arise from consuming library +charts. + +### Chart.yaml apiVersion bump + +With the introduction of library chart support and the consolidation of +requirements.yaml into Chart.yaml, clients that understood Helm 2's package +format won't understand these new features. So, we bumped the apiVersion in +Chart.yaml from `v1` to `v2`. + +`helm create` now creates charts using this new format, so the default +apiVersion was bumped there as well. + +Clients wishing to support both versions of Helm charts should inspect the +`apiVersion` field in Chart.yaml to understand how to parse the package format. + +### XDG Base Directory Support + +[The XDG Base Directory +Specification](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html) +is a portable standard defining where configuration, data, and cached files +should be stored on the filesystem. + +In Helm 2, Helm stored all this information in `~/.helm` (affectionately known +as `helm home`), which could be changed by setting the `$HELM_HOME` environment +variable, or by using the global flag `--home`. + +In Helm 3, Helm now respects the following environment variables as per the XDG +Base Directory Specification: + +- `$XDG_CACHE_HOME` +- `$XDG_CONFIG_HOME` +- `$XDG_DATA_HOME` + +Helm plugins are still passed `$HELM_HOME` as an alias to `$XDG_DATA_HOME` for +backwards compatibility with plugins looking to use `$HELM_HOME` as a scratchpad +environment. + +Several new environment variables are also passed in to the plugin's environment +to accommodate this change: + +- `$HELM_PATH_CACHE` for the cache path +- `$HELM_PATH_CONFIG` for the config path +- `$HELM_PATH_DATA` for the data path + +Helm plugins looking to support Helm 3 should consider using these new +environment variables instead. + +### CLI Command Renames + +In order to better align the verbiage from other package managers, `helm delete` +was re-named to `helm uninstall`. `helm delete` is still retained as an alias to +`helm uninstall`, so either form can be used. + +In Helm 2, in order to purge the release ledger, the `--purge` flag had to be +provided. This functionality is now enabled by default. To retain the previous +behavior, use `helm uninstall --keep-history`. + +Additionally, several other commands were re-named to accommodate the same +conventions: + +- `helm inspect` -> `helm show` +- `helm fetch` -> `helm pull` + +These commands have also retained their older verbs as aliases, so you can +continue to use them in either form. + +### Automatically creating namespaces + +When creating a release in a namespace that does not exist, Helm 2 created the +namespace. Helm 3 follows the behavior of other Kubernetes tooling and returns +an error if the namespace does not exist. Helm 3 will create the namespace if +you explicitly specify `--create-namespace` flag. + +### What happened to .Chart.ApiVersion? + +Helm follows the typical convention for CamelCasing which is to capitalize an +acronym. We have done this elsewhere in the code, such as with +`.Capabilities.APIVersions.Has`. In Helm v3, we corrected `.Chart.ApiVersion` +to follow this pattern, renaming it to `.Chart.APIVersion`. + diff --git a/content/en/docs/faq/installing.md b/content/en/docs/faq/installing.md new file mode 100644 index 0000000000..c7a0d238d5 --- /dev/null +++ b/content/en/docs/faq/installing.md @@ -0,0 +1,39 @@ +--- +title: "Installing" +weight: 2 +--- + +## Installing + +### Why aren't there native packages of Helm for Fedora and other Linux distros? + +The Helm project does not maintain packages for operating systems and +environments. The Helm community may provide native packages and if the Helm +project is made aware of them they will be listed. This is how the Homebrew +formula was started and listed. If you're interested in maintaining a package, +we'd love it. + +### Why do you provide a `curl ...|bash` script? + +There is a script in our repository (`scripts/get-helm-3`) that can be executed +as a `curl ..|bash` script. The transfers are all protected by HTTPS, and the +script does some auditing of the packages it fetches. However, the script has +all the usual dangers of any shell script. + +We provide it because it is useful, but we suggest that users carefully read the +script first. What we'd really like, though, are better packaged releases of +Helm. + +### How do I put the Helm client files somewhere other than their defaults? + +Helm uses the XDG structure for storing files. There are environment variables +you can use to override these locations: + +- `$XDG_CACHE_HOME`: set an alternative location for storing cached files. +- `$XDG_CONFIG_HOME`: set an alternative location for storing Helm + configuration. +- `$XDG_DATA_HOME`: set an alternative location for storing Helm data. + +Note that if you have existing repositories, you will need to re-add them with +`helm repo add...`. + diff --git a/content/en/docs/faq/troubleshooting.md b/content/en/docs/faq/troubleshooting.md new file mode 100644 index 0000000000..05e65eb53e --- /dev/null +++ b/content/en/docs/faq/troubleshooting.md @@ -0,0 +1,162 @@ +--- +title: "Troubleshooting" +weight: 4 +--- + +## Troubleshooting + +### I am getting a warning about "Unable to get an update from the "stable" chart repository" + +Run `helm repo list`. If it shows your `stable` repository pointing to a `storage.googleapis.com` URL, you +will need to update that repository. On November 13, 2020, the Helm Charts repo [became unsupported](https://github.com/helm/charts#deprecation-timeline) after a year-long deprecation. An archive has been made available at +`https://charts.helm.sh/stable` but will no longer receive updates. + +You can run the following command to fix your repository: + +```console +$ helm repo add stable https://charts.helm.sh/stable --force-update +``` + +The same goes for the `incubator` repository, which has an archive available at https://charts.helm.sh/incubator. +You can run the following command to repair it: + +```console +$ helm repo add incubator https://charts.helm.sh/incubator --force-update +``` + +### I am getting the warning 'WARNING: "kubernetes-charts.storage.googleapis.com" is deprecated for "stable" and will be deleted Nov. 13, 2020.' + +The old Google helm chart repository has been replaced by a new Helm chart repository. + +Run the following command to permanently fix this: + +```console +$ helm repo add stable https://charts.helm.sh/stable --force-update +``` + +If you get a similar error for `incubator`, run this command: + +```console +$ helm repo add incubator https://charts.helm.sh/incubator --force-update +``` + +### When I add a Helm repo, I get the error 'Error: Repo "https://kubernetes-charts.storage.googleapis.com" is no longer available' + +The Helm Chart repositories are no longer supported after [a year-long deprecation period](https://github.com/helm/charts#deprecation-timeline). +Archives for these repositories are available at `https://charts.helm.sh/stable` and `https://charts.helm.sh/incubator`, however they will no longer receive updates. The command +`helm repo add` will not let you add the old URLs unless you specify `--use-deprecated-repos`. + +### On GKE (Google Container Engine) I get "No SSH tunnels currently open" + +``` +Error: Error forwarding ports: error upgrading connection: No SSH tunnels currently open. Were the targets able to accept an ssh-key for user "gke-[redacted]"? +``` + +Another variation of the error message is: + + +``` +Unable to connect to the server: x509: certificate signed by unknown authority +``` + +The issue is that your local Kubernetes config file must have the correct +credentials. + +When you create a cluster on GKE, it will give you credentials, including SSL +certificates and certificate authorities. These need to be stored in a +Kubernetes config file (Default: `~/.kube/config`) so that `kubectl` and `helm` +can access them. + +### After migration from Helm 2, `helm list` shows only some (or none) of my releases + +It is likely that you have missed the fact that Helm 3 now uses cluster +namespaces throughout to scope releases. This means that for all commands +referencing a release you must either: + +* rely on the current namespace in the active kubernetes context (as described + by the `kubectl config view --minify` command), +* specify the correct namespace using the `--namespace`/`-n` flag, or +* for the `helm list` command, specify the `--all-namespaces`/`-A` flag + +This applies to `helm ls`, `helm uninstall`, and all other `helm` commands +referencing a release. + + +### On macOS, the file `/etc/.mdns_debug` is accessed. Why? + +We are aware of a case on macOS where Helm will try to access a file named +`/etc/.mdns_debug`. If the file exists, Helm holds the file handle open while it +executes. + +This is caused by macOS's MDNS library. It attempts to load that file to read +debugging settings (if enabled). The file handle probably should not be held open, and +this issue has been reported to Apple. However, it is macOS, not Helm, that causes this +behavior. + +If you do not want Helm to load this file, you may be able to compile Helm to as +a static library that does not use the host network stack. Doing so will inflate the +binary size of Helm, but will prevent the file from being open. + +This issue was originally flagged as a potential security problem. But it has since +been determined that there is no flaw or vulnerability caused by this behavior. + +### helm repo add fails when it used to work + +In helm 3.3.1 and before, the command `helm repo add ` will give +no output if you attempt to add a repo which already exists. The flag +`--no-update` would raise an error if the repo was already registered. + +In helm 3.3.2 and beyond, an attempt to add an existing repo will error: + +`Error: repository name (reponame) already exists, please specify a different name` + +The default behavior is now reversed. `--no-update` is now ignored, while if you +want to replace (overwrite) an existing repo, you can use `--force-update`. + +This is due to a breaking change for a security fix as explained in the [Helm +3.3.2 release notes](https://github.com/helm/helm/releases/tag/v3.3.2). + +### Enabling Kubernetes client logging + +Printing log messages for debugging the Kubernetes client can be enabled using +the [klog](https://pkg.go.dev/k8s.io/klog) flags. Using the `-v` flag to set +verbosity level will be enough for most cases. + +For example: + +``` +helm list -v 6 +``` + +### Tiller installations stopped working and access is denied + +Helm releases used to be available from . As explained in ["Announcing get.helm.sh"](https://helm.sh/blog/get-helm-sh/), the official location changed in June 2019. [GitHub Container Registry](https://github.com/orgs/helm/packages/container/package/tiller) makes all the old Tiller images available. + + +If you are trying to download older versions of Helm from the storage bucket you used in the past, you may find that they are missing: + +``` + + AccessDenied + Access denied. +
Anonymous caller does not have storage.objects.get access to the Google Cloud Storage object.
+
+``` + +The [legacy Tiller image location](https://gcr.io/kubernetes-helm/tiller) began the removal of images in August 2021. We have made these images available at the [GitHub Container Registry](https://github.com/orgs/helm/packages/container/package/tiller) location. For example, to download version v2.17.0, replace: + +`https://storage.googleapis.com/kubernetes-helm/helm-v2.17.0-linux-amd64.tar.gz` + +with: + +`https://get.helm.sh/helm-v2.17.0-linux-amd64.tar.gz` + +To initialize with Helm v2.17.0: + +`helm init —upgrade` + +Or if a different version is needed, use the --tiller-image flag to override the default location and install a specific Helm v2 version: + +`helm init --tiller-image ghcr.io/helm/tiller:v2.16.9` + +**Note:** The Helm maintainers recommend migration to a currently-supported version of Helm. Helm v2.17.0 was the final release of Helm v2; Helm v2 is unsupported since November 2020, as detailed in [Helm 2 and the Charts Project Are Now Unsupported](https://helm.sh/blog/helm-2-becomes-unsupported/). Many CVEs have been flagged against Helm since then, and those exploits are patched in Helm v3 but will never be patched in Helm v2. See the [current list of published Helm advisories](https://github.com/helm/helm/security/advisories?state=published) and make a plan to [migrate to Helm v3](https://helm.sh/docs/topics/v2_v3_migration/#helm) today. diff --git a/content/en/docs/faq/uninstalling.md b/content/en/docs/faq/uninstalling.md new file mode 100644 index 0000000000..b0558134ce --- /dev/null +++ b/content/en/docs/faq/uninstalling.md @@ -0,0 +1,23 @@ +--- +title: "Uninstalling" +weight: 3 +--- + +## Uninstalling + +### I want to delete my local Helm. Where are all its files? + +Along with the `helm` binary, Helm stores some files in the following locations: + +- $XDG_CACHE_HOME +- $XDG_CONFIG_HOME +- $XDG_DATA_HOME + +The following table gives the default folder for each of these, by OS: + +| Operating System | Cache Path | Configuration Path | Data Path | +|------------------|-----------------------------|----------------------------------|---------------------------| +| Linux | `$HOME/.cache/helm ` | `$HOME/.config/helm ` | `$HOME/.local/share/helm` | +| macOS | `$HOME/Library/Caches/helm` | `$HOME/Library/Preferences/helm` | `$HOME/Library/helm ` | +| Windows | `%TEMP%\helm ` | `%APPDATA%\helm ` | `%APPDATA%\helm` | + diff --git a/content/en/docs/glossary/_index.md b/content/en/docs/glossary/_index.md new file mode 100644 index 0000000000..a2f563760c --- /dev/null +++ b/content/en/docs/glossary/_index.md @@ -0,0 +1,160 @@ +--- +title: "Glossary" +description: "Terms used to describe components of Helm's architecture." +weight: 9 +--- + +# Glossary + +## Chart + +A Helm package that contains information sufficient for installing a set of +Kubernetes resources into a Kubernetes cluster. + +Charts contain a `Chart.yaml` file as well as templates, default values +(`values.yaml`), and dependencies. + +Charts are developed in a well-defined directory structure, and then packaged +into an archive format called a _chart archive_. + +## Chart Archive + +A _chart archive_ is a tarred and gzipped (and optionally signed) chart. + +## Chart Dependency (Subcharts) + +Charts may depend upon other charts. There are two ways a dependency may occur: + +- Soft dependency: A chart may simply not function without another chart being + installed in a cluster. Helm does not provide tooling for this case. In this + case, dependencies may be managed separately. +- Hard dependency: A chart may contain (inside of its `charts/` directory) + another chart upon which it depends. In this case, installing the chart will + install all of its dependencies. In this case, a chart and its dependencies + are managed as a collection. + +When a chart is packaged (via `helm package`) all of its hard dependencies are +bundled with it. + +## Chart Version + +Charts are versioned according to the [SemVer 2 spec](https://semver.org). A +version number is required on every chart. + +## Chart.yaml + +Information about a chart is stored in a special file called `Chart.yaml`. Every +chart must have this file. + +## Helm (and helm) + +Helm is the package manager for Kubernetes. As an operating system package +manager makes it easy to install tools on an OS, Helm makes it easy to install +applications and resources into Kubernetes clusters. + +While _Helm_ is the name of the project, the command line client is also named +`helm`. By convention, when speaking of the project, _Helm_ is capitalized. When +speaking of the client, _helm_ is in lowercase. + +## Helm Configuration Files (XDG) + +Helm stores its configuration files in XDG directories. These directories are +created the first time `helm` is run. + +## Kube Config (KUBECONFIG) + +The Helm client learns about Kubernetes clusters by using files in the _Kube +config_ file format. By default, Helm attempts to find this file in the place +where `kubectl` creates it (`$HOME/.kube/config`). + +## Lint (Linting) + +To _lint_ a chart is to validate that it follows the conventions and +requirements of the Helm chart standard. Helm provides tools to do this, notably +the `helm lint` command. + +## Provenance (Provenance file) + +Helm charts may be accompanied by a _provenance file_ which provides information +about where the chart came from and what it contains. + +Provenance files are one part of the Helm security story. A provenance contains +a cryptographic hash of the chart archive file, the Chart.yaml data, and a +signature block (an OpenPGP "clearsign" block). When coupled with a keychain, +this provides chart users with the ability to: + +- Validate that a chart was signed by a trusted party +- Validate that the chart file has not been tampered with +- Validate the contents of a chart metadata (`Chart.yaml`) +- Quickly match a chart to its provenance data + +Provenance files have the `.prov` extension, and can be served from a chart +repository server or any other HTTP server. + +## Release + +When a chart is installed, the Helm library creates a _release_ to track that +installation. + +A single chart may be installed many times into the same cluster, and create +many different releases. For example, one can install three PostgreSQL databases +by running `helm install` three times with a different release name. + +## Release Number (Release Version) + +A single release can be updated multiple times. A sequential counter is used to +track releases as they change. After a first `helm install`, a release will have +_release number_ 1. Each time a release is upgraded or rolled back, the release +number will be incremented. + +## Rollback + +A release can be upgraded to a newer chart or configuration. But since release +history is stored, a release can also be _rolled back_ to a previous release +number. This is done with the `helm rollback` command. + +Importantly, a rolled back release will receive a new release number. + +| Operation | Release Number | +|------------|------------------------------------------------------| +| install | release 1 | +| upgrade | release 2 | +| upgrade | release 3 | +| rollback 1 | release 4 (but running the same config as release 1) | + +The above table illustrates how release numbers increment across install, +upgrade, and rollback. + +## Helm Library (or SDK) + +The Helm Library (or SDK) refers to the Go code that interacts directly with the +Kubernetes API server to install, upgrade, query, and remove Kubernetes +resources. It can be imported into a project to use Helm as a client library +instead of a CLI. + +## Repository (Repo, Chart Repository) + +Helm charts may be stored on dedicated HTTP servers called _chart repositories_ +(_repositories_, or just _repos_). + +A chart repository server is a simple HTTP server that can serve an `index.yaml` +file that describes a batch of charts, and provides information on where each +chart can be downloaded from. (Many chart repositories serve the charts as well +as the `index.yaml` file.) + +A Helm client can point to zero or more chart repositories. By default, Helm +clients are not configured with any chart repositories. Chart repositories can +be added at any time using the `helm repo add` command. + +## Values (Values Files, values.yaml) + +Values provide a way to override template defaults with your own information. + +Helm Charts are "parameterized", which means the chart developer may expose +configuration that can be overridden at installation time. For example, a chart +may expose a `username` field that allows setting a user name for a service. + +These exposed variables are called _values_ in Helm parlance. + +Values can be set during `helm install` and `helm upgrade` operations, either by +passing them in directly, or by using a `values.yaml` file. diff --git a/content/en/docs/helm/_index.md b/content/en/docs/helm/_index.md new file mode 100644 index 0000000000..12b5febbe8 --- /dev/null +++ b/content/en/docs/helm/_index.md @@ -0,0 +1,10 @@ +--- +title: "Helm Commands" +description: "Documentation for the full list of helm CLI commands." +weight: 6 +slug: helm +--- + +# Helm Commands + +Here you’ll find the list of CLI commands for Helm, with help info on their usage. diff --git a/content/en/docs/helm/helm.md b/content/en/docs/helm/helm.md new file mode 100644 index 0000000000..8d8279010e --- /dev/null +++ b/content/en/docs/helm/helm.md @@ -0,0 +1,112 @@ +--- +title: "Helm" +--- + +## helm + +The Helm package manager for Kubernetes. + +### Synopsis + +The Kubernetes package manager + +Common actions for Helm: + +- helm search: search for charts +- helm pull: download a chart to your local directory to view +- helm install: upload the chart to Kubernetes +- helm list: list releases of charts + +Environment variables: + +| Name | Description | +|------------------------------------|---------------------------------------------------------------------------------------------------| +| $HELM_CACHE_HOME | set an alternative location for storing cached files. | +| $HELM_CONFIG_HOME | set an alternative location for storing Helm configuration. | +| $HELM_DATA_HOME | set an alternative location for storing Helm data. | +| $HELM_DEBUG | indicate whether or not Helm is running in Debug mode | +| $HELM_DRIVER | set the backend storage driver. Values are: configmap, secret, memory, sql. | +| $HELM_DRIVER_SQL_CONNECTION_STRING | set the connection string the SQL storage driver should use. | +| $HELM_MAX_HISTORY | set the maximum number of helm release history. | +| $HELM_NAMESPACE | set the namespace used for the helm operations. | +| $HELM_NO_PLUGINS | disable plugins. Set HELM_NO_PLUGINS=1 to disable plugins. | +| $HELM_PLUGINS | set the path to the plugins directory | +| $HELM_REGISTRY_CONFIG | set the path to the registry config file. | +| $HELM_REPOSITORY_CACHE | set the path to the repository cache directory | +| $HELM_REPOSITORY_CONFIG | set the path to the repositories file. | +| $KUBECONFIG | set an alternative Kubernetes configuration file (default "~/.kube/config") | +| $HELM_KUBEAPISERVER | set the Kubernetes API Server Endpoint for authentication | +| $HELM_KUBECAFILE | set the Kubernetes certificate authority file. | +| $HELM_KUBEASGROUPS | set the Groups to use for impersonation using a comma-separated list. | +| $HELM_KUBEASUSER | set the Username to impersonate for the operation. | +| $HELM_KUBECONTEXT | set the name of the kubeconfig context. | +| $HELM_KUBETOKEN | set the Bearer KubeToken used for authentication. | +| $HELM_KUBEINSECURE_SKIP_TLS_VERIFY | indicate if the Kubernetes API server's certificate validation should be skipped (insecure) | +| $HELM_KUBETLS_SERVER_NAME | set the server name used to validate the Kubernetes API server certificate | +| $HELM_BURST_LIMIT | set the default burst limit in the case the server contains many CRDs (default 100, -1 to disable)| + +Helm stores cache, configuration, and data based on the following configuration order: + +- If a HELM_*_HOME environment variable is set, it will be used +- Otherwise, on systems supporting the XDG base directory specification, the XDG variables will be used +- When no other location is set a default location will be used based on the operating system + +By default, the default directories depend on the Operating System. The defaults are listed below: + +| Operating System | Cache Path | Configuration Path | Data Path | +|------------------|---------------------------|--------------------------------|-------------------------| +| Linux | $HOME/.cache/helm | $HOME/.config/helm | $HOME/.local/share/helm | +| macOS | $HOME/Library/Caches/helm | $HOME/Library/Preferences/helm | $HOME/Library/helm | +| Windows | %TEMP%\helm | %APPDATA%\helm | %APPDATA%\helm | + + +### Options + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + -h, --help help for helm + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm completion](helm_completion.md) - generate autocompletion scripts for the specified shell +* [helm create](helm_create.md) - create a new chart with the given name +* [helm dependency](helm_dependency.md) - manage a chart's dependencies +* [helm env](helm_env.md) - helm client environment information +* [helm get](helm_get.md) - download extended information of a named release +* [helm history](helm_history.md) - fetch release history +* [helm install](helm_install.md) - install a chart +* [helm lint](helm_lint.md) - examine a chart for possible issues +* [helm list](helm_list.md) - list releases +* [helm package](helm_package.md) - package a chart directory into a chart archive +* [helm plugin](helm_plugin.md) - install, list, or uninstall Helm plugins +* [helm pull](helm_pull.md) - download a chart from a repository and (optionally) unpack it in local directory +* [helm push](helm_push.md) - push a chart to remote +* [helm registry](helm_registry.md) - login to or logout from a registry +* [helm repo](helm_repo.md) - add, list, remove, update, and index chart repositories +* [helm rollback](helm_rollback.md) - roll back a release to a previous revision +* [helm search](helm_search.md) - search for a keyword in charts +* [helm show](helm_show.md) - show information of a chart +* [helm status](helm_status.md) - display the status of the named release +* [helm template](helm_template.md) - locally render templates +* [helm test](helm_test.md) - run tests for a release +* [helm uninstall](helm_uninstall.md) - uninstall a release +* [helm upgrade](helm_upgrade.md) - upgrade a release +* [helm verify](helm_verify.md) - verify that a chart at the given path has been signed and is valid +* [helm version](helm_version.md) - print the client version information + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_completion.md b/content/en/docs/helm/helm_completion.md new file mode 100644 index 0000000000..c641c32b18 --- /dev/null +++ b/content/en/docs/helm/helm_completion.md @@ -0,0 +1,49 @@ +--- +title: "Helm Completion" +--- + +## helm completion + +generate autocompletion scripts for the specified shell + +### Synopsis + + +Generate autocompletion scripts for Helm for the specified shell. + + +### Options + +``` + -h, --help help for completion +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm](helm.md) - The Helm package manager for Kubernetes. +* [helm completion bash](helm_completion_bash.md) - generate autocompletion script for bash +* [helm completion fish](helm_completion_fish.md) - generate autocompletion script for fish +* [helm completion powershell](helm_completion_powershell.md) - generate autocompletion script for powershell +* [helm completion zsh](helm_completion_zsh.md) - generate autocompletion script for zsh + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_completion_bash.md b/content/en/docs/helm/helm_completion_bash.md new file mode 100644 index 0000000000..e3f5c195f7 --- /dev/null +++ b/content/en/docs/helm/helm_completion_bash.md @@ -0,0 +1,63 @@ +--- +title: "Helm Completion Bash" +--- + +## helm completion bash + +generate autocompletion script for bash + +### Synopsis + + +Generate the autocompletion script for Helm for the bash shell. + +To load completions in your current shell session: + + source <(helm completion bash) + +To load completions for every new session, execute once: +- Linux: + + helm completion bash > /etc/bash_completion.d/helm + +- MacOS: + + helm completion bash > /usr/local/etc/bash_completion.d/helm + + +``` +helm completion bash [flags] +``` + +### Options + +``` + -h, --help help for bash + --no-descriptions disable completion descriptions +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm completion](helm_completion.md) - generate autocompletion scripts for the specified shell + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_completion_fish.md b/content/en/docs/helm/helm_completion_fish.md new file mode 100644 index 0000000000..acae91300c --- /dev/null +++ b/content/en/docs/helm/helm_completion_fish.md @@ -0,0 +1,60 @@ +--- +title: "Helm Completion Fish" +--- + +## helm completion fish + +generate autocompletion script for fish + +### Synopsis + + +Generate the autocompletion script for Helm for the fish shell. + +To load completions in your current shell session: + + helm completion fish | source + +To load completions for every new session, execute once: + + helm completion fish > ~/.config/fish/completions/helm.fish + +You will need to start a new shell for this setup to take effect. + + +``` +helm completion fish [flags] +``` + +### Options + +``` + -h, --help help for fish + --no-descriptions disable completion descriptions +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm completion](helm_completion.md) - generate autocompletion scripts for the specified shell + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_completion_powershell.md b/content/en/docs/helm/helm_completion_powershell.md new file mode 100644 index 0000000000..148590de3e --- /dev/null +++ b/content/en/docs/helm/helm_completion_powershell.md @@ -0,0 +1,56 @@ +--- +title: "Helm Completion Powershell" +--- + +## helm completion powershell + +generate autocompletion script for powershell + +### Synopsis + + +Generate the autocompletion script for powershell. + +To load completions in your current shell session: +PS C:\> helm completion powershell | Out-String | Invoke-Expression + +To load completions for every new session, add the output of the above command +to your powershell profile. + + +``` +helm completion powershell [flags] +``` + +### Options + +``` + -h, --help help for powershell + --no-descriptions disable completion descriptions +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm completion](helm_completion.md) - generate autocompletion scripts for the specified shell + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_completion_zsh.md b/content/en/docs/helm/helm_completion_zsh.md new file mode 100644 index 0000000000..d4a36188a4 --- /dev/null +++ b/content/en/docs/helm/helm_completion_zsh.md @@ -0,0 +1,58 @@ +--- +title: "Helm Completion Zsh" +--- + +## helm completion zsh + +generate autocompletion script for zsh + +### Synopsis + + +Generate the autocompletion script for Helm for the zsh shell. + +To load completions in your current shell session: + + source <(helm completion zsh) + +To load completions for every new session, execute once: + + helm completion zsh > "${fpath[1]}/_helm" + + +``` +helm completion zsh [flags] +``` + +### Options + +``` + -h, --help help for zsh + --no-descriptions disable completion descriptions +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm completion](helm_completion.md) - generate autocompletion scripts for the specified shell + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_create.md b/content/en/docs/helm/helm_create.md new file mode 100644 index 0000000000..f8cccbe3fa --- /dev/null +++ b/content/en/docs/helm/helm_create.md @@ -0,0 +1,67 @@ +--- +title: "Helm Create" +--- + +## helm create + +create a new chart with the given name + +### Synopsis + + +This command creates a chart directory along with the common files and +directories used in a chart. + +For example, 'helm create foo' will create a directory structure that looks +something like this: + + foo/ + ├── .helmignore # Contains patterns to ignore when packaging Helm charts. + ├── Chart.yaml # Information about your chart + ├── values.yaml # The default values for your templates + ├── charts/ # Charts that this chart depends on + └── templates/ # The template files + └── tests/ # The test files + +'helm create' takes a path for an argument. If directories in the given path +do not exist, Helm will attempt to create them as it goes. If the given +destination exists and there are files in that directory, conflicting files +will be overwritten, but other files will be left alone. + + +``` +helm create NAME [flags] +``` + +### Options + +``` + -h, --help help for create + -p, --starter string the name or absolute path to Helm starter scaffold +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm](helm.md) - The Helm package manager for Kubernetes. + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_delete.md b/content/en/docs/helm/helm_delete.md new file mode 100644 index 0000000000..ba4c423453 --- /dev/null +++ b/content/en/docs/helm/helm_delete.md @@ -0,0 +1,7 @@ +--- +section: deprecated +--- + +## helm delete + +This command has been renamed. Please refer instead to [helm uninstall](helm_uninstall). diff --git a/content/en/docs/helm/helm_dependency.md b/content/en/docs/helm/helm_dependency.md new file mode 100644 index 0000000000..cec1280cca --- /dev/null +++ b/content/en/docs/helm/helm_dependency.md @@ -0,0 +1,92 @@ +--- +title: "Helm Dependency" +--- + +## helm dependency + +manage a chart's dependencies + +### Synopsis + + +Manage the dependencies of a chart. + +Helm charts store their dependencies in 'charts/'. For chart developers, it is +often easier to manage dependencies in 'Chart.yaml' which declares all +dependencies. + +The dependency commands operate on that file, making it easy to synchronize +between the desired dependencies and the actual dependencies stored in the +'charts/' directory. + +For example, this Chart.yaml declares two dependencies: + + # Chart.yaml + dependencies: + - name: nginx + version: "1.2.3" + repository: "https://example.com/charts" + - name: memcached + version: "3.2.1" + repository: "https://another.example.com/charts" + + +The 'name' should be the name of a chart, where that name must match the name +in that chart's 'Chart.yaml' file. + +The 'version' field should contain a semantic version or version range. + +The 'repository' URL should point to a Chart Repository. Helm expects that by +appending '/index.yaml' to the URL, it should be able to retrieve the chart +repository's index. Note: 'repository' can be an alias. The alias must start +with 'alias:' or '@'. + +Starting from 2.2.0, repository can be defined as the path to the directory of +the dependency charts stored locally. The path should start with a prefix of +"file://". For example, + + # Chart.yaml + dependencies: + - name: nginx + version: "1.2.3" + repository: "file://../dependency_chart/nginx" + +If the dependency chart is retrieved locally, it is not required to have the +repository added to helm by "helm add repo". Version matching is also supported +for this case. + + +### Options + +``` + -h, --help help for dependency +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm](helm.md) - The Helm package manager for Kubernetes. +* [helm dependency build](helm_dependency_build.md) - rebuild the charts/ directory based on the Chart.lock file +* [helm dependency list](helm_dependency_list.md) - list the dependencies for the given chart +* [helm dependency update](helm_dependency_update.md) - update charts/ based on the contents of Chart.yaml + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_dependency_build.md b/content/en/docs/helm/helm_dependency_build.md new file mode 100644 index 0000000000..c457c05972 --- /dev/null +++ b/content/en/docs/helm/helm_dependency_build.md @@ -0,0 +1,59 @@ +--- +title: "Helm Dependency Build" +--- + +## helm dependency build + +rebuild the charts/ directory based on the Chart.lock file + +### Synopsis + + +Build out the charts/ directory from the Chart.lock file. + +Build is used to reconstruct a chart's dependencies to the state specified in +the lock file. This will not re-negotiate dependencies, as 'helm dependency update' +does. + +If no lock file is found, 'helm dependency build' will mirror the behavior +of 'helm dependency update'. + + +``` +helm dependency build CHART [flags] +``` + +### Options + +``` + -h, --help help for build + --keyring string keyring containing public keys (default "~/.gnupg/pubring.gpg") + --skip-refresh do not refresh the local repository cache + --verify verify the packages against signatures +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm dependency](helm_dependency.md) - manage a chart's dependencies + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_dependency_list.md b/content/en/docs/helm/helm_dependency_list.md new file mode 100644 index 0000000000..c2946cfdc5 --- /dev/null +++ b/content/en/docs/helm/helm_dependency_list.md @@ -0,0 +1,55 @@ +--- +title: "Helm Dependency List" +--- + +## helm dependency list + +list the dependencies for the given chart + +### Synopsis + + +List all of the dependencies declared in a chart. + +This can take chart archives and chart directories as input. It will not alter +the contents of a chart. + +This will produce an error if the chart cannot be loaded. + + +``` +helm dependency list CHART [flags] +``` + +### Options + +``` + -h, --help help for list + --max-col-width uint maximum column width for output table (default 80) +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm dependency](helm_dependency.md) - manage a chart's dependencies + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_dependency_update.md b/content/en/docs/helm/helm_dependency_update.md new file mode 100644 index 0000000000..b484c0dd97 --- /dev/null +++ b/content/en/docs/helm/helm_dependency_update.md @@ -0,0 +1,63 @@ +--- +title: "Helm Dependency Update" +--- + +## helm dependency update + +update charts/ based on the contents of Chart.yaml + +### Synopsis + + +Update the on-disk dependencies to mirror Chart.yaml. + +This command verifies that the required charts, as expressed in 'Chart.yaml', +are present in 'charts/' and are at an acceptable version. It will pull down +the latest charts that satisfy the dependencies, and clean up old dependencies. + +On successful update, this will generate a lock file that can be used to +rebuild the dependencies to an exact version. + +Dependencies are not required to be represented in 'Chart.yaml'. For that +reason, an update command will not remove charts unless they are (a) present +in the Chart.yaml file, but (b) at the wrong version. + + +``` +helm dependency update CHART [flags] +``` + +### Options + +``` + -h, --help help for update + --keyring string keyring containing public keys (default "~/.gnupg/pubring.gpg") + --skip-refresh do not refresh the local repository cache + --verify verify the packages against signatures +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm dependency](helm_dependency.md) - manage a chart's dependencies + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_env.md b/content/en/docs/helm/helm_env.md new file mode 100644 index 0000000000..da580b16e1 --- /dev/null +++ b/content/en/docs/helm/helm_env.md @@ -0,0 +1,49 @@ +--- +title: "Helm Env" +--- + +## helm env + +helm client environment information + +### Synopsis + + +Env prints out all the environment information in use by Helm. + + +``` +helm env [flags] +``` + +### Options + +``` + -h, --help help for env +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm](helm.md) - The Helm package manager for Kubernetes. + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_get.md b/content/en/docs/helm/helm_get.md new file mode 100644 index 0000000000..2c42bcd808 --- /dev/null +++ b/content/en/docs/helm/helm_get.md @@ -0,0 +1,56 @@ +--- +title: "Helm Get" +--- + +## helm get + +download extended information of a named release + +### Synopsis + + +This command consists of multiple subcommands which can be used to +get extended information about the release, including: + +- The values used to generate the release +- The generated manifest file +- The notes provided by the chart of the release +- The hooks associated with the release + + +### Options + +``` + -h, --help help for get +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm](helm.md) - The Helm package manager for Kubernetes. +* [helm get all](helm_get_all.md) - download all information for a named release +* [helm get hooks](helm_get_hooks.md) - download all hooks for a named release +* [helm get manifest](helm_get_manifest.md) - download the manifest for a named release +* [helm get notes](helm_get_notes.md) - download the notes for a named release +* [helm get values](helm_get_values.md) - download the values file for a named release + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_get_all.md b/content/en/docs/helm/helm_get_all.md new file mode 100644 index 0000000000..f955052092 --- /dev/null +++ b/content/en/docs/helm/helm_get_all.md @@ -0,0 +1,52 @@ +--- +title: "Helm Get All" +--- + +## helm get all + +download all information for a named release + +### Synopsis + + +This command prints a human readable collection of information about the +notes, hooks, supplied values, and generated manifest file of the given release. + + +``` +helm get all RELEASE_NAME [flags] +``` + +### Options + +``` + -h, --help help for all + --revision int get the named release with revision + --template string go template for formatting the output, eg: {{.Release.Name}} +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm get](helm_get.md) - download extended information of a named release + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_get_hooks.md b/content/en/docs/helm/helm_get_hooks.md new file mode 100644 index 0000000000..0359e19171 --- /dev/null +++ b/content/en/docs/helm/helm_get_hooks.md @@ -0,0 +1,52 @@ +--- +title: "Helm Get Hooks" +--- + +## helm get hooks + +download all hooks for a named release + +### Synopsis + + +This command downloads hooks for a given release. + +Hooks are formatted in YAML and separated by the YAML '---\n' separator. + + +``` +helm get hooks RELEASE_NAME [flags] +``` + +### Options + +``` + -h, --help help for hooks + --revision int get the named release with revision +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm get](helm_get.md) - download extended information of a named release + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_get_manifest.md b/content/en/docs/helm/helm_get_manifest.md new file mode 100644 index 0000000000..ad9130851e --- /dev/null +++ b/content/en/docs/helm/helm_get_manifest.md @@ -0,0 +1,54 @@ +--- +title: "Helm Get Manifest" +--- + +## helm get manifest + +download the manifest for a named release + +### Synopsis + + +This command fetches the generated manifest for a given release. + +A manifest is a YAML-encoded representation of the Kubernetes resources that +were generated from this release's chart(s). If a chart is dependent on other +charts, those resources will also be included in the manifest. + + +``` +helm get manifest RELEASE_NAME [flags] +``` + +### Options + +``` + -h, --help help for manifest + --revision int get the named release with revision +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm get](helm_get.md) - download extended information of a named release + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_get_notes.md b/content/en/docs/helm/helm_get_notes.md new file mode 100644 index 0000000000..58f75c20d8 --- /dev/null +++ b/content/en/docs/helm/helm_get_notes.md @@ -0,0 +1,50 @@ +--- +title: "Helm Get Notes" +--- + +## helm get notes + +download the notes for a named release + +### Synopsis + + +This command shows notes provided by the chart of a named release. + + +``` +helm get notes RELEASE_NAME [flags] +``` + +### Options + +``` + -h, --help help for notes + --revision int get the named release with revision +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm get](helm_get.md) - download extended information of a named release + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_get_values.md b/content/en/docs/helm/helm_get_values.md new file mode 100644 index 0000000000..bba37dfc3b --- /dev/null +++ b/content/en/docs/helm/helm_get_values.md @@ -0,0 +1,52 @@ +--- +title: "Helm Get Values" +--- + +## helm get values + +download the values file for a named release + +### Synopsis + + +This command downloads a values file for a given release. + + +``` +helm get values RELEASE_NAME [flags] +``` + +### Options + +``` + -a, --all dump all (computed) values + -h, --help help for values + -o, --output format prints the output in the specified format. Allowed values: table, json, yaml (default table) + --revision int get the named release with revision +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm get](helm_get.md) - download extended information of a named release + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_history.md b/content/en/docs/helm/helm_history.md new file mode 100644 index 0000000000..cd71987bc2 --- /dev/null +++ b/content/en/docs/helm/helm_history.md @@ -0,0 +1,63 @@ +--- +title: "Helm History" +--- + +## helm history + +fetch release history + +### Synopsis + + +History prints historical revisions for a given release. + +A default maximum of 256 revisions will be returned. Setting '--max' +configures the maximum length of the revision list returned. + +The historical release set is printed as a formatted table, e.g: + + $ helm history angry-bird + REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION + 1 Mon Oct 3 10:15:13 2016 superseded alpine-0.1.0 1.0 Initial install + 2 Mon Oct 3 10:15:13 2016 superseded alpine-0.1.0 1.0 Upgraded successfully + 3 Mon Oct 3 10:15:13 2016 superseded alpine-0.1.0 1.0 Rolled back to 2 + 4 Mon Oct 3 10:15:13 2016 deployed alpine-0.1.0 1.0 Upgraded successfully + + +``` +helm history RELEASE_NAME [flags] +``` + +### Options + +``` + -h, --help help for history + --max int maximum number of revision to include in history (default 256) + -o, --output format prints the output in the specified format. Allowed values: table, json, yaml (default table) +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm](helm.md) - The Helm package manager for Kubernetes. + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_init.md b/content/en/docs/helm/helm_init.md new file mode 100644 index 0000000000..634843c6b9 --- /dev/null +++ b/content/en/docs/helm/helm_init.md @@ -0,0 +1,9 @@ +--- +section: deprecated +--- + +## helm init + +This command does not exist in Helm 3, following the [removal of Tiller](https://helm.sh/docs/faq/#removal-of-tiller). You no longer need to install Tiller in your cluster in order to use Helm. + +If you are using Helm 2, go to [v2.helm.sh](https://v2.helm.sh/docs/helm/#helm-init) to view the [Helm Init documentation](https://v2.helm.sh/docs/helm/#helm-init). diff --git a/content/en/docs/helm/helm_inspect.md b/content/en/docs/helm/helm_inspect.md new file mode 100644 index 0000000000..e4d1c41a16 --- /dev/null +++ b/content/en/docs/helm/helm_inspect.md @@ -0,0 +1,7 @@ +--- +section: deprecated +--- + +## helm inspect + +This command has been renamed. Please refer instead to [helm show](../helm_show/). diff --git a/content/en/docs/helm/helm_install.md b/content/en/docs/helm/helm_install.md new file mode 100644 index 0000000000..06ebc9313e --- /dev/null +++ b/content/en/docs/helm/helm_install.md @@ -0,0 +1,163 @@ +--- +title: "Helm Install" +--- + +## helm install + +install a chart + +### Synopsis + + +This command installs a chart archive. + +The install argument must be a chart reference, a path to a packaged chart, +a path to an unpacked chart directory or a URL. + +To override values in a chart, use either the '--values' flag and pass in a file +or use the '--set' flag and pass configuration from the command line, to force +a string value use '--set-string'. You can use '--set-file' to set individual +values from a file when the value itself is too long for the command line +or is dynamically generated. You can also use '--set-json' to set json values +(scalars/objects/arrays) from the command line. + + $ helm install -f myvalues.yaml myredis ./redis + +or + + $ helm install --set name=prod myredis ./redis + +or + + $ helm install --set-string long_int=1234567890 myredis ./redis + +or + + $ helm install --set-file my_script=dothings.sh myredis ./redis + +or + + $ helm install --set-json 'master.sidecars=[{"name":"sidecar","image":"myImage","imagePullPolicy":"Always","ports":[{"name":"portname","containerPort":1234}]}]' myredis ./redis + + +You can specify the '--values'/'-f' flag multiple times. The priority will be given to the +last (right-most) file specified. For example, if both myvalues.yaml and override.yaml +contained a key called 'Test', the value set in override.yaml would take precedence: + + $ helm install -f myvalues.yaml -f override.yaml myredis ./redis + +You can specify the '--set' flag multiple times. The priority will be given to the +last (right-most) set specified. For example, if both 'bar' and 'newbar' values are +set for a key called 'foo', the 'newbar' value would take precedence: + + $ helm install --set foo=bar --set foo=newbar myredis ./redis + +Similarly, in the following example 'foo' is set to '["four"]': + + $ helm install --set-json='foo=["one", "two", "three"]' --set-json='foo=["four"]' myredis ./redis + +And in the following example, 'foo' is set to '{"key1":"value1","key2":"bar"}': + + $ helm install --set-json='foo={"key1":"value1","key2":"value2"}' --set-json='foo.key2="bar"' myredis ./redis + +To check the generated manifests of a release without installing the chart, +the '--debug' and '--dry-run' flags can be combined. + +If --verify is set, the chart MUST have a provenance file, and the provenance +file MUST pass all verification steps. + +There are six different ways you can express the chart you want to install: + +1. By chart reference: helm install mymaria example/mariadb +2. By path to a packaged chart: helm install mynginx ./nginx-1.2.3.tgz +3. By path to an unpacked chart directory: helm install mynginx ./nginx +4. By absolute URL: helm install mynginx https://example.com/charts/nginx-1.2.3.tgz +5. By chart reference and repo url: helm install --repo https://example.com/charts/ mynginx nginx +6. By OCI registries: helm install mynginx --version 1.2.3 oci://example.com/charts/nginx + +CHART REFERENCES + +A chart reference is a convenient way of referencing a chart in a chart repository. + +When you use a chart reference with a repo prefix ('example/mariadb'), Helm will look in the local +configuration for a chart repository named 'example', and will then look for a +chart in that repository whose name is 'mariadb'. It will install the latest stable version of that chart +until you specify '--devel' flag to also include development version (alpha, beta, and release candidate releases), or +supply a version number with the '--version' flag. + +To see the list of chart repositories, use 'helm repo list'. To search for +charts in a repository, use 'helm search'. + + +``` +helm install [NAME] [CHART] [flags] +``` + +### Options + +``` + --atomic if set, the installation process deletes the installation on failure. The --wait flag will be set automatically if --atomic is used + --ca-file string verify certificates of HTTPS-enabled servers using this CA bundle + --cert-file string identify HTTPS client using this SSL certificate file + --create-namespace create the release namespace if not present + --dependency-update update dependencies if they are missing before installing the chart + --description string add a custom description + --devel use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored + --disable-openapi-validation if set, the installation process will not validate rendered templates against the Kubernetes OpenAPI Schema + --dry-run simulate an install + --enable-dns enable DNS lookups when rendering templates + --force force resource updates through a replacement strategy + -g, --generate-name generate the name (and omit the NAME parameter) + -h, --help help for install + --insecure-skip-tls-verify skip tls certificate checks for the chart download + --key-file string identify HTTPS client using this SSL key file + --keyring string location of public keys used for verification (default "~/.gnupg/pubring.gpg") + --name-template string specify template used to name the release + --no-hooks prevent hooks from running during install + -o, --output format prints the output in the specified format. Allowed values: table, json, yaml (default table) + --pass-credentials pass credentials to all domains + --password string chart repository password where to locate the requested chart + --post-renderer postRendererString the path to an executable to be used for post rendering. If it exists in $PATH, the binary will be used, otherwise it will try to look for the executable at the given path + --post-renderer-args postRendererArgsSlice an argument to the post-renderer (can specify multiple) (default []) + --render-subchart-notes if set, render subchart notes along with the parent + --replace re-use the given name, only if that name is a deleted release which remains in the history. This is unsafe in production + --repo string chart repository url where to locate the requested chart + --set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) + --set-file stringArray set values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2) + --set-json stringArray set JSON values on the command line (can specify multiple or separate values with commas: key1=jsonval1,key2=jsonval2) + --set-string stringArray set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) + --skip-crds if set, no CRDs will be installed. By default, CRDs are installed if not already present + --timeout duration time to wait for any individual Kubernetes operation (like Jobs for hooks) (default 5m0s) + --username string chart repository username where to locate the requested chart + -f, --values strings specify values in a YAML file or a URL (can specify multiple) + --verify verify the package before using it + --version string specify a version constraint for the chart version to use. This constraint can be a specific tag (e.g. 1.1.1) or it may reference a valid range (e.g. ^2.0.0). If this is not specified, the latest version is used + --wait if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment, StatefulSet, or ReplicaSet are in a ready state before marking the release as successful. It will wait for as long as --timeout + --wait-for-jobs if set and --wait enabled, will wait until all Jobs have been completed before marking the release as successful. It will wait for as long as --timeout +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm](helm.md) - The Helm package manager for Kubernetes. + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_lint.md b/content/en/docs/helm/helm_lint.md new file mode 100644 index 0000000000..b18207e542 --- /dev/null +++ b/content/en/docs/helm/helm_lint.md @@ -0,0 +1,62 @@ +--- +title: "Helm Lint" +--- + +## helm lint + +examine a chart for possible issues + +### Synopsis + + +This command takes a path to a chart and runs a series of tests to verify that +the chart is well-formed. + +If the linter encounters things that will cause the chart to fail installation, +it will emit [ERROR] messages. If it encounters issues that break with convention +or recommendation, it will emit [WARNING] messages. + + +``` +helm lint PATH [flags] +``` + +### Options + +``` + -h, --help help for lint + --quiet print only warnings and errors + --set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) + --set-file stringArray set values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2) + --set-json stringArray set JSON values on the command line (can specify multiple or separate values with commas: key1=jsonval1,key2=jsonval2) + --set-string stringArray set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) + --strict fail on lint warnings + -f, --values strings specify values in a YAML file or a URL (can specify multiple) + --with-subcharts lint dependent charts +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm](helm.md) - The Helm package manager for Kubernetes. + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_list.md b/content/en/docs/helm/helm_list.md new file mode 100644 index 0000000000..50e50e710b --- /dev/null +++ b/content/en/docs/helm/helm_list.md @@ -0,0 +1,90 @@ +--- +title: "Helm List" +--- + +## helm list + +list releases + +### Synopsis + + +This command lists all of the releases for a specified namespace (uses current namespace context if namespace not specified). + +By default, it lists only releases that are deployed or failed. Flags like +'--uninstalled' and '--all' will alter this behavior. Such flags can be combined: +'--uninstalled --failed'. + +By default, items are sorted alphabetically. Use the '-d' flag to sort by +release date. + +If the --filter flag is provided, it will be treated as a filter. Filters are +regular expressions (Perl compatible) that are applied to the list of releases. +Only items that match the filter will be returned. + + $ helm list --filter 'ara[a-z]+' + NAME UPDATED CHART + maudlin-arachnid 2020-06-18 14:17:46.125134977 +0000 UTC alpine-0.1.0 + +If no results are found, 'helm list' will exit 0, but with no output (or in +the case of no '-q' flag, only headers). + +By default, up to 256 items may be returned. To limit this, use the '--max' flag. +Setting '--max' to 0 will not return all results. Rather, it will return the +server's default, which may be much higher than 256. Pairing the '--max' +flag with the '--offset' flag allows you to page through results. + + +``` +helm list [flags] +``` + +### Options + +``` + -a, --all show all releases without any filter applied + -A, --all-namespaces list releases across all namespaces + -d, --date sort by release date + --deployed show deployed releases. If no other is specified, this will be automatically enabled + --failed show failed releases + -f, --filter string a regular expression (Perl compatible). Any releases that match the expression will be included in the results + -h, --help help for list + -m, --max int maximum number of releases to fetch (default 256) + --no-headers don't print headers when using the default output format + --offset int next release index in the list, used to offset from start value + -o, --output format prints the output in the specified format. Allowed values: table, json, yaml (default table) + --pending show pending releases + -r, --reverse reverse the sort order + -l, --selector string Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2). Works only for secret(default) and configmap storage backends. + -q, --short output short (quiet) listing format + --superseded show superseded releases + --time-format string format time using golang time formatter. Example: --time-format "2006-01-02 15:04:05Z0700" + --uninstalled show uninstalled releases (if 'helm uninstall --keep-history' was used) + --uninstalling show releases that are currently being uninstalled +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm](helm.md) - The Helm package manager for Kubernetes. + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_package.md b/content/en/docs/helm/helm_package.md new file mode 100644 index 0000000000..4657a80904 --- /dev/null +++ b/content/en/docs/helm/helm_package.md @@ -0,0 +1,69 @@ +--- +title: "Helm Package" +--- + +## helm package + +package a chart directory into a chart archive + +### Synopsis + + +This command packages a chart into a versioned chart archive file. If a path +is given, this will look at that path for a chart (which must contain a +Chart.yaml file) and then package that directory. + +Versioned chart archives are used by Helm package repositories. + +To sign a chart, use the '--sign' flag. In most cases, you should also +provide '--keyring path/to/secret/keys' and '--key keyname'. + + $ helm package --sign ./mychart --key mykey --keyring ~/.gnupg/secring.gpg + +If '--keyring' is not specified, Helm usually defaults to the public keyring +unless your environment is otherwise configured. + + +``` +helm package [CHART_PATH] [...] [flags] +``` + +### Options + +``` + --app-version string set the appVersion on the chart to this version + -u, --dependency-update update dependencies from "Chart.yaml" to dir "charts/" before packaging + -d, --destination string location to write the chart. (default ".") + -h, --help help for package + --key string name of the key to use when signing. Used if --sign is true + --keyring string location of a public keyring (default "~/.gnupg/pubring.gpg") + --passphrase-file string location of a file which contains the passphrase for the signing key. Use "-" in order to read from stdin. + --sign use a PGP private key to sign this package + --version string set the version on the chart to this semver version +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm](helm.md) - The Helm package manager for Kubernetes. + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_plugin.md b/content/en/docs/helm/helm_plugin.md new file mode 100644 index 0000000000..1bdd9b3567 --- /dev/null +++ b/content/en/docs/helm/helm_plugin.md @@ -0,0 +1,49 @@ +--- +title: "Helm Plugin" +--- + +## helm plugin + +install, list, or uninstall Helm plugins + +### Synopsis + + +Manage client-side Helm plugins. + + +### Options + +``` + -h, --help help for plugin +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm](helm.md) - The Helm package manager for Kubernetes. +* [helm plugin install](helm_plugin_install.md) - install one or more Helm plugins +* [helm plugin list](helm_plugin_list.md) - list installed Helm plugins +* [helm plugin uninstall](helm_plugin_uninstall.md) - uninstall one or more Helm plugins +* [helm plugin update](helm_plugin_update.md) - update one or more Helm plugins + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_plugin_install.md b/content/en/docs/helm/helm_plugin_install.md new file mode 100644 index 0000000000..36d621207e --- /dev/null +++ b/content/en/docs/helm/helm_plugin_install.md @@ -0,0 +1,50 @@ +--- +title: "Helm Plugin Install" +--- + +## helm plugin install + +install one or more Helm plugins + +### Synopsis + + +This command allows you to install a plugin from a url to a VCS repo or a local path. + + +``` +helm plugin install [options] ... [flags] +``` + +### Options + +``` + -h, --help help for install + --version string specify a version constraint. If this is not specified, the latest version is installed +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm plugin](helm_plugin.md) - install, list, or uninstall Helm plugins + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_plugin_list.md b/content/en/docs/helm/helm_plugin_list.md new file mode 100644 index 0000000000..fc90c5784c --- /dev/null +++ b/content/en/docs/helm/helm_plugin_list.md @@ -0,0 +1,43 @@ +--- +title: "Helm Plugin List" +--- + +## helm plugin list + +list installed Helm plugins + +``` +helm plugin list [flags] +``` + +### Options + +``` + -h, --help help for list +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm plugin](helm_plugin.md) - install, list, or uninstall Helm plugins + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_plugin_uninstall.md b/content/en/docs/helm/helm_plugin_uninstall.md new file mode 100644 index 0000000000..897b770635 --- /dev/null +++ b/content/en/docs/helm/helm_plugin_uninstall.md @@ -0,0 +1,43 @@ +--- +title: "Helm Plugin Uninstall" +--- + +## helm plugin uninstall + +uninstall one or more Helm plugins + +``` +helm plugin uninstall ... [flags] +``` + +### Options + +``` + -h, --help help for uninstall +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm plugin](helm_plugin.md) - install, list, or uninstall Helm plugins + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_plugin_update.md b/content/en/docs/helm/helm_plugin_update.md new file mode 100644 index 0000000000..d76e18bcaa --- /dev/null +++ b/content/en/docs/helm/helm_plugin_update.md @@ -0,0 +1,43 @@ +--- +title: "Helm Plugin Update" +--- + +## helm plugin update + +update one or more Helm plugins + +``` +helm plugin update ... [flags] +``` + +### Options + +``` + -h, --help help for update +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm plugin](helm_plugin.md) - install, list, or uninstall Helm plugins + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_pull.md b/content/en/docs/helm/helm_pull.md new file mode 100644 index 0000000000..68d7c818a8 --- /dev/null +++ b/content/en/docs/helm/helm_pull.md @@ -0,0 +1,76 @@ +--- +title: "Helm Pull" +--- + +## helm pull + +download a chart from a repository and (optionally) unpack it in local directory + +### Synopsis + + +Retrieve a package from a package repository, and download it locally. + +This is useful for fetching packages to inspect, modify, or repackage. It can +also be used to perform cryptographic verification of a chart without installing +the chart. + +There are options for unpacking the chart after download. This will create a +directory for the chart and uncompress into that directory. + +If the --verify flag is specified, the requested chart MUST have a provenance +file, and MUST pass the verification process. Failure in any part of this will +result in an error, and the chart will not be saved locally. + + +``` +helm pull [chart URL | repo/chartname] [...] [flags] +``` + +### Options + +``` + --ca-file string verify certificates of HTTPS-enabled servers using this CA bundle + --cert-file string identify HTTPS client using this SSL certificate file + -d, --destination string location to write the chart. If this and untardir are specified, untardir is appended to this (default ".") + --devel use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored. + -h, --help help for pull + --insecure-skip-tls-verify skip tls certificate checks for the chart download + --key-file string identify HTTPS client using this SSL key file + --keyring string location of public keys used for verification (default "~/.gnupg/pubring.gpg") + --pass-credentials pass credentials to all domains + --password string chart repository password where to locate the requested chart + --prov fetch the provenance file, but don't perform verification + --repo string chart repository url where to locate the requested chart + --untar if set to true, will untar the chart after downloading it + --untardir string if untar is specified, this flag specifies the name of the directory into which the chart is expanded (default ".") + --username string chart repository username where to locate the requested chart + --verify verify the package before using it + --version string specify a version constraint for the chart version to use. This constraint can be a specific tag (e.g. 1.1.1) or it may reference a valid range (e.g. ^2.0.0). If this is not specified, the latest version is used +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm](helm.md) - The Helm package manager for Kubernetes. + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_push.md b/content/en/docs/helm/helm_push.md new file mode 100644 index 0000000000..f7e403d547 --- /dev/null +++ b/content/en/docs/helm/helm_push.md @@ -0,0 +1,52 @@ +--- +title: "Helm Push" +--- + +## helm push + +push a chart to remote + +### Synopsis + + +Upload a chart to a registry. + +If the chart has an associated provenance file, +it will also be uploaded. + + +``` +helm push [chart] [remote] [flags] +``` + +### Options + +``` + -h, --help help for push +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm](helm.md) - The Helm package manager for Kubernetes. + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_registry.md b/content/en/docs/helm/helm_registry.md new file mode 100644 index 0000000000..142ae857e0 --- /dev/null +++ b/content/en/docs/helm/helm_registry.md @@ -0,0 +1,47 @@ +--- +title: "Helm Registry" +--- + +## helm registry + +login to or logout from a registry + +### Synopsis + + +This command consists of multiple subcommands to interact with registries. + + +### Options + +``` + -h, --help help for registry +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm](helm.md) - The Helm package manager for Kubernetes. +* [helm registry login](helm_registry_login.md) - login to a registry +* [helm registry logout](helm_registry_logout.md) - logout from a registry + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_registry_login.md b/content/en/docs/helm/helm_registry_login.md new file mode 100644 index 0000000000..fb7b216c96 --- /dev/null +++ b/content/en/docs/helm/helm_registry_login.md @@ -0,0 +1,53 @@ +--- +title: "Helm Registry Login" +--- + +## helm registry login + +login to a registry + +### Synopsis + + +Authenticate to a remote registry. + + +``` +helm registry login [host] [flags] +``` + +### Options + +``` + -h, --help help for login + --insecure allow connections to TLS registry without certs + -p, --password string registry password or identity token + --password-stdin read password or identity token from stdin + -u, --username string registry username +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm registry](helm_registry.md) - login to or logout from a registry + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_registry_logout.md b/content/en/docs/helm/helm_registry_logout.md new file mode 100644 index 0000000000..5a844cdea1 --- /dev/null +++ b/content/en/docs/helm/helm_registry_logout.md @@ -0,0 +1,49 @@ +--- +title: "Helm Registry Logout" +--- + +## helm registry logout + +logout from a registry + +### Synopsis + + +Remove credentials stored for a remote registry. + + +``` +helm registry logout [host] [flags] +``` + +### Options + +``` + -h, --help help for logout +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm registry](helm_registry.md) - login to or logout from a registry + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_repo.md b/content/en/docs/helm/helm_repo.md new file mode 100644 index 0000000000..99bc87ea7d --- /dev/null +++ b/content/en/docs/helm/helm_repo.md @@ -0,0 +1,52 @@ +--- +title: "Helm Repo" +--- + +## helm repo + +add, list, remove, update, and index chart repositories + +### Synopsis + + +This command consists of multiple subcommands to interact with chart repositories. + +It can be used to add, remove, list, and index chart repositories. + + +### Options + +``` + -h, --help help for repo +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm](helm.md) - The Helm package manager for Kubernetes. +* [helm repo add](helm_repo_add.md) - add a chart repository +* [helm repo index](helm_repo_index.md) - generate an index file given a directory containing packaged charts +* [helm repo list](helm_repo_list.md) - list chart repositories +* [helm repo remove](helm_repo_remove.md) - remove one or more chart repositories +* [helm repo update](helm_repo_update.md) - update information of available charts locally from chart repositories + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_repo_add.md b/content/en/docs/helm/helm_repo_add.md new file mode 100644 index 0000000000..7b4e67605e --- /dev/null +++ b/content/en/docs/helm/helm_repo_add.md @@ -0,0 +1,54 @@ +--- +title: "Helm Repo Add" +--- + +## helm repo add + +add a chart repository + +``` +helm repo add [NAME] [URL] [flags] +``` + +### Options + +``` + --allow-deprecated-repos by default, this command will not allow adding official repos that have been permanently deleted. This disables that behavior + --ca-file string verify certificates of HTTPS-enabled servers using this CA bundle + --cert-file string identify HTTPS client using this SSL certificate file + --force-update replace (overwrite) the repo if it already exists + -h, --help help for add + --insecure-skip-tls-verify skip tls certificate checks for the repository + --key-file string identify HTTPS client using this SSL key file + --no-update Ignored. Formerly, it would disabled forced updates. It is deprecated by force-update. + --pass-credentials pass credentials to all domains + --password string chart repository password + --password-stdin read chart repository password from stdin + --username string chart repository username +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm repo](helm_repo.md) - add, list, remove, update, and index chart repositories + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_repo_index.md b/content/en/docs/helm/helm_repo_index.md new file mode 100644 index 0000000000..c605179e53 --- /dev/null +++ b/content/en/docs/helm/helm_repo_index.md @@ -0,0 +1,58 @@ +--- +title: "Helm Repo Index" +--- + +## helm repo index + +generate an index file given a directory containing packaged charts + +### Synopsis + + +Read the current directory and generate an index file based on the charts found. + +This tool is used for creating an 'index.yaml' file for a chart repository. To +set an absolute URL to the charts, use '--url' flag. + +To merge the generated index with an existing index file, use the '--merge' +flag. In this case, the charts found in the current directory will be merged +into the existing index, with local charts taking priority over existing charts. + + +``` +helm repo index [DIR] [flags] +``` + +### Options + +``` + -h, --help help for index + --merge string merge the generated index into the given index + --url string url of chart repository +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm repo](helm_repo.md) - add, list, remove, update, and index chart repositories + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_repo_list.md b/content/en/docs/helm/helm_repo_list.md new file mode 100644 index 0000000000..bdbc1eac49 --- /dev/null +++ b/content/en/docs/helm/helm_repo_list.md @@ -0,0 +1,44 @@ +--- +title: "Helm Repo List" +--- + +## helm repo list + +list chart repositories + +``` +helm repo list [flags] +``` + +### Options + +``` + -h, --help help for list + -o, --output format prints the output in the specified format. Allowed values: table, json, yaml (default table) +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm repo](helm_repo.md) - add, list, remove, update, and index chart repositories + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_repo_remove.md b/content/en/docs/helm/helm_repo_remove.md new file mode 100644 index 0000000000..cd9c8e6a5b --- /dev/null +++ b/content/en/docs/helm/helm_repo_remove.md @@ -0,0 +1,43 @@ +--- +title: "Helm Repo Remove" +--- + +## helm repo remove + +remove one or more chart repositories + +``` +helm repo remove [REPO1 [REPO2 ...]] [flags] +``` + +### Options + +``` + -h, --help help for remove +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm repo](helm_repo.md) - add, list, remove, update, and index chart repositories + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_repo_update.md b/content/en/docs/helm/helm_repo_update.md new file mode 100644 index 0000000000..07f2ba183a --- /dev/null +++ b/content/en/docs/helm/helm_repo_update.md @@ -0,0 +1,55 @@ +--- +title: "Helm Repo Update" +--- + +## helm repo update + +update information of available charts locally from chart repositories + +### Synopsis + + +Update gets the latest information about charts from the respective chart repositories. +Information is cached locally, where it is used by commands like 'helm search'. + +You can optionally specify a list of repositories you want to update. + $ helm repo update ... +To update all the repositories, use 'helm repo update'. + + +``` +helm repo update [REPO1 [REPO2 ...]] [flags] +``` + +### Options + +``` + --fail-on-repo-update-fail update fails if any of the repository updates fail + -h, --help help for update +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm repo](helm_repo.md) - add, list, remove, update, and index chart repositories + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_rollback.md b/content/en/docs/helm/helm_rollback.md new file mode 100644 index 0000000000..43f2bc52b2 --- /dev/null +++ b/content/en/docs/helm/helm_rollback.md @@ -0,0 +1,64 @@ +--- +title: "Helm Rollback" +--- + +## helm rollback + +roll back a release to a previous revision + +### Synopsis + + +This command rolls back a release to a previous revision. + +The first argument of the rollback command is the name of a release, and the +second is a revision (version) number. If this argument is omitted, it will +roll back to the previous release. + +To see revision numbers, run 'helm history RELEASE'. + + +``` +helm rollback [REVISION] [flags] +``` + +### Options + +``` + --cleanup-on-fail allow deletion of new resources created in this rollback when rollback fails + --dry-run simulate a rollback + --force force resource update through delete/recreate if needed + -h, --help help for rollback + --history-max int limit the maximum number of revisions saved per release. Use 0 for no limit (default 10) + --no-hooks prevent hooks from running during rollback + --recreate-pods performs pods restart for the resource if applicable + --timeout duration time to wait for any individual Kubernetes operation (like Jobs for hooks) (default 5m0s) + --wait if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment, StatefulSet, or ReplicaSet are in a ready state before marking the release as successful. It will wait for as long as --timeout + --wait-for-jobs if set and --wait enabled, will wait until all Jobs have been completed before marking the release as successful. It will wait for as long as --timeout +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm](helm.md) - The Helm package manager for Kubernetes. + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_search.md b/content/en/docs/helm/helm_search.md new file mode 100644 index 0000000000..17f3a51538 --- /dev/null +++ b/content/en/docs/helm/helm_search.md @@ -0,0 +1,49 @@ +--- +title: "Helm Search" +--- + +## helm search + +search for a keyword in charts + +### Synopsis + + +Search provides the ability to search for Helm charts in the various places +they can be stored including the Artifact Hub and repositories you have added. +Use search subcommands to search different locations for charts. + + +### Options + +``` + -h, --help help for search +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm](helm.md) - The Helm package manager for Kubernetes. +* [helm search hub](helm_search_hub.md) - search for charts in the Artifact Hub or your own hub instance +* [helm search repo](helm_search_repo.md) - search repositories for a keyword in charts + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_search_hub.md b/content/en/docs/helm/helm_search_hub.md new file mode 100644 index 0000000000..63425a46da --- /dev/null +++ b/content/en/docs/helm/helm_search_hub.md @@ -0,0 +1,69 @@ +--- +title: "Helm Search Hub" +--- + +## helm search hub + +search for charts in the Artifact Hub or your own hub instance + +### Synopsis + + +Search for Helm charts in the Artifact Hub or your own hub instance. + +Artifact Hub is a web-based application that enables finding, installing, and +publishing packages and configurations for CNCF projects, including publicly +available distributed charts Helm charts. It is a Cloud Native Computing +Foundation sandbox project. You can browse the hub at https://artifacthub.io/ + +The [KEYWORD] argument accepts either a keyword string, or quoted string of rich +query options. For rich query options documentation, see +https://artifacthub.github.io/hub/api/?urls.primaryName=Monocular%20compatible%20search%20API#/Monocular/get_api_chartsvc_v1_charts_search + +Previous versions of Helm used an instance of Monocular as the default +'endpoint', so for backwards compatibility Artifact Hub is compatible with the +Monocular search API. Similarly, when setting the 'endpoint' flag, the specified +endpoint must also be implement a Monocular compatible search API endpoint. +Note that when specifying a Monocular instance as the 'endpoint', rich queries +are not supported. For API details, see https://github.com/helm/monocular + + +``` +helm search hub [KEYWORD] [flags] +``` + +### Options + +``` + --endpoint string Hub instance to query for charts (default "https://hub.helm.sh") + -h, --help help for hub + --list-repo-url print charts repository URL + --max-col-width uint maximum column width for output table (default 50) + -o, --output format prints the output in the specified format. Allowed values: table, json, yaml (default table) +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm search](helm_search.md) - search for a keyword in charts + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_search_repo.md b/content/en/docs/helm/helm_search_repo.md new file mode 100644 index 0000000000..c4037c5b4e --- /dev/null +++ b/content/en/docs/helm/helm_search_repo.md @@ -0,0 +1,74 @@ +--- +title: "Helm Search Repo" +--- + +## helm search repo + +search repositories for a keyword in charts + +### Synopsis + + +Search reads through all of the repositories configured on the system, and +looks for matches. Search of these repositories uses the metadata stored on +the system. + +It will display the latest stable versions of the charts found. If you +specify the --devel flag, the output will include pre-release versions. +If you want to search using a version constraint, use --version. + +Examples: + + # Search for stable release versions matching the keyword "nginx" + $ helm search repo nginx + + # Search for release versions matching the keyword "nginx", including pre-release versions + $ helm search repo nginx --devel + + # Search for the latest stable release for nginx-ingress with a major version of 1 + $ helm search repo nginx-ingress --version ^1.0.0 + +Repositories are managed with 'helm repo' commands. + + +``` +helm search repo [keyword] [flags] +``` + +### Options + +``` + --devel use development versions (alpha, beta, and release candidate releases), too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored + -h, --help help for repo + --max-col-width uint maximum column width for output table (default 50) + -o, --output format prints the output in the specified format. Allowed values: table, json, yaml (default table) + -r, --regexp use regular expressions for searching repositories you have added + --version string search using semantic versioning constraints on repositories you have added + -l, --versions show the long listing, with each version of each chart on its own line, for repositories you have added +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm search](helm_search.md) - search for a keyword in charts + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_show.md b/content/en/docs/helm/helm_show.md new file mode 100644 index 0000000000..65fa34235b --- /dev/null +++ b/content/en/docs/helm/helm_show.md @@ -0,0 +1,50 @@ +--- +title: "Helm Show" +--- + +## helm show + +show information of a chart + +### Synopsis + + +This command consists of multiple subcommands to display information about a chart + + +### Options + +``` + -h, --help help for show +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm](helm.md) - The Helm package manager for Kubernetes. +* [helm show all](helm_show_all.md) - show all information of the chart +* [helm show chart](helm_show_chart.md) - show the chart's definition +* [helm show crds](helm_show_crds.md) - show the chart's CRDs +* [helm show readme](helm_show_readme.md) - show the chart's README +* [helm show values](helm_show_values.md) - show the chart's values + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_show_all.md b/content/en/docs/helm/helm_show_all.md new file mode 100644 index 0000000000..a65a753d63 --- /dev/null +++ b/content/en/docs/helm/helm_show_all.md @@ -0,0 +1,62 @@ +--- +title: "Helm Show All" +--- + +## helm show all + +show all information of the chart + +### Synopsis + + +This command inspects a chart (directory, file, or URL) and displays all its content +(values.yaml, Chart.yaml, README) + + +``` +helm show all [CHART] [flags] +``` + +### Options + +``` + --ca-file string verify certificates of HTTPS-enabled servers using this CA bundle + --cert-file string identify HTTPS client using this SSL certificate file + --devel use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored + -h, --help help for all + --insecure-skip-tls-verify skip tls certificate checks for the chart download + --key-file string identify HTTPS client using this SSL key file + --keyring string location of public keys used for verification (default "~/.gnupg/pubring.gpg") + --pass-credentials pass credentials to all domains + --password string chart repository password where to locate the requested chart + --repo string chart repository url where to locate the requested chart + --username string chart repository username where to locate the requested chart + --verify verify the package before using it + --version string specify a version constraint for the chart version to use. This constraint can be a specific tag (e.g. 1.1.1) or it may reference a valid range (e.g. ^2.0.0). If this is not specified, the latest version is used +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm show](helm_show.md) - show information of a chart + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_show_chart.md b/content/en/docs/helm/helm_show_chart.md new file mode 100644 index 0000000000..5e6cd96075 --- /dev/null +++ b/content/en/docs/helm/helm_show_chart.md @@ -0,0 +1,62 @@ +--- +title: "Helm Show Chart" +--- + +## helm show chart + +show the chart's definition + +### Synopsis + + +This command inspects a chart (directory, file, or URL) and displays the contents +of the Chart.yaml file + + +``` +helm show chart [CHART] [flags] +``` + +### Options + +``` + --ca-file string verify certificates of HTTPS-enabled servers using this CA bundle + --cert-file string identify HTTPS client using this SSL certificate file + --devel use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored + -h, --help help for chart + --insecure-skip-tls-verify skip tls certificate checks for the chart download + --key-file string identify HTTPS client using this SSL key file + --keyring string location of public keys used for verification (default "~/.gnupg/pubring.gpg") + --pass-credentials pass credentials to all domains + --password string chart repository password where to locate the requested chart + --repo string chart repository url where to locate the requested chart + --username string chart repository username where to locate the requested chart + --verify verify the package before using it + --version string specify a version constraint for the chart version to use. This constraint can be a specific tag (e.g. 1.1.1) or it may reference a valid range (e.g. ^2.0.0). If this is not specified, the latest version is used +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm show](helm_show.md) - show information of a chart + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_show_crds.md b/content/en/docs/helm/helm_show_crds.md new file mode 100644 index 0000000000..7ba9b6a0f7 --- /dev/null +++ b/content/en/docs/helm/helm_show_crds.md @@ -0,0 +1,62 @@ +--- +title: "Helm Show Crds" +--- + +## helm show crds + +show the chart's CRDs + +### Synopsis + + +This command inspects a chart (directory, file, or URL) and displays the contents +of the CustomResourceDefinition files + + +``` +helm show crds [CHART] [flags] +``` + +### Options + +``` + --ca-file string verify certificates of HTTPS-enabled servers using this CA bundle + --cert-file string identify HTTPS client using this SSL certificate file + --devel use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored + -h, --help help for crds + --insecure-skip-tls-verify skip tls certificate checks for the chart download + --key-file string identify HTTPS client using this SSL key file + --keyring string location of public keys used for verification (default "~/.gnupg/pubring.gpg") + --pass-credentials pass credentials to all domains + --password string chart repository password where to locate the requested chart + --repo string chart repository url where to locate the requested chart + --username string chart repository username where to locate the requested chart + --verify verify the package before using it + --version string specify a version constraint for the chart version to use. This constraint can be a specific tag (e.g. 1.1.1) or it may reference a valid range (e.g. ^2.0.0). If this is not specified, the latest version is used +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm show](helm_show.md) - show information of a chart + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_show_readme.md b/content/en/docs/helm/helm_show_readme.md new file mode 100644 index 0000000000..4ace87419e --- /dev/null +++ b/content/en/docs/helm/helm_show_readme.md @@ -0,0 +1,62 @@ +--- +title: "Helm Show Readme" +--- + +## helm show readme + +show the chart's README + +### Synopsis + + +This command inspects a chart (directory, file, or URL) and displays the contents +of the README file + + +``` +helm show readme [CHART] [flags] +``` + +### Options + +``` + --ca-file string verify certificates of HTTPS-enabled servers using this CA bundle + --cert-file string identify HTTPS client using this SSL certificate file + --devel use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored + -h, --help help for readme + --insecure-skip-tls-verify skip tls certificate checks for the chart download + --key-file string identify HTTPS client using this SSL key file + --keyring string location of public keys used for verification (default "~/.gnupg/pubring.gpg") + --pass-credentials pass credentials to all domains + --password string chart repository password where to locate the requested chart + --repo string chart repository url where to locate the requested chart + --username string chart repository username where to locate the requested chart + --verify verify the package before using it + --version string specify a version constraint for the chart version to use. This constraint can be a specific tag (e.g. 1.1.1) or it may reference a valid range (e.g. ^2.0.0). If this is not specified, the latest version is used +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm show](helm_show.md) - show information of a chart + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_show_values.md b/content/en/docs/helm/helm_show_values.md new file mode 100644 index 0000000000..72cd00e74e --- /dev/null +++ b/content/en/docs/helm/helm_show_values.md @@ -0,0 +1,63 @@ +--- +title: "Helm Show Values" +--- + +## helm show values + +show the chart's values + +### Synopsis + + +This command inspects a chart (directory, file, or URL) and displays the contents +of the values.yaml file + + +``` +helm show values [CHART] [flags] +``` + +### Options + +``` + --ca-file string verify certificates of HTTPS-enabled servers using this CA bundle + --cert-file string identify HTTPS client using this SSL certificate file + --devel use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored + -h, --help help for values + --insecure-skip-tls-verify skip tls certificate checks for the chart download + --jsonpath string supply a JSONPath expression to filter the output + --key-file string identify HTTPS client using this SSL key file + --keyring string location of public keys used for verification (default "~/.gnupg/pubring.gpg") + --pass-credentials pass credentials to all domains + --password string chart repository password where to locate the requested chart + --repo string chart repository url where to locate the requested chart + --username string chart repository username where to locate the requested chart + --verify verify the package before using it + --version string specify a version constraint for the chart version to use. This constraint can be a specific tag (e.g. 1.1.1) or it may reference a valid range (e.g. ^2.0.0). If this is not specified, the latest version is used +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm show](helm_show.md) - show information of a chart + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_status.md b/content/en/docs/helm/helm_status.md new file mode 100644 index 0000000000..3f47027eaf --- /dev/null +++ b/content/en/docs/helm/helm_status.md @@ -0,0 +1,62 @@ +--- +title: "Helm Status" +--- + +## helm status + +display the status of the named release + +### Synopsis + + +This command shows the status of a named release. +The status consists of: +- last deployment time +- k8s namespace in which the release lives +- state of the release (can be: unknown, deployed, uninstalled, superseded, failed, uninstalling, pending-install, pending-upgrade or pending-rollback) +- revision of the release +- description of the release (can be completion message or error message, need to enable --show-desc) +- list of resources that this release consists of (need to enable --show-resources) +- details on last test suite run, if applicable +- additional notes provided by the chart + + +``` +helm status RELEASE_NAME [flags] +``` + +### Options + +``` + -h, --help help for status + -o, --output format prints the output in the specified format. Allowed values: table, json, yaml (default table) + --revision int if set, display the status of the named release with revision + --show-desc if set, display the description message of the named release + --show-resources if set, display the resources of the named release +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm](helm.md) - The Helm package manager for Kubernetes. + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_template.md b/content/en/docs/helm/helm_template.md new file mode 100644 index 0000000000..2f14d4e6c1 --- /dev/null +++ b/content/en/docs/helm/helm_template.md @@ -0,0 +1,98 @@ +--- +title: "Helm Template" +--- + +## helm template + +locally render templates + +### Synopsis + + +Render chart templates locally and display the output. + +Any values that would normally be looked up or retrieved in-cluster will be +faked locally. Additionally, none of the server-side testing of chart validity +(e.g. whether an API is supported) is done. + + +``` +helm template [NAME] [CHART] [flags] +``` + +### Options + +``` + -a, --api-versions strings Kubernetes api versions used for Capabilities.APIVersions + --atomic if set, the installation process deletes the installation on failure. The --wait flag will be set automatically if --atomic is used + --ca-file string verify certificates of HTTPS-enabled servers using this CA bundle + --cert-file string identify HTTPS client using this SSL certificate file + --create-namespace create the release namespace if not present + --dependency-update update dependencies if they are missing before installing the chart + --description string add a custom description + --devel use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored + --disable-openapi-validation if set, the installation process will not validate rendered templates against the Kubernetes OpenAPI Schema + --dry-run simulate an install + --enable-dns enable DNS lookups when rendering templates + --force force resource updates through a replacement strategy + -g, --generate-name generate the name (and omit the NAME parameter) + -h, --help help for template + --include-crds include CRDs in the templated output + --insecure-skip-tls-verify skip tls certificate checks for the chart download + --is-upgrade set .Release.IsUpgrade instead of .Release.IsInstall + --key-file string identify HTTPS client using this SSL key file + --keyring string location of public keys used for verification (default "~/.gnupg/pubring.gpg") + --kube-version string Kubernetes version used for Capabilities.KubeVersion + --name-template string specify template used to name the release + --no-hooks prevent hooks from running during install + --output-dir string writes the executed templates to files in output-dir instead of stdout + --pass-credentials pass credentials to all domains + --password string chart repository password where to locate the requested chart + --post-renderer postRendererString the path to an executable to be used for post rendering. If it exists in $PATH, the binary will be used, otherwise it will try to look for the executable at the given path + --post-renderer-args postRendererArgsSlice an argument to the post-renderer (can specify multiple) (default []) + --release-name use release name in the output-dir path. + --render-subchart-notes if set, render subchart notes along with the parent + --replace re-use the given name, only if that name is a deleted release which remains in the history. This is unsafe in production + --repo string chart repository url where to locate the requested chart + --set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) + --set-file stringArray set values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2) + --set-json stringArray set JSON values on the command line (can specify multiple or separate values with commas: key1=jsonval1,key2=jsonval2) + --set-string stringArray set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) + -s, --show-only stringArray only show manifests rendered from the given templates + --skip-crds if set, no CRDs will be installed. By default, CRDs are installed if not already present + --skip-tests skip tests from templated output + --timeout duration time to wait for any individual Kubernetes operation (like Jobs for hooks) (default 5m0s) + --username string chart repository username where to locate the requested chart + --validate validate your manifests against the Kubernetes cluster you are currently pointing at. This is the same validation performed on an install + -f, --values strings specify values in a YAML file or a URL (can specify multiple) + --verify verify the package before using it + --version string specify a version constraint for the chart version to use. This constraint can be a specific tag (e.g. 1.1.1) or it may reference a valid range (e.g. ^2.0.0). If this is not specified, the latest version is used + --wait if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment, StatefulSet, or ReplicaSet are in a ready state before marking the release as successful. It will wait for as long as --timeout + --wait-for-jobs if set and --wait enabled, will wait until all Jobs have been completed before marking the release as successful. It will wait for as long as --timeout +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm](helm.md) - The Helm package manager for Kubernetes. + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_test.md b/content/en/docs/helm/helm_test.md new file mode 100644 index 0000000000..ab6ac63e92 --- /dev/null +++ b/content/en/docs/helm/helm_test.md @@ -0,0 +1,55 @@ +--- +title: "Helm Test" +--- + +## helm test + +run tests for a release + +### Synopsis + + +The test command runs the tests for a release. + +The argument this command takes is the name of a deployed release. +The tests to be run are defined in the chart that was installed. + + +``` +helm test [RELEASE] [flags] +``` + +### Options + +``` + --filter strings specify tests by attribute (currently "name") using attribute=value syntax or '!attribute=value' to exclude a test (can specify multiple or separate values with commas: name=test1,name=test2) + -h, --help help for test + --logs dump the logs from test pods (this runs after all tests are complete, but before any cleanup) + --timeout duration time to wait for any individual Kubernetes operation (like Jobs for hooks) (default 5m0s) +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm](helm.md) - The Helm package manager for Kubernetes. + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_uninstall.md b/content/en/docs/helm/helm_uninstall.md new file mode 100644 index 0000000000..040f9d8c3e --- /dev/null +++ b/content/en/docs/helm/helm_uninstall.md @@ -0,0 +1,61 @@ +--- +title: "Helm Uninstall" +--- + +## helm uninstall + +uninstall a release + +### Synopsis + + +This command takes a release name and uninstalls the release. + +It removes all of the resources associated with the last release of the chart +as well as the release history, freeing it up for future use. + +Use the '--dry-run' flag to see which releases will be uninstalled without actually +uninstalling them. + + +``` +helm uninstall RELEASE_NAME [...] [flags] +``` + +### Options + +``` + --description string add a custom description + --dry-run simulate a uninstall + -h, --help help for uninstall + --keep-history remove all associated resources and mark the release as deleted, but retain the release history + --no-hooks prevent hooks from running during uninstallation + --timeout duration time to wait for any individual Kubernetes operation (like Jobs for hooks) (default 5m0s) + --wait if set, will wait until all the resources are deleted before returning. It will wait for as long as --timeout +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm](helm.md) - The Helm package manager for Kubernetes. + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_upgrade.md b/content/en/docs/helm/helm_upgrade.md new file mode 100644 index 0000000000..abcd83a28c --- /dev/null +++ b/content/en/docs/helm/helm_upgrade.md @@ -0,0 +1,112 @@ +--- +title: "Helm Upgrade" +--- + +## helm upgrade + +upgrade a release + +### Synopsis + + +This command upgrades a release to a new version of a chart. + +The upgrade arguments must be a release and chart. The chart +argument can be either: a chart reference('example/mariadb'), a path to a chart directory, +a packaged chart, or a fully qualified URL. For chart references, the latest +version will be specified unless the '--version' flag is set. + +To override values in a chart, use either the '--values' flag and pass in a file +or use the '--set' flag and pass configuration from the command line, to force string +values, use '--set-string'. You can use '--set-file' to set individual +values from a file when the value itself is too long for the command line +or is dynamically generated. You can also use '--set-json' to set json values +(scalars/objects/arrays) from the command line. + +You can specify the '--values'/'-f' flag multiple times. The priority will be given to the +last (right-most) file specified. For example, if both myvalues.yaml and override.yaml +contained a key called 'Test', the value set in override.yaml would take precedence: + + $ helm upgrade -f myvalues.yaml -f override.yaml redis ./redis + +You can specify the '--set' flag multiple times. The priority will be given to the +last (right-most) set specified. For example, if both 'bar' and 'newbar' values are +set for a key called 'foo', the 'newbar' value would take precedence: + + $ helm upgrade --set foo=bar --set foo=newbar redis ./redis + + +``` +helm upgrade [RELEASE] [CHART] [flags] +``` + +### Options + +``` + --atomic if set, upgrade process rolls back changes made in case of failed upgrade. The --wait flag will be set automatically if --atomic is used + --ca-file string verify certificates of HTTPS-enabled servers using this CA bundle + --cert-file string identify HTTPS client using this SSL certificate file + --cleanup-on-fail allow deletion of new resources created in this upgrade when upgrade fails + --create-namespace if --install is set, create the release namespace if not present + --dependency-update update dependencies if they are missing before installing the chart + --description string add a custom description + --devel use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored + --disable-openapi-validation if set, the upgrade process will not validate rendered templates against the Kubernetes OpenAPI Schema + --dry-run simulate an upgrade + --enable-dns enable DNS lookups when rendering templates + --force force resource updates through a replacement strategy + -h, --help help for upgrade + --history-max int limit the maximum number of revisions saved per release. Use 0 for no limit (default 10) + --insecure-skip-tls-verify skip tls certificate checks for the chart download + -i, --install if a release by this name doesn't already exist, run an install + --key-file string identify HTTPS client using this SSL key file + --keyring string location of public keys used for verification (default "~/.gnupg/pubring.gpg") + --no-hooks disable pre/post upgrade hooks + -o, --output format prints the output in the specified format. Allowed values: table, json, yaml (default table) + --pass-credentials pass credentials to all domains + --password string chart repository password where to locate the requested chart + --post-renderer postRendererString the path to an executable to be used for post rendering. If it exists in $PATH, the binary will be used, otherwise it will try to look for the executable at the given path + --post-renderer-args postRendererArgsSlice an argument to the post-renderer (can specify multiple) (default []) + --render-subchart-notes if set, render subchart notes along with the parent + --repo string chart repository url where to locate the requested chart + --reset-values when upgrading, reset the values to the ones built into the chart + --reuse-values when upgrading, reuse the last release's values and merge in any overrides from the command line via --set and -f. If '--reset-values' is specified, this is ignored + --set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) + --set-file stringArray set values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2) + --set-json stringArray set JSON values on the command line (can specify multiple or separate values with commas: key1=jsonval1,key2=jsonval2) + --set-string stringArray set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) + --skip-crds if set, no CRDs will be installed when an upgrade is performed with install flag enabled. By default, CRDs are installed if not already present, when an upgrade is performed with install flag enabled + --timeout duration time to wait for any individual Kubernetes operation (like Jobs for hooks) (default 5m0s) + --username string chart repository username where to locate the requested chart + -f, --values strings specify values in a YAML file or a URL (can specify multiple) + --verify verify the package before using it + --version string specify a version constraint for the chart version to use. This constraint can be a specific tag (e.g. 1.1.1) or it may reference a valid range (e.g. ^2.0.0). If this is not specified, the latest version is used + --wait if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment, StatefulSet, or ReplicaSet are in a ready state before marking the release as successful. It will wait for as long as --timeout + --wait-for-jobs if set and --wait enabled, will wait until all Jobs have been completed before marking the release as successful. It will wait for as long as --timeout +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm](helm.md) - The Helm package manager for Kubernetes. + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_verify.md b/content/en/docs/helm/helm_verify.md new file mode 100644 index 0000000000..cdbc84520e --- /dev/null +++ b/content/en/docs/helm/helm_verify.md @@ -0,0 +1,57 @@ +--- +title: "Helm Verify" +--- + +## helm verify + +verify that a chart at the given path has been signed and is valid + +### Synopsis + + +Verify that the given chart has a valid provenance file. + +Provenance files provide cryptographic verification that a chart has not been +tampered with, and was packaged by a trusted provider. + +This command can be used to verify a local chart. Several other commands provide +'--verify' flags that run the same validation. To generate a signed package, use +the 'helm package --sign' command. + + +``` +helm verify PATH [flags] +``` + +### Options + +``` + -h, --help help for verify + --keyring string keyring containing public keys (default "~/.gnupg/pubring.gpg") +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm](helm.md) - The Helm package manager for Kubernetes. + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/helm/helm_version.md b/content/en/docs/helm/helm_version.md new file mode 100644 index 0000000000..878d1edbea --- /dev/null +++ b/content/en/docs/helm/helm_version.md @@ -0,0 +1,72 @@ +--- +title: "Helm Version" +--- + +## helm version + +print the client version information + +### Synopsis + + +Show the version for Helm. + +This will print a representation the version of Helm. +The output will look something like this: + +version.BuildInfo{Version:"v3.2.1", GitCommit:"fe51cd1e31e6a202cba7dead9552a6d418ded79a", GitTreeState:"clean", GoVersion:"go1.13.10"} + +- Version is the semantic version of the release. +- GitCommit is the SHA for the commit that this version was built from. +- GitTreeState is "clean" if there are no local code changes when this binary was + built, and "dirty" if the binary was built from locally modified code. +- GoVersion is the version of Go that was used to compile Helm. + +When using the --template flag the following properties are available to use in +the template: + +- .Version contains the semantic version of Helm +- .GitCommit is the git commit +- .GitTreeState is the state of the git tree when Helm was built +- .GoVersion contains the version of Go that Helm was compiled with + +For example, --template='Version: {{.Version}}' outputs 'Version: v3.2.1'. + + +``` +helm version [flags] +``` + +### Options + +``` + -h, --help help for version + --short print the version number + --template string template for version string format +``` + +### Options inherited from parent commands + +``` + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm](helm.md) - The Helm package manager for Kubernetes. + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/en/docs/howto/_index.md b/content/en/docs/howto/_index.md new file mode 100644 index 0000000000..ed03027359 --- /dev/null +++ b/content/en/docs/howto/_index.md @@ -0,0 +1,11 @@ +--- +title: "How-to" +weight: 2 +--- + +# How-to Guides + +Here you’ll find short answers to “How do I….?” types of questions. These how-to +guides don’t cover topics in depth – you’ll find that material in the [Topic +Guides](../topics). However, these guides will help you quickly accomplish +common tasks. diff --git a/content/en/docs/howto/chart_releaser_action.md b/content/en/docs/howto/chart_releaser_action.md new file mode 100644 index 0000000000..672dd19b17 --- /dev/null +++ b/content/en/docs/howto/chart_releaser_action.md @@ -0,0 +1,104 @@ +--- +title: "Chart Releaser Action to Automate GitHub Page Charts" +description: "Describe how to use Chart Releaser Action to automate releasing charts through GitHub pages." +weight: 3 +--- + +This guide describes how to use [Chart Releaser +Action](https://github.com/marketplace/actions/helm-chart-releaser) to automate +releasing charts through GitHub pages. Chart Releaser Action is a GitHub Action +workflow to turn a GitHub project into a self-hosted Helm chart repo, using +[helm/chart-releaser](https://github.com/helm/chart-releaser) CLI tool. + +## Repository Changes + +Create a Git repository under your GitHub organization. You could give the name +of the repository as `helm-charts`, though other names are also acceptable. The +sources of all the charts can be placed under the `main` branch. The charts +should be placed under `/charts` directory at the top-level of the directory +tree. + +There should be another branch named `gh-pages` to publish the charts. The +changes to that branch will be automatically created by the Chart Releaser +Action described here. However, you can create that `gh-branch` and add +`README.md` file, which is going to be visible to the users visiting the page. + +You can add instruction in the `README.md` for charts installation like this +(replace ``, ``, and ``): + +``` +## Usage + +[Helm](https://helm.sh) must be installed to use the charts. Please refer to +Helm's [documentation](https://helm.sh/docs) to get started. + +Once Helm has been set up correctly, add the repo as follows: + + helm repo add https://.github.io/helm-charts + +If you had already added this repo earlier, run `helm repo update` to retrieve +the latest versions of the packages. You can then run `helm search repo +` to see the charts. + +To install the chart: + + helm install my- / + +To uninstall the chart: + + helm delete my- +``` + +The charts will be published to a website with URL like this: + + https://.github.io/helm-charts + +## GitHub Actions Workflow + +Create GitHub Actions workflow file in the `main` branch at +`.github/workflows/release.yml` + +``` +name: Release Charts + +on: + push: + branches: + - main + +jobs: + release: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Configure Git + run: | + git config user.name "$GITHUB_ACTOR" + git config user.email "$GITHUB_ACTOR@users.noreply.github.com" + + - name: Run chart-releaser + uses: helm/chart-releaser-action@v1.5.0 + env: + CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}" +``` + +The above configuration uses +[@helm/chart-releaser-action](https://github.com/helm/chart-releaser-action) to +turn your GitHub project into a self-hosted Helm chart repo. It does this - +during every push to main - by checking each chart in your project, and whenever +there's a new chart version, creates a corresponding GitHub release named for +the chart version, adds Helm chart artifacts to the release, and creates or +updates an `index.yaml` file with metadata about those releases, which is then +hosted on GitHub pages. + +The Chart Releaser Action version number used in the above example is `v1.5.0`. +You can change it to the [latest available +version](https://github.com/helm/chart-releaser-action/releases). + +Note: The Chart Releaser Action is almost always used in tandem with the [Helm Testing +Action](https://github.com/marketplace/actions/helm-chart-testing) and [Kind +Action](https://github.com/marketplace/actions/kind-cluster). diff --git a/content/en/docs/howto/chart_repository_sync_example.md b/content/en/docs/howto/chart_repository_sync_example.md new file mode 100644 index 0000000000..1ba4c5874b --- /dev/null +++ b/content/en/docs/howto/chart_repository_sync_example.md @@ -0,0 +1,94 @@ +--- +title: "Syncing Your Chart Repository" +description: "Describes how to synchronize your local and remote chart repositories." +weight: 2 +aliases: ["/docs/chart_repository_sync_example/"] +--- + +*Note: This example is specifically for a Google Cloud Storage (GCS) bucket +which serves a chart repository.* + +## Prerequisites +* Install the [gsutil](https://cloud.google.com/storage/docs/gsutil) tool. *We + rely heavily on the gsutil rsync functionality* +* Be sure to have access to the Helm binary +* _Optional: We recommend you set [object + versioning](https://cloud.google.com/storage/docs/gsutil/addlhelp/ObjectVersioningandConcurrencyControl#top_of_page) + on your GCS bucket in case you accidentally delete something._ + +## Set up a local chart repository directory +Create a local directory like we did in [the chart repository guide]({{< ref +"/docs/topics/chart_repository.md" >}}), and place your packaged charts in that +directory. + +For example: +```console +$ mkdir fantastic-charts +$ mv alpine-0.1.0.tgz fantastic-charts/ +``` + +## Generate an updated index.yaml +Use Helm to generate an updated index.yaml file by passing in the directory path +and the url of the remote repository to the `helm repo index` command like this: + +```console +$ helm repo index fantastic-charts/ --url https://fantastic-charts.storage.googleapis.com +``` +This will generate an updated index.yaml file and place it in the +`fantastic-charts/` directory. + +## Sync your local and remote chart repositories +Upload the contents of the directory to your GCS bucket by running +`scripts/sync-repo.sh` and pass in the local directory name and the GCS bucket +name. + +For example: +```console +$ pwd +/Users/me/code/go/src/helm.sh/helm +$ scripts/sync-repo.sh fantastic-charts/ fantastic-charts +Getting ready to sync your local directory (fantastic-charts/) to a remote repository at gs://fantastic-charts +Verifying Prerequisites.... +Thumbs up! Looks like you have gsutil. Let's continue. +Building synchronization state... +Starting synchronization +Would copy file://fantastic-charts/alpine-0.1.0.tgz to gs://fantastic-charts/alpine-0.1.0.tgz +Would copy file://fantastic-charts/index.yaml to gs://fantastic-charts/index.yaml +Are you sure you would like to continue with these changes?? [y/N]} y +Building synchronization state... +Starting synchronization +Copying file://fantastic-charts/alpine-0.1.0.tgz [Content-Type=application/x-tar]... +Uploading gs://fantastic-charts/alpine-0.1.0.tgz: 740 B/740 B +Copying file://fantastic-charts/index.yaml [Content-Type=application/octet-stream]... +Uploading gs://fantastic-charts/index.yaml: 347 B/347 B +Congratulations your remote chart repository now matches the contents of fantastic-charts/ +``` +## Updating your chart repository +You'll want to keep a local copy of the contents of your chart repository or use +`gsutil rsync` to copy the contents of your remote chart repository to a local +directory. + +For example: +```console +$ gsutil rsync -d -n gs://bucket-name local-dir/ # the -n flag does a dry run +Building synchronization state... +Starting synchronization +Would copy gs://bucket-name/alpine-0.1.0.tgz to file://local-dir/alpine-0.1.0.tgz +Would copy gs://bucket-name/index.yaml to file://local-dir/index.yaml + +$ gsutil rsync -d gs://bucket-name local-dir/ # performs the copy actions +Building synchronization state... +Starting synchronization +Copying gs://bucket-name/alpine-0.1.0.tgz... +Downloading file://local-dir/alpine-0.1.0.tgz: 740 B/740 B +Copying gs://bucket-name/index.yaml... +Downloading file://local-dir/index.yaml: 346 B/346 B +``` + +Helpful Links: +* Documentation on [gsutil + rsync](https://cloud.google.com/storage/docs/gsutil/commands/rsync#description) +* [The Chart Repository Guide]({{< ref "/docs/topics/chart_repository.md" >}}) +* Documentation on [object versioning and concurrency + control](https://cloud.google.com/storage/docs/gsutil/addlhelp/ObjectVersioningandConcurrencyControl#overview) + in Google Cloud Storage diff --git a/content/en/docs/howto/charts_tips_and_tricks.md b/content/en/docs/howto/charts_tips_and_tricks.md new file mode 100644 index 0000000000..61ed5888e8 --- /dev/null +++ b/content/en/docs/howto/charts_tips_and_tricks.md @@ -0,0 +1,316 @@ +--- +title: "Chart Development Tips and Tricks" +description: "Covers some of the tips and tricks Helm chart developers have learned while building production-quality charts." +weight: 1 +aliases: ["/docs/charts_tips_and_tricks/"] +--- + +This guide covers some of the tips and tricks Helm chart developers have learned +while building production-quality charts. + +## Know Your Template Functions + +Helm uses [Go templates](https://godoc.org/text/template) for templating your +resource files. While Go ships several built-in functions, we have added many +others. + +First, we added all of the functions in the [Sprig +library](https://masterminds.github.io/sprig/), except `env` and `expandenv`, for security reasons. + +We also added two special template functions: `include` and `required`. The +`include` function allows you to bring in another template, and then pass the +results to other template functions. + +For example, this template snippet includes a template called `mytpl`, then +lowercases the result, then wraps that in double quotes. + +```yaml +value: {{ include "mytpl" . | lower | quote }} +``` + +The `required` function allows you to declare a particular values entry as +required for template rendering. If the value is empty, the template rendering +will fail with a user submitted error message. + +The following example of the `required` function declares an entry for +`.Values.who` is required, and will print an error message when that entry is +missing: + +```yaml +value: {{ required "A valid .Values.who entry required!" .Values.who }} +``` + +## Quote Strings, Don't Quote Integers + +When you are working with string data, you are always safer quoting the strings +than leaving them as bare words: + +```yaml +name: {{ .Values.MyName | quote }} +``` + +But when working with integers _do not quote the values._ That can, in many +cases, cause parsing errors inside of Kubernetes. + +```yaml +port: {{ .Values.Port }} +``` + +This remark does not apply to env variables values which are expected to be +string, even if they represent integers: + +```yaml +env: + - name: HOST + value: "http://host" + - name: PORT + value: "1234" +``` + +## Using the 'include' Function + +Go provides a way of including one template in another using a built-in +`template` directive. However, the built-in function cannot be used in Go +template pipelines. + +To make it possible to include a template, and then perform an operation on that +template's output, Helm has a special `include` function: + +``` +{{ include "toYaml" $value | indent 2 }} +``` + +The above includes a template called `toYaml`, passes it `$value`, and then +passes the output of that template to the `indent` function. + +Because YAML ascribes significance to indentation levels and whitespace, this is +one great way to include snippets of code, but handle indentation in a relevant +context. + +## Using the 'required' function + +Go provides a way for setting template options to control behavior when a map is +indexed with a key that's not present in the map. This is typically set with +`template.Options("missingkey=option")`, where `option` can be `default`, +`zero`, or `error`. While setting this option to error will stop execution with +an error, this would apply to every missing key in the map. There may be +situations where a chart developer wants to enforce this behavior for select +values in the `values.yaml` file. + +The `required` function gives developers the ability to declare a value entry as +required for template rendering. If the entry is empty in `values.yaml`, the +template will not render and will return an error message supplied by the +developer. + +For example: + +``` +{{ required "A valid foo is required!" .Values.foo }} +``` + +The above will render the template when `.Values.foo` is defined, but will fail +to render and exit when `.Values.foo` is undefined. + +## Using the 'tpl' Function + +The `tpl` function allows developers to evaluate strings as templates inside a +template. This is useful to pass a template string as a value to a chart or +render external configuration files. Syntax: `{{ tpl TEMPLATE_STRING VALUES }}` + +Examples: + +```yaml +# values +template: "{{ .Values.name }}" +name: "Tom" + +# template +{{ tpl .Values.template . }} + +# output +Tom +``` + +Rendering an external configuration file: + +```yaml +# external configuration file conf/app.conf +firstName={{ .Values.firstName }} +lastName={{ .Values.lastName }} + +# values +firstName: Peter +lastName: Parker + +# template +{{ tpl (.Files.Get "conf/app.conf") . }} + +# output +firstName=Peter +lastName=Parker +``` + +## Creating Image Pull Secrets +Image pull secrets are essentially a combination of _registry_, _username_, and +_password_. You may need them in an application you are deploying, but to +create them requires running `base64` a couple of times. We can write a helper +template to compose the Docker configuration file for use as the Secret's +payload. Here is an example: + +First, assume that the credentials are defined in the `values.yaml` file like +so: +```yaml +imageCredentials: + registry: quay.io + username: someone + password: sillyness + email: someone@host.com +``` + +We then define our helper template as follows: +``` +{{- define "imagePullSecret" }} +{{- with .Values.imageCredentials }} +{{- printf "{\"auths\":{\"%s\":{\"username\":\"%s\",\"password\":\"%s\",\"email\":\"%s\",\"auth\":\"%s\"}}}" .registry .username .password .email (printf "%s:%s" .username .password | b64enc) | b64enc }} +{{- end }} +{{- end }} +``` + +Finally, we use the helper template in a larger template to create the Secret +manifest: +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: myregistrykey +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +``` + +## Automatically Roll Deployments + +Often times ConfigMaps or Secrets are injected as configuration files in +containers or there are other external dependency changes that require rolling +pods. Depending on the application a restart may be required should those be +updated with a subsequent `helm upgrade`, but if the deployment spec itself +didn't change the application keeps running with the old configuration resulting +in an inconsistent deployment. + +The `sha256sum` function can be used to ensure a deployment's annotation section +is updated if another file changes: + +```yaml +kind: Deployment +spec: + template: + metadata: + annotations: + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} +[...] +``` + +NOTE: If you're adding this to a library chart you won't be able to access your +file in `$.Template.BasePath`. Instead you can reference your definition with +`{{ include ("mylibchart.configmap") . | sha256sum }}`. + +In the event you always want to roll your deployment, you can use a similar +annotation step as above, instead replacing with a random string so it always +changes and causes the deployment to roll: + +```yaml +kind: Deployment +spec: + template: + metadata: + annotations: + rollme: {{ randAlphaNum 5 | quote }} +[...] +``` + +Each invocation of the template function will generate a unique random string. +This means that if it's necessary to sync the random strings used by multiple +resources, all relevant resources will need to be in the same template file. + +Both of these methods allow your Deployment to leverage the built in update +strategy logic to avoid taking downtime. + +NOTE: In the past we recommended using the `--recreate-pods` flag as another +option. This flag has been marked as deprecated in Helm 3 in favor of the more +declarative method above. + +## Tell Helm Not To Uninstall a Resource + +Sometimes there are resources that should not be uninstalled when Helm runs a +`helm uninstall`. Chart developers can add an annotation to a resource to +prevent it from being uninstalled. + +```yaml +kind: Secret +metadata: + annotations: + "helm.sh/resource-policy": keep +[...] +``` + +(Quotation marks are required) + +The annotation `"helm.sh/resource-policy": keep` instructs Helm to skip deleting +this resource when a helm operation (such as `helm uninstall`, `helm upgrade` or +`helm rollback`) would result in its deletion. _However_, this resource becomes +orphaned. Helm will no longer manage it in any way. This can lead to problems if +using `helm install --replace` on a release that has already been uninstalled, +but has kept resources. + +## Using "Partials" and Template Includes + +Sometimes you want to create some reusable parts in your chart, whether they're +blocks or template partials. And often, it's cleaner to keep these in their own +files. + +In the `templates/` directory, any file that begins with an underscore(`_`) is +not expected to output a Kubernetes manifest file. So by convention, helper +templates and partials are placed in a `_helpers.tpl` file. + +## Complex Charts with Many Dependencies + +Many of the charts in the CNCF [Artifact +Hub](https://artifacthub.io/packages/search?kind=0) are "building blocks" for +creating more advanced applications. But charts may be used to create instances +of large-scale applications. In such cases, a single umbrella chart may have +multiple subcharts, each of which functions as a piece of the whole. + +The current best practice for composing a complex application from discrete +parts is to create a top-level umbrella chart that exposes the global +configurations, and then use the `charts/` subdirectory to embed each of the +components. + +## YAML is a Superset of JSON + +According to the YAML specification, YAML is a superset of JSON. That means that +any valid JSON structure ought to be valid in YAML. + +This has an advantage: Sometimes template developers may find it easier to +express a datastructure with a JSON-like syntax rather than deal with YAML's +whitespace sensitivity. + +As a best practice, templates should follow a YAML-like syntax _unless_ the JSON +syntax substantially reduces the risk of a formatting issue. + +## Be Careful with Generating Random Values + +There are functions in Helm that allow you to generate random data, +cryptographic keys, and so on. These are fine to use. But be aware that during +upgrades, templates are re-executed. When a template run generates data that +differs from the last run, that will trigger an update of that resource. + +## Install or Upgrade a Release with One Command + +Helm provides a way to perform an install-or-upgrade as a single command. Use +`helm upgrade` with the `--install` command. This will cause Helm to see if the +release is already installed. If not, it will run an install. If it is, then the +existing release will be upgraded. + +```console +$ helm upgrade --install --values +``` diff --git a/docs.helm.sh/rootfs/public/images/create-a-bucket.png b/content/en/docs/images/create-a-bucket.png old mode 100755 new mode 100644 similarity index 100% rename from docs.helm.sh/rootfs/public/images/create-a-bucket.png rename to content/en/docs/images/create-a-bucket.png diff --git a/docs.helm.sh/rootfs/public/images/create-a-gh-page-button.png b/content/en/docs/images/create-a-gh-page-button.png old mode 100755 new mode 100644 similarity index 100% rename from docs.helm.sh/rootfs/public/images/create-a-gh-page-button.png rename to content/en/docs/images/create-a-gh-page-button.png diff --git a/docs.helm.sh/rootfs/public/images/edit-permissions.png b/content/en/docs/images/edit-permissions.png old mode 100755 new mode 100644 similarity index 100% rename from docs.helm.sh/rootfs/public/images/edit-permissions.png rename to content/en/docs/images/edit-permissions.png diff --git a/content/en/docs/images/make-bucket-public.png b/content/en/docs/images/make-bucket-public.png new file mode 100644 index 0000000000..e457e34b23 Binary files /dev/null and b/content/en/docs/images/make-bucket-public.png differ diff --git a/docs.helm.sh/rootfs/public/images/set-a-gh-page.png b/content/en/docs/images/set-a-gh-page.png old mode 100755 new mode 100644 similarity index 100% rename from docs.helm.sh/rootfs/public/images/set-a-gh-page.png rename to content/en/docs/images/set-a-gh-page.png diff --git a/content/en/docs/intro/_index.md b/content/en/docs/intro/_index.md new file mode 100644 index 0000000000..81f93cfa07 --- /dev/null +++ b/content/en/docs/intro/_index.md @@ -0,0 +1,9 @@ +--- +title: "Introduction" +weight: 1 +aliases: ["/docs/using_helm/"] +--- + +# Introduction to Helm + +Are you new to Helm? This is the place to start! diff --git a/content/en/docs/intro/install.md b/content/en/docs/intro/install.md new file mode 100755 index 0000000000..d2be078d45 --- /dev/null +++ b/content/en/docs/intro/install.md @@ -0,0 +1,177 @@ +--- +title: "Installing Helm" +description: "Learn how to install and get running with Helm." +weight: 2 +aliases: ["/docs/install/"] +--- + +This guide shows how to install the Helm CLI. Helm can be installed either from +source, or from pre-built binary releases. + +## From The Helm Project + +The Helm project provides two ways to fetch and install Helm. These are the +official methods to get Helm releases. In addition to that, the Helm community +provides methods to install Helm through different package managers. +Installation through those methods can be found below the official methods. + +### From the Binary Releases + +Every [release](https://github.com/helm/helm/releases) of Helm provides binary +releases for a variety of OSes. These binary versions can be manually downloaded +and installed. + +1. Download your [desired version](https://github.com/helm/helm/releases) +2. Unpack it (`tar -zxvf helm-v3.0.0-linux-amd64.tar.gz`) +3. Find the `helm` binary in the unpacked directory, and move it to its desired + destination (`mv linux-amd64/helm /usr/local/bin/helm`) + +From there, you should be able to run the client and [add the stable +repo](https://helm.sh/docs/intro/quickstart/#initialize-a-helm-chart-repository): +`helm help`. + +**Note:** Helm automated tests are performed for Linux AMD64 only during +CircleCi builds and releases. Testing of other OSes are the responsibility of +the community requesting Helm for the OS in question. + +### From Script + +Helm now has an installer script that will automatically grab the latest version +of Helm and [install it +locally](https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3). + +You can fetch that script, and then execute it locally. It's well documented so +that you can read through it and understand what it is doing before you run it. + +```console +$ curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 +$ chmod 700 get_helm.sh +$ ./get_helm.sh +``` + +Yes, you can `curl +https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash` if +you want to live on the edge. + +## Through Package Managers + +The Helm community provides the ability to install Helm through operating system +package managers. These are not supported by the Helm project and are not +considered trusted 3rd parties. + +### From Homebrew (macOS) + +Members of the Helm community have contributed a Helm formula build to Homebrew. +This formula is generally up to date. + +```console +brew install helm +``` + +(Note: There is also a formula for emacs-helm, which is a different project.) + +### From Chocolatey (Windows) + +Members of the Helm community have contributed a [Helm +package](https://chocolatey.org/packages/kubernetes-helm) build to +[Chocolatey](https://chocolatey.org/). This package is generally up to date. + +```console +choco install kubernetes-helm +``` + +### From Scoop (Windows) + +Members of the Helm community have contributed a [Helm +package](https://github.com/ScoopInstaller/Main/blob/master/bucket/helm.json) build to [Scoop](https://scoop.sh). This package is generally up to date. + +```console +scoop install helm +``` + +### From Apt (Debian/Ubuntu) + +Members of the Helm community have contributed a [Helm +package](https://helm.baltorepo.com/stable/debian/) for Apt. This package is +generally up to date. + +```console +curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null +sudo apt-get install apt-transport-https --yes +echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list +sudo apt-get update +sudo apt-get install helm +``` + +### From dnf/yum (fedora) +Since Fedora 35, helm is available on the official repository. +You can install helm with invoking: + +```console +sudo dnf install helm +``` + +### From Snap + +The [Snapcrafters](https://github.com/snapcrafters) community maintains the Snap +version of the [Helm package](https://snapcraft.io/helm): + +```console +sudo snap install helm --classic +``` + +### From pkg (FreeBSD) + +Members of the FreeBSD community have contributed a [Helm +package](https://www.freshports.org/sysutils/helm) build to the +[FreeBSD Ports Collection](https://man.freebsd.org/ports). +This package is generally up to date. + +```console +pkg install helm +``` + +### Development Builds + +In addition to releases you can download or install development snapshots of +Helm. + +### From Canary Builds + +"Canary" builds are versions of the Helm software that are built from the latest +`main` branch. They are not official releases, and may not be stable. However, +they offer the opportunity to test the cutting edge features. + +Canary Helm binaries are stored at [get.helm.sh](https://get.helm.sh). Here are +links to the common builds: + +- [Linux AMD64](https://get.helm.sh/helm-canary-linux-amd64.tar.gz) +- [macOS AMD64](https://get.helm.sh/helm-canary-darwin-amd64.tar.gz) +- [Experimental Windows + AMD64](https://get.helm.sh/helm-canary-windows-amd64.zip) + +### From Source (Linux, macOS) + +Building Helm from source is slightly more work, but is the best way to go if +you want to test the latest (pre-release) Helm version. + +You must have a working Go environment. + +```console +$ git clone https://github.com/helm/helm.git +$ cd helm +$ make +``` + +If required, it will fetch the dependencies and cache them, and validate +configuration. It will then compile `helm` and place it in `bin/helm`. + +## Conclusion + +In most cases, installation is as simple as getting a pre-built `helm` binary. +This document covers additional cases for those who want to do more +sophisticated things with Helm. + +Once you have the Helm Client successfully installed, you can move on to using +Helm to manage charts and [add the stable +repo](https://helm.sh/docs/intro/quickstart/#initialize-a-helm-chart-repository). diff --git a/content/en/docs/intro/quickstart.md b/content/en/docs/intro/quickstart.md new file mode 100644 index 0000000000..15b9c9d4e9 --- /dev/null +++ b/content/en/docs/intro/quickstart.md @@ -0,0 +1,134 @@ +--- +title: "Quickstart Guide" +description: "How to install and get started with Helm including instructions for distros, FAQs, and plugins." +weight: 1 +aliases: ["/docs/quickstart/"] +--- + +This guide covers how you can quickly get started using Helm. + +## Prerequisites + +The following prerequisites are required for a successful and properly secured +use of Helm. + +1. A Kubernetes cluster +2. Deciding what security configurations to apply to your installation, if any +3. Installing and configuring Helm. + +### Install Kubernetes or have access to a cluster + +- You must have Kubernetes installed. For the latest release of Helm, we + recommend the latest stable release of Kubernetes, which in most cases is the + second-latest minor release. +- You should also have a local configured copy of `kubectl`. + +See the [Helm Version Support Policy](https://helm.sh/docs/topics/version_skew/) for the maximum version skew supported between Helm and Kubernetes. + +## Install Helm + +Download a binary release of the Helm client. You can use tools like `homebrew`, +or look at [the official releases page](https://github.com/helm/helm/releases). + +For more details, or for other options, see [the installation guide]({{< ref +"install.md" >}}). + +## Initialize a Helm Chart Repository + +Once you have Helm ready, you can add a chart repository. Check [Artifact +Hub](https://artifacthub.io/packages/search?kind=0) for available Helm chart +repositories. + +```console +$ helm repo add bitnami https://charts.bitnami.com/bitnami +``` + +Once this is installed, you will be able to list the charts you can install: + +```console +$ helm search repo bitnami +NAME CHART VERSION APP VERSION DESCRIPTION +bitnami/bitnami-common 0.0.9 0.0.9 DEPRECATED Chart with custom templates used in ... +bitnami/airflow 8.0.2 2.0.0 Apache Airflow is a platform to programmaticall... +bitnami/apache 8.2.3 2.4.46 Chart for Apache HTTP Server +bitnami/aspnet-core 1.2.3 3.1.9 ASP.NET Core is an open-source framework create... +# ... and many more +``` + +## Install an Example Chart + +To install a chart, you can run the `helm install` command. Helm has several +ways to find and install a chart, but the easiest is to use the `bitnami` +charts. + +```console +$ helm repo update # Make sure we get the latest list of charts +$ helm install bitnami/mysql --generate-name +NAME: mysql-1612624192 +LAST DEPLOYED: Sat Feb 6 16:09:56 2021 +NAMESPACE: default +STATUS: deployed +REVISION: 1 +TEST SUITE: None +NOTES: ... +``` + +In the example above, the `bitnami/mysql` chart was released, and the name of +our new release is `mysql-1612624192`. + +You get a simple idea of the features of this MySQL chart by running `helm show +chart bitnami/mysql`. Or you could run `helm show all bitnami/mysql` to get all +information about the chart. + +Whenever you install a chart, a new release is created. So one chart can be +installed multiple times into the same cluster. And each can be independently +managed and upgraded. + +The `helm install` command is a very powerful command with many capabilities. To +learn more about it, check out the [Using Helm Guide]({{< ref "using_helm.md" +>}}) + +## Learn About Releases + +It's easy to see what has been released using Helm: + +```console +$ helm list +NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION +mysql-1612624192 default 1 2021-02-06 16:09:56.283059 +0100 CET deployed mysql-8.3.0 8.0.23 +``` + +The `helm list` (or `helm ls`) function will show you a list of all deployed releases. + +## Uninstall a Release + +To uninstall a release, use the `helm uninstall` command: + +```console +$ helm uninstall mysql-1612624192 +release "mysql-1612624192" uninstalled +``` + +This will uninstall `mysql-1612624192` from Kubernetes, which will remove all +resources associated with the release as well as the release history. + +If the flag `--keep-history` is provided, release history will be kept. You will +be able to request information about that release: + +```console +$ helm status mysql-1612624192 +Status: UNINSTALLED +... +``` + +Because Helm tracks your releases even after you've uninstalled them, you can +audit a cluster's history, and even undelete a release (with `helm rollback`). + +## Reading the Help Text + +To learn more about the available Helm commands, use `helm help` or type a +command followed by the `-h` flag: + +```console +$ helm get -h +``` diff --git a/content/en/docs/intro/using_helm.md b/content/en/docs/intro/using_helm.md new file mode 100755 index 0000000000..526f9cc9e4 --- /dev/null +++ b/content/en/docs/intro/using_helm.md @@ -0,0 +1,549 @@ +--- +title: "Using Helm" +description: "Explains the basics of Helm." +weight: 3 +--- + +This guide explains the basics of using Helm to manage packages on your +Kubernetes cluster. It assumes that you have already [installed]({{< ref +"install.md" >}}) the Helm client. + +If you are simply interested in running a few quick commands, you may wish to +begin with the [Quickstart Guide]({{< ref "quickstart.md" >}}). This chapter +covers the particulars of Helm commands, and explains how to use Helm. + +## Three Big Concepts + +A *Chart* is a Helm package. It contains all of the resource definitions +necessary to run an application, tool, or service inside of a Kubernetes +cluster. Think of it like the Kubernetes equivalent of a Homebrew formula, an +Apt dpkg, or a Yum RPM file. + +A *Repository* is the place where charts can be collected and shared. It's like +Perl's [CPAN archive](https://www.cpan.org) or the [Fedora Package +Database](https://src.fedoraproject.org/), but for Kubernetes packages. + +A *Release* is an instance of a chart running in a Kubernetes cluster. One chart +can often be installed many times into the same cluster. And each time it is +installed, a new _release_ is created. Consider a MySQL chart. If you want two +databases running in your cluster, you can install that chart twice. Each one +will have its own _release_, which will in turn have its own _release name_. + +With these concepts in mind, we can now explain Helm like this: + +Helm installs _charts_ into Kubernetes, creating a new _release_ for each +installation. And to find new charts, you can search Helm chart _repositories_. + +## 'helm search': Finding Charts + +Helm comes with a powerful search command. It can be used to search two +different types of source: + +- `helm search hub` searches [the Artifact Hub](https://artifacthub.io), which + lists helm charts from dozens of different repositories. +- `helm search repo` searches the repositories that you have added to your local + helm client (with `helm repo add`). This search is done over local data, and + no public network connection is needed. + +You can find publicly available charts by running `helm search hub`: + +```console +$ helm search hub wordpress +URL CHART VERSION APP VERSION DESCRIPTION +https://hub.helm.sh/charts/bitnami/wordpress 7.6.7 5.2.4 Web publishing platform for building blogs and ... +https://hub.helm.sh/charts/presslabs/wordpress-... v0.6.3 v0.6.3 Presslabs WordPress Operator Helm Chart +https://hub.helm.sh/charts/presslabs/wordpress-... v0.7.1 v0.7.1 A Helm chart for deploying a WordPress site on ... +``` + +The above searches for all `wordpress` charts on Artifact Hub. + +With no filter, `helm search hub` shows you all of the available charts. + +Using `helm search repo`, you can find the names of the charts in repositories +you have already added: + +```console +$ helm repo add brigade https://brigadecore.github.io/charts +"brigade" has been added to your repositories +$ helm search repo brigade +NAME CHART VERSION APP VERSION DESCRIPTION +brigade/brigade 1.3.2 v1.2.1 Brigade provides event-driven scripting of Kube... +brigade/brigade-github-app 0.4.1 v0.2.1 The Brigade GitHub App, an advanced gateway for... +brigade/brigade-github-oauth 0.2.0 v0.20.0 The legacy OAuth GitHub Gateway for Brigade +brigade/brigade-k8s-gateway 0.1.0 A Helm chart for Kubernetes +brigade/brigade-project 1.0.0 v1.0.0 Create a Brigade project +brigade/kashti 0.4.0 v0.4.0 A Helm chart for Kubernetes +``` + +Helm search uses a fuzzy string matching algorithm, so you can type parts of +words or phrases: + +```console +$ helm search repo kash +NAME CHART VERSION APP VERSION DESCRIPTION +brigade/kashti 0.4.0 v0.4.0 A Helm chart for Kubernetes +``` + +Search is a good way to find available packages. Once you have found a package +you want to install, you can use `helm install` to install it. + +## 'helm install': Installing a Package + +To install a new package, use the `helm install` command. At its simplest, it +takes two arguments: A release name that you pick, and the name of the chart you +want to install. + +```console +$ helm install happy-panda bitnami/wordpress +NAME: happy-panda +LAST DEPLOYED: Tue Jan 26 10:27:17 2021 +NAMESPACE: default +STATUS: deployed +REVISION: 1 +NOTES: +** Please be patient while the chart is being deployed ** + +Your WordPress site can be accessed through the following DNS name from within your cluster: + + happy-panda-wordpress.default.svc.cluster.local (port 80) + +To access your WordPress site from outside the cluster follow the steps below: + +1. Get the WordPress URL by running these commands: + + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + Watch the status with: 'kubectl get svc --namespace default -w happy-panda-wordpress' + + export SERVICE_IP=$(kubectl get svc --namespace default happy-panda-wordpress --template "{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}") + echo "WordPress URL: http://$SERVICE_IP/" + echo "WordPress Admin URL: http://$SERVICE_IP/admin" + +2. Open a browser and access WordPress using the obtained URL. + +3. Login with the following credentials below to see your blog: + + echo Username: user + echo Password: $(kubectl get secret --namespace default happy-panda-wordpress -o jsonpath="{.data.wordpress-password}" | base64 --decode) +``` + +Now the `wordpress` chart is installed. Note that installing a chart creates a +new _release_ object. The release above is named `happy-panda`. (If you want +Helm to generate a name for you, leave off the release name and use +`--generate-name`.) + +During installation, the `helm` client will print useful information about which +resources were created, what the state of the release is, and also whether there +are additional configuration steps you can or should take. + +Helm installs resources in the following order: + +- Namespace +- NetworkPolicy +- ResourceQuota +- LimitRange +- PodSecurityPolicy +- PodDisruptionBudget +- ServiceAccount +- Secret +- SecretList +- ConfigMap +- StorageClass +- PersistentVolume +- PersistentVolumeClaim +- CustomResourceDefinition +- ClusterRole +- ClusterRoleList +- ClusterRoleBinding +- ClusterRoleBindingList +- Role +- RoleList +- RoleBinding +- RoleBindingList +- Service +- DaemonSet +- Pod +- ReplicationController +- ReplicaSet +- Deployment +- HorizontalPodAutoscaler +- StatefulSet +- Job +- CronJob +- Ingress +- APIService + +Helm does not wait until all of the resources are running before it exits. Many +charts require Docker images that are over 600M in size, and may take a long +time to install into the cluster. + +To keep track of a release's state, or to re-read configuration information, you +can use `helm status`: + +```console +$ helm status happy-panda +NAME: happy-panda +LAST DEPLOYED: Tue Jan 26 10:27:17 2021 +NAMESPACE: default +STATUS: deployed +REVISION: 1 +NOTES: +** Please be patient while the chart is being deployed ** + +Your WordPress site can be accessed through the following DNS name from within your cluster: + + happy-panda-wordpress.default.svc.cluster.local (port 80) + +To access your WordPress site from outside the cluster follow the steps below: + +1. Get the WordPress URL by running these commands: + + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + Watch the status with: 'kubectl get svc --namespace default -w happy-panda-wordpress' + + export SERVICE_IP=$(kubectl get svc --namespace default happy-panda-wordpress --template "{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}") + echo "WordPress URL: http://$SERVICE_IP/" + echo "WordPress Admin URL: http://$SERVICE_IP/admin" + +2. Open a browser and access WordPress using the obtained URL. + +3. Login with the following credentials below to see your blog: + + echo Username: user + echo Password: $(kubectl get secret --namespace default happy-panda-wordpress -o jsonpath="{.data.wordpress-password}" | base64 --decode) +``` + +The above shows the current state of your release. + +### Customizing the Chart Before Installing + +Installing the way we have here will only use the default configuration options +for this chart. Many times, you will want to customize the chart to use your +preferred configuration. + +To see what options are configurable on a chart, use `helm show values`: + +```console +$ helm show values bitnami/wordpress +## Global Docker image parameters +## Please, note that this will override the image parameters, including dependencies, configured to use the global value +## Current available global Docker image parameters: imageRegistry and imagePullSecrets +## +# global: +# imageRegistry: myRegistryName +# imagePullSecrets: +# - myRegistryKeySecretName +# storageClass: myStorageClass + +## Bitnami WordPress image version +## ref: https://hub.docker.com/r/bitnami/wordpress/tags/ +## +image: + registry: docker.io + repository: bitnami/wordpress + tag: 5.6.0-debian-10-r35 + [..] +``` + +You can then override any of these settings in a YAML formatted file, and then +pass that file during installation. + +```console +$ echo '{mariadb.auth.database: user0db, mariadb.auth.username: user0}' > values.yaml +$ helm install -f values.yaml bitnami/wordpress --generate-name +``` + +The above will create a default MariaDB user with the name `user0`, and grant +this user access to a newly created `user0db` database, but will accept all the +rest of the defaults for that chart. + +There are two ways to pass configuration data during install: + +- `--values` (or `-f`): Specify a YAML file with overrides. This can be + specified multiple times and the rightmost file will take precedence +- `--set`: Specify overrides on the command line. + +If both are used, `--set` values are merged into `--values` with higher +precedence. Overrides specified with `--set` are persisted in a ConfigMap. +Values that have been `--set` can be viewed for a given release with `helm get +values `. Values that have been `--set` can be cleared by running +`helm upgrade` with `--reset-values` specified. + +#### The Format and Limitations of `--set` + +The `--set` option takes zero or more name/value pairs. At its simplest, it is +used like this: `--set name=value`. The YAML equivalent of that is: + +```yaml +name: value +``` + +Multiple values are separated by `,` characters. So `--set a=b,c=d` becomes: + +```yaml +a: b +c: d +``` + +More complex expressions are supported. For example, `--set outer.inner=value` +is translated into this: +```yaml +outer: + inner: value +``` + +Lists can be expressed by enclosing values in `{` and `}`. For example, `--set +name={a, b, c}` translates to: + +```yaml +name: + - a + - b + - c +``` + +Certain name/key can be set to be `null` or to be an empty array `[]`. For example, `--set name=[],a=null` translates + +```yaml +name: + - a + - b + - c +a: b +``` + +to + +```yaml +name: [] +a: null +``` + +As of Helm 2.5.0, it is possible to access list items using an array index +syntax. For example, `--set servers[0].port=80` becomes: + +```yaml +servers: + - port: 80 +``` + +Multiple values can be set this way. The line `--set +servers[0].port=80,servers[0].host=example` becomes: + +```yaml +servers: + - port: 80 + host: example +``` + +Sometimes you need to use special characters in your `--set` lines. You can use +a backslash to escape the characters; `--set name=value1\,value2` will become: + +```yaml +name: "value1,value2" +``` + +Similarly, you can escape dot sequences as well, which may come in handy when +charts use the `toYaml` function to parse annotations, labels and node +selectors. The syntax for `--set nodeSelector."kubernetes\.io/role"=master` +becomes: + +```yaml +nodeSelector: + kubernetes.io/role: master +``` + +Deeply nested data structures can be difficult to express using `--set`. Chart +designers are encouraged to consider the `--set` usage when designing the format +of a `values.yaml` file (read more about [Values Files](../chart_template_guide/values_files/)). + +### More Installation Methods + +The `helm install` command can install from several sources: + +- A chart repository (as we've seen above) +- A local chart archive (`helm install foo foo-0.1.1.tgz`) +- An unpacked chart directory (`helm install foo path/to/foo`) +- A full URL (`helm install foo https://example.com/charts/foo-1.2.3.tgz`) + +## 'helm upgrade' and 'helm rollback': Upgrading a Release, and Recovering on Failure + +When a new version of a chart is released, or when you want to change the +configuration of your release, you can use the `helm upgrade` command. + +An upgrade takes an existing release and upgrades it according to the +information you provide. Because Kubernetes charts can be large and complex, +Helm tries to perform the least invasive upgrade. It will only update things +that have changed since the last release. + +```console +$ helm upgrade -f panda.yaml happy-panda bitnami/wordpress +``` + +In the above case, the `happy-panda` release is upgraded with the same chart, +but with a new YAML file: + +```yaml +mariadb.auth.username: user1 +``` + +We can use `helm get values` to see whether that new setting took effect. + +```console +$ helm get values happy-panda +mariadb: + auth: + username: user1 +``` + +The `helm get` command is a useful tool for looking at a release in the cluster. +And as we can see above, it shows that our new values from `panda.yaml` were +deployed to the cluster. + +Now, if something does not go as planned during a release, it is easy to roll +back to a previous release using `helm rollback [RELEASE] [REVISION]`. + +```console +$ helm rollback happy-panda 1 +``` + +The above rolls back our happy-panda to its very first release version. A +release version is an incremental revision. Every time an install, upgrade, or +rollback happens, the revision number is incremented by 1. The first revision +number is always 1. And we can use `helm history [RELEASE]` to see revision +numbers for a certain release. + +## Helpful Options for Install/Upgrade/Rollback + +There are several other helpful options you can specify for customizing the +behavior of Helm during an install/upgrade/rollback. Please note that this is +not a full list of cli flags. To see a description of all flags, just run `helm + --help`. + +- `--timeout`: A [Go duration](https://golang.org/pkg/time/#ParseDuration) value + to wait for Kubernetes commands to complete. This defaults to `5m0s`. +- `--wait`: Waits until all Pods are in a ready state, PVCs are bound, + Deployments have minimum (`Desired` minus `maxUnavailable`) Pods in ready + state and Services have an IP address (and Ingress if a `LoadBalancer`) before + marking the release as successful. It will wait for as long as the `--timeout` + value. If timeout is reached, the release will be marked as `FAILED`. Note: In + scenarios where Deployment has `replicas` set to 1 and `maxUnavailable` is not + set to 0 as part of rolling update strategy, `--wait` will return as ready as + it has satisfied the minimum Pod in ready condition. +- `--no-hooks`: This skips running hooks for the command +- `--recreate-pods` (only available for `upgrade` and `rollback`): This flag + will cause all pods to be recreated (with the exception of pods belonging to + deployments). (DEPRECATED in Helm 3) + +## 'helm uninstall': Uninstalling a Release + +When it is time to uninstall a release from the cluster, use the `helm +uninstall` command: + +```console +$ helm uninstall happy-panda +``` + +This will remove the release from the cluster. You can see all of your currently +deployed releases with the `helm list` command: + +```console +$ helm list +NAME VERSION UPDATED STATUS CHART +inky-cat 1 Wed Sep 28 12:59:46 2016 DEPLOYED alpine-0.1.0 +``` + +From the output above, we can see that the `happy-panda` release was +uninstalled. + +In previous versions of Helm, when a release was deleted, a record of its +deletion would remain. In Helm 3, deletion removes the release record as well. +If you wish to keep a deletion release record, use `helm uninstall +--keep-history`. Using `helm list --uninstalled` will only show releases that +were uninstalled with the `--keep-history` flag. + +The `helm list --all` flag will show you all release records that Helm has +retained, including records for failed or deleted items (if `--keep-history` was +specified): + +```console +$ helm list --all +NAME VERSION UPDATED STATUS CHART +happy-panda 2 Wed Sep 28 12:47:54 2016 UNINSTALLED wordpress-10.4.5.6.0 +inky-cat 1 Wed Sep 28 12:59:46 2016 DEPLOYED alpine-0.1.0 +kindred-angelf 2 Tue Sep 27 16:16:10 2016 UNINSTALLED alpine-0.1.0 +``` + +Note that because releases are now deleted by default, it is no longer possible +to rollback an uninstalled resource. + +## 'helm repo': Working with Repositories + +Helm 3 no longer ships with a default chart repository. The `helm repo` command +group provides commands to add, list, and remove repositories. + +You can see which repositories are configured using `helm repo list`: + +```console +$ helm repo list +NAME URL +stable https://charts.helm.sh/stable +mumoshu https://mumoshu.github.io/charts +``` + +And new repositories can be added with `helm repo add`: + +```console +$ helm repo add dev https://example.com/dev-charts +``` + +Because chart repositories change frequently, at any point you can make sure +your Helm client is up to date by running `helm repo update`. + +Repositories can be removed with `helm repo remove`. + +## Creating Your Own Charts + +The [Chart Development Guide]({{< ref "../topics/charts.md" >}}) explains how +to develop your own charts. But you can get started quickly by using the `helm +create` command: + +```console +$ helm create deis-workflow +Creating deis-workflow +``` + +Now there is a chart in `./deis-workflow`. You can edit it and create your own +templates. + +As you edit your chart, you can validate that it is well-formed by running `helm +lint`. + +When it's time to package the chart up for distribution, you can run the `helm +package` command: + +```console +$ helm package deis-workflow +deis-workflow-0.1.0.tgz +``` + +And that chart can now easily be installed by `helm install`: + +```console +$ helm install deis-workflow ./deis-workflow-0.1.0.tgz +... +``` + +Charts that are packaged can be loaded into chart repositories. See the +documentation for [Helm chart +repositories]({{< ref "/docs/topics/chart_repository.md" >}}) for more details. + +## Conclusion + +This chapter has covered the basic usage patterns of the `helm` client, +including searching, installation, upgrading, and uninstalling. It has also +covered useful utility commands like `helm status`, `helm get`, and `helm repo`. + +For more information on these commands, take a look at Helm's built-in help: +`helm help`. + +In the [next chapter](../howto/charts_tips_and_tricks/), we look at the process of developing charts. diff --git a/content/en/docs/logos/helm-blue-vector.svg b/content/en/docs/logos/helm-blue-vector.svg new file mode 100644 index 0000000000..45f2c2f862 --- /dev/null +++ b/content/en/docs/logos/helm-blue-vector.svg @@ -0,0 +1,43 @@ + + + + +logo +Created with Sketch. + + + + + + diff --git a/content/en/docs/logos/helm-white-vector.svg b/content/en/docs/logos/helm-white-vector.svg new file mode 100644 index 0000000000..0f09be31ef --- /dev/null +++ b/content/en/docs/logos/helm-white-vector.svg @@ -0,0 +1,43 @@ + + + + +logo white +Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + diff --git a/content/en/docs/logos/helm.svg b/content/en/docs/logos/helm.svg new file mode 100644 index 0000000000..2d8858e938 --- /dev/null +++ b/content/en/docs/logos/helm.svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs.helm.sh/rootfs/public/logos/helm_logo_transparent.png b/content/en/docs/logos/helm_logo_transparent.png similarity index 100% rename from docs.helm.sh/rootfs/public/logos/helm_logo_transparent.png rename to content/en/docs/logos/helm_logo_transparent.png diff --git a/content/en/docs/topics/_index.md b/content/en/docs/topics/_index.md new file mode 100644 index 0000000000..273e6418bb --- /dev/null +++ b/content/en/docs/topics/_index.md @@ -0,0 +1,9 @@ +--- +title: "Topics" +weight: 3 +--- + +# Topic Guides + +Here you’ll find introductions to all the key parts of Helm you’ll need or want +to know. diff --git a/content/en/docs/topics/advanced.md b/content/en/docs/topics/advanced.md new file mode 100644 index 0000000000..7444b2e4ce --- /dev/null +++ b/content/en/docs/topics/advanced.md @@ -0,0 +1,224 @@ +--- +title: "Advanced Helm Techniques" +description: "Explains various advanced features for Helm power users" +aliases: ["/docs/advanced_helm_techniques"] +weight: 9 +--- + +This section explains various advanced features and techniques for using Helm. +The information in this section is intended for "power users" of Helm that wish +to do advanced customization and manipulation of their charts and releases. Each +of these advanced features comes with their own tradeoffs and caveats, so each +one must be used carefully and with deep knowledge of Helm. Or in other words, +remember the [Peter Parker +principle](https://en.wikipedia.org/wiki/With_great_power_comes_great_responsibility) + +## Post Rendering +Post rendering gives chart installers the ability to manually manipulate, +configure, and/or validate rendered manifests before they are installed by Helm. +This allows users with advanced configuration needs to be able to use tools like +[`kustomize`](https://kustomize.io) to apply configuration changes without the +need to fork a public chart or requiring chart maintainers to specify every last +configuration option for a piece of software. There are also use cases for +injecting common tools and side cars in enterprise environments or analysis of +the manifests before deployment. + +### Prerequisites +- Helm 3.1+ + +### Usage +A post-renderer can be any executable that accepts rendered Kubernetes manifests +on STDIN and returns valid Kubernetes manifests on STDOUT. It should return an +non-0 exit code in the event of a failure. This is the only "API" between the +two components. It allows for great flexibility in what you can do with your +post-render process. + +A post renderer can be used with `install`, `upgrade`, and `template`. To use a +post-renderer, use the `--post-renderer` flag with a path to the renderer +executable you wish to use: + +```shell +$ helm install mychart stable/wordpress --post-renderer ./path/to/executable +``` + +If the path does not contain any separators, it will search in $PATH, otherwise +it will resolve any relative paths to a fully qualified path + +If you wish to use multiple post-renderers, call all of them in a script or +together in whatever binary tool you have built. In bash, this would be as +simple as `renderer1 | renderer2 | renderer3`. + +You can see an example of using `kustomize` as a post renderer +[here](https://github.com/thomastaylor312/advanced-helm-demos/tree/master/post-render). + +### Caveats +When using post renderers, there are several important things to keep in mind. +The most important of these is that when using a post-renderer, all people +modifying that release **MUST** use the same renderer in order to have +repeatable builds. This feature is purposefully built to allow any user to +switch out which renderer they are using or to stop using a renderer, but this +should be done deliberately to avoid accidental modification or data loss. + +One other important note is around security. If you are using a post-renderer, +you should ensure it is coming from a reliable source (as is the case for any +other arbitrary executable). Using non-trusted or non-verified renderers is NOT +recommended as they have full access to rendered templates, which often contain +secret data. + +### Custom Post Renderers +The post render step offers even more flexibility when used in the Go SDK. Any +post renderer only needs to implement the following Go interface: + +```go +type PostRenderer interface { + // Run expects a single buffer filled with Helm rendered manifests. It + // expects the modified results to be returned on a separate buffer or an + // error if there was an issue or failure while running the post render step + Run(renderedManifests *bytes.Buffer) (modifiedManifests *bytes.Buffer, err error) +} +``` + +For more information on using the Go SDK, See the [Go SDK section](#go-sdk) + +## Go SDK +Helm 3 debuted a completely restructured Go SDK for a better experience when +building software and tools that leverage Helm. Full documentation can be found +at [https://pkg.go.dev/helm.sh/helm/v3](https://pkg.go.dev/helm.sh/helm/v3), but +a brief overview of some of the most common packages and a simple example follow +below. + +### Package overview +This is a list of the most commonly used packages with a simple explanation +about each one: + +- `pkg/action`: Contains the main “client” for performing Helm actions. This is + the same package that the CLI is using underneath the hood. If you just need + to perform basic Helm commands from another Go program, this package is for + you +- `pkg/{chart,chartutil}`: Methods and helpers used for loading and manipulating + charts +- `pkg/cli` and its subpackages: Contains all the handlers for the standard Helm + environment variables and its subpackages contain output and values file + handling +- `pkg/release`: Defines the `Release` object and statuses + +Obviously there are many more packages besides these, so go check out the +documentation for more information! + +### Simple example +This is a simple example of doing a `helm list` using the Go SDK: + +```go +package main + +import ( + "log" + "os" + + "helm.sh/helm/v3/pkg/action" + "helm.sh/helm/v3/pkg/cli" +) + +func main() { + settings := cli.New() + + actionConfig := new(action.Configuration) + // You can pass an empty string instead of settings.Namespace() to list + // all namespaces + if err := actionConfig.Init(settings.RESTClientGetter(), settings.Namespace(), os.Getenv("HELM_DRIVER"), log.Printf); err != nil { + log.Printf("%+v", err) + os.Exit(1) + } + + client := action.NewList(actionConfig) + // Only list deployed + client.Deployed = true + results, err := client.Run() + if err != nil { + log.Printf("%+v", err) + os.Exit(1) + } + + for _, rel := range results { + log.Printf("%+v", rel) + } +} + +``` + +## Storage backends + +Helm 3 changed the default release information storage to Secrets in the +namespace of the release. Helm 2 by default stores release information as +ConfigMaps in the namespace of the Tiller instance. The subsections which follow +show how to configure different backends. This configuration is based on the +`HELM_DRIVER` environment variable. It can be set to one of the values: +`[configmap, secret, sql]`. + +### ConfigMap storage backend + +To enable the ConfigMap backend, you'll need to set the environmental variable +`HELM_DRIVER` to `configmap`. + +You can set it in a shell as follows: + +```shell +export HELM_DRIVER=configmap +``` + +If you want to switch from the default backend to the ConfigMap backend, you'll +have to do the migration for this on your own. You can retrieve release +information with the following command: + +```shell +kubectl get secret --all-namespaces -l "owner=helm" +``` + +**PRODUCTION NOTES**: The release information includes the contents of charts and +values files, and therefore might contain sensitive data (like +passwords, private keys, and other credentials) that needs to be protected from +unauthorized access. When managing Kubernetes authorization, for instance with +[RBAC](https://kubernetes.io/docs/reference/access-authn-authz/rbac/), it is +possible to grant broader access to ConfigMap resources, while restricting +access to Secret resources. For instance, the default [user-facing +role](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#user-facing-roles) +"view" grants access to most resources, but not to Secrets. Furthermore, secrets +data can be configured for [encrypted +storage](https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/). +Please keep that in mind if you decide to switch to the ConfigMap backend, as it +could expose your application's sensitive data. + +### SQL storage backend + +There is a ***beta*** SQL storage backend that stores release information in an SQL +database. + +Using such a storage backend is particularly useful if your release information +weighs more than 1MB (in which case, it can't be stored in ConfigMaps/Secrets +because of internal limits in Kubernetes' underlying etcd key-value store). + +To enable the SQL backend, you'll need to deploy a SQL database and set the +environmental variable `HELM_DRIVER` to `sql`. The DB details are set with the +environmental variable `HELM_DRIVER_SQL_CONNECTION_STRING`. + +You can set it in a shell as follows: + +```shell +export HELM_DRIVER=sql +export HELM_DRIVER_SQL_CONNECTION_STRING=postgresql://helm-postgres:5432/helm?user=helm&password=changeme +``` + +> Note: Only PostgreSQL is supported at this moment. + +**PRODUCTION NOTES**: It is recommended to: +- Make your database production ready. For PostgreSQL, refer to the [Server Administration](https://www.postgresql.org/docs/12/admin.html) docs for more details +- Enable [permission management](/docs/permissions_sql_storage_backend/) to +mirror Kubernetes RBAC for release information + +If you want to switch from the default backend to the SQL backend, you'll have +to do the migration for this on your own. You can retrieve release information +with the following command: + +```shell +kubectl get secret --all-namespaces -l "owner=helm" +``` diff --git a/content/en/docs/topics/architecture.md b/content/en/docs/topics/architecture.md new file mode 100644 index 0000000000..08e5281ebd --- /dev/null +++ b/content/en/docs/topics/architecture.md @@ -0,0 +1,64 @@ +--- +title: "Helm Architecture" +description: "Describes the Helm architecture at a high level." +aliases: ["/docs/architecture/"] +weight: 8 +--- + +# Helm Architecture + +This document describes the Helm architecture at a high level. + +## The Purpose of Helm + +Helm is a tool for managing Kubernetes packages called _charts_. Helm can do the +following: + +- Create new charts from scratch +- Package charts into chart archive (tgz) files +- Interact with chart repositories where charts are stored +- Install and uninstall charts into an existing Kubernetes cluster +- Manage the release cycle of charts that have been installed with Helm + +For Helm, there are three important concepts: + +1. The _chart_ is a bundle of information necessary to create an instance of a + Kubernetes application. +2. The _config_ contains configuration information that can be merged into a + packaged chart to create a releasable object. +3. A _release_ is a running instance of a _chart_, combined with a specific + _config_. + +## Components + +Helm is an executable which is implemented into two distinct parts: + +**The Helm Client** is a command-line client for end users. The client is +responsible for the following: + +- Local chart development +- Managing repositories +- Managing releases +- Interfacing with the Helm library + - Sending charts to be installed + - Requesting upgrading or uninstalling of existing releases + +**The Helm Library** provides the logic for executing all Helm operations. It +interfaces with the Kubernetes API server and provides the following capability: + +- Combining a chart and configuration to build a release +- Installing charts into Kubernetes, and providing the subsequent release object +- Upgrading and uninstalling charts by interacting with Kubernetes + +The standalone Helm library encapsulates the Helm logic so that it can be +leveraged by different clients. + +## Implementation + +The Helm client and library is written in the Go programming language. + +The library uses the Kubernetes client library to communicate with Kubernetes. +Currently, that library uses REST+JSON. It stores information in Secrets located +inside of Kubernetes. It does not need its own database. + +Configuration files are, when possible, written in YAML. diff --git a/content/en/docs/topics/chart_repository.md b/content/en/docs/topics/chart_repository.md new file mode 100644 index 0000000000..1bed56421d --- /dev/null +++ b/content/en/docs/topics/chart_repository.md @@ -0,0 +1,325 @@ +--- +title: "The Chart Repository Guide" +description: "How to create and work with Helm chart repositories." +aliases: ["/docs/chart_repository/"] +weight: 6 +--- + +This section explains how to create and work with Helm chart repositories. At a +high level, a chart repository is a location where packaged charts can be stored +and shared. + +The distributed community Helm chart repository is located at +[Artifact Hub](https://artifacthub.io/packages/search?kind=0) and welcomes +participation. But Helm also makes it possible to create and run your own chart +repository. This guide explains how to do so. + +## Prerequisites + +* Go through the [Quickstart]({{< ref "quickstart.md" >}}) Guide +* Read through the [Charts]({{< ref "/docs/topics/charts.md" >}}) document + +## Create a chart repository + +A _chart repository_ is an HTTP server that houses an `index.yaml` file and +optionally some packaged charts. When you're ready to share your charts, the +preferred way to do so is by uploading them to a chart repository. + +As of Helm 2.2.0, client-side SSL auth to a repository is supported. Other +authentication protocols may be available as plugins. + +Because a chart repository can be any HTTP server that can serve YAML and tar +files and can answer GET requests, you have a plethora of options when it comes +down to hosting your own chart repository. For example, you can use a Google +Cloud Storage (GCS) bucket, Amazon S3 bucket, GitHub Pages, or even create your +own web server. + +### The chart repository structure + +A chart repository consists of packaged charts and a special file called +`index.yaml` which contains an index of all of the charts in the repository. +Frequently, the charts that `index.yaml` describes are also hosted on the same +server, as are the [provenance files]({{< ref "provenance.md" >}}). + +For example, the layout of the repository `https://example.com/charts` might +look like this: + +``` +charts/ + | + |- index.yaml + | + |- alpine-0.1.2.tgz + | + |- alpine-0.1.2.tgz.prov +``` + +In this case, the index file would contain information about one chart, the +Alpine chart, and provide the download URL +`https://example.com/charts/alpine-0.1.2.tgz` for that chart. + +It is not required that a chart package be located on the same server as the +`index.yaml` file. However, doing so is often the easiest. + +### The index file + +The index file is a yaml file called `index.yaml`. It contains some metadata +about the package, including the contents of a chart's `Chart.yaml` file. A +valid chart repository must have an index file. The index file contains +information about each chart in the chart repository. The `helm repo index` +command will generate an index file based on a given local directory that +contains packaged charts. + +This is an example of an index file: + +```yaml +apiVersion: v1 +entries: + alpine: + - created: 2016-10-06T16:23:20.499814565-06:00 + description: Deploy a basic Alpine Linux pod + digest: 99c76e403d752c84ead610644d4b1c2f2b453a74b921f422b9dcb8a7c8b559cd + home: https://helm.sh/helm + name: alpine + sources: + - https://github.com/helm/helm + urls: + - https://technosophos.github.io/tscharts/alpine-0.2.0.tgz + version: 0.2.0 + - created: 2016-10-06T16:23:20.499543808-06:00 + description: Deploy a basic Alpine Linux pod + digest: 515c58e5f79d8b2913a10cb400ebb6fa9c77fe813287afbacf1a0b897cd78727 + home: https://helm.sh/helm + name: alpine + sources: + - https://github.com/helm/helm + urls: + - https://technosophos.github.io/tscharts/alpine-0.1.0.tgz + version: 0.1.0 + nginx: + - created: 2016-10-06T16:23:20.499543808-06:00 + description: Create a basic nginx HTTP server + digest: aaff4545f79d8b2913a10cb400ebb6fa9c77fe813287afbacf1a0b897cdffffff + home: https://helm.sh/helm + name: nginx + sources: + - https://github.com/helm/charts + urls: + - https://technosophos.github.io/tscharts/nginx-1.1.0.tgz + version: 1.1.0 +generated: 2016-10-06T16:23:20.499029981-06:00 +``` + +## Hosting Chart Repositories + +This part shows several ways to serve a chart repository. + +### Google Cloud Storage + +The first step is to **create your GCS bucket**. We'll call ours +`fantastic-charts`. + +![Create a GCS Bucket](https://helm.sh/img/create-a-bucket.png) + +Next, make your bucket public by **editing the bucket permissions**. + +![Edit Permissions](https://helm.sh/img/edit-permissions.png) + +Insert this line item to **make your bucket public**: + +![Make Bucket Public](https://helm.sh/img/make-bucket-public.png) + +Congratulations, now you have an empty GCS bucket ready to serve charts! + +You may upload your chart repository using the Google Cloud Storage command +line tool, or using the GCS web UI. A public GCS bucket can be accessed via +simple HTTPS at this address: `https://bucket-name.storage.googleapis.com/`. + +### Cloudsmith + +You can also set up chart repositories using Cloudsmith. Read more about +chart repositories with Cloudsmith +[here](https://help.cloudsmith.io/docs/helm-chart-repository) + +### JFrog Artifactory + +Similarly, you can also set up chart repositories using JFrog Artifactory. Read more about +chart repositories with JFrog Artifactory +[here](https://www.jfrog.com/confluence/display/RTF/Helm+Chart+Repositories) + +### GitHub Pages example + +In a similar way you can create charts repository using GitHub Pages. + +GitHub allows you to serve static web pages in two different ways: + +- By configuring a project to serve the contents of its `docs/` directory +- By configuring a project to serve a particular branch + +We'll take the second approach, though the first is just as easy. + +The first step will be to **create your gh-pages branch**. You can do that +locally as. + +```console +$ git checkout -b gh-pages +``` + +Or via web browser using **Branch** button on your GitHub repository: + +![Create GitHub Pages branch](https://helm.sh/img/create-a-gh-page-button.png) + +Next, you'll want to make sure your **gh-pages branch** is set as GitHub Pages, +click on your repo **Settings** and scroll down to **GitHub pages** section and +set as per below: + +![Create GitHub Pages branch](https://helm.sh/img/set-a-gh-page.png) + +By default **Source** usually gets set to **gh-pages branch**. If this is not +set by default, then select it. + +You can use a **custom domain** there if you wish so. + +And check that **Enforce HTTPS** is ticked, so the **HTTPS** will be used when +charts are served. + +In such setup you can use your default branch to store your charts code, and +**gh-pages branch** as charts repository, e.g.: +`https://USERNAME.github.io/REPONAME`. The demonstration [TS +Charts](https://github.com/technosophos/tscharts) repository is accessible at +`https://technosophos.github.io/tscharts/`. + +If you have decided to use GitHub pages to host the chart repository, check out +[Chart Releaser Action]({{< ref "/docs/howto/chart_releaser_action.md" >}}). +Chart Releaser Action is a GitHub Action workflow to turn a GitHub project into +a self-hosted Helm chart repo, using +[helm/chart-releaser](https://github.com/helm/chart-releaser) CLI tool. + +### Ordinary web servers + +To configure an ordinary web server to serve Helm charts, you merely need to do +the following: + +- Put your index and charts in a directory that the server can serve +- Make sure the `index.yaml` file can be accessed with no authentication + requirement +- Make sure `yaml` files are served with the correct content type (`text/yaml` + or `text/x-yaml`) + +For example, if you want to serve your charts out of `$WEBROOT/charts`, make +sure there is a `charts/` directory in your web root, and put the index file and +charts inside of that folder. + +### ChartMuseum Repository Server + +ChartMuseum is an open-source Helm Chart Repository server written in Go +(Golang), with support for cloud storage backends, including [Google Cloud +Storage](https://cloud.google.com/storage/), [Amazon +S3](https://aws.amazon.com/s3/), [Microsoft Azure Blob +Storage](https://azure.microsoft.com/en-us/services/storage/blobs/), [Alibaba +Cloud OSS Storage](https://www.alibabacloud.com/product/oss), [Openstack Object +Storage](https://developer.openstack.org/api-ref/object-store/), [Oracle Cloud +Infrastructure Object Storage](https://cloud.oracle.com/storage), [Baidu Cloud +BOS Storage](https://cloud.baidu.com/product/bos.html), [Tencent Cloud Object +Storage](https://intl.cloud.tencent.com/product/cos), [DigitalOcean +Spaces](https://www.digitalocean.com/products/spaces/), +[Minio](https://min.io/), and [etcd](https://etcd.io/). + +You can also use the +[ChartMuseum](https://chartmuseum.com/docs/#using-with-local-filesystem-storage) +server to host a chart repository from a local file system. + +### GitLab Package Registry + +With GitLab you can publish Helm charts in your project’s Package Registry. +Read more about setting up a helm package repository with GitLab [here](https://docs.gitlab.com/ee/user/packages/helm_repository/). + +## Managing Chart Repositories + +Now that you have a chart repository, the last part of this guide explains how +to maintain charts in that repository. + + +### Store charts in your chart repository + +Now that you have a chart repository, let's upload a chart and an index file to +the repository. Charts in a chart repository must be packaged (`helm package +chart-name/`) and versioned correctly (following [SemVer 2](https://semver.org/) +guidelines). + +These next steps compose an example workflow, but you are welcome to use +whatever workflow you fancy for storing and updating charts in your chart +repository. + +Once you have a packaged chart ready, create a new directory, and move your +packaged chart to that directory. + +```console +$ helm package docs/examples/alpine/ +$ mkdir fantastic-charts +$ mv alpine-0.1.0.tgz fantastic-charts/ +$ helm repo index fantastic-charts --url https://fantastic-charts.storage.googleapis.com +``` + +The last command takes the path of the local directory that you just created and +the URL of your remote chart repository and composes an `index.yaml` file inside +the given directory path. + +Now you can upload the chart and the index file to your chart repository using a +sync tool or manually. If you're using Google Cloud Storage, check out this +[example workflow]({{< ref "/docs/howto/chart_repository_sync_example.md" >}}) +using the gsutil client. For GitHub, you can simply put the charts in the +appropriate destination branch. + +### Add new charts to an existing repository + +Each time you want to add a new chart to your repository, you must regenerate +the index. The `helm repo index` command will completely rebuild the +`index.yaml` file from scratch, including only the charts that it finds locally. + +However, you can use the `--merge` flag to incrementally add new charts to an +existing `index.yaml` file (a great option when working with a remote repository +like GCS). Run `helm repo index --help` to learn more, + +Make sure that you upload both the revised `index.yaml` file and the chart. And +if you generated a provenance file, upload that too. + +### Share your charts with others + +When you're ready to share your charts, simply let someone know what the URL of +your repository is. + +From there, they will add the repository to their helm client via the `helm repo +add [NAME] [URL]` command with any name they would like to use to reference the +repository. + +```console +$ helm repo add fantastic-charts https://fantastic-charts.storage.googleapis.com +$ helm repo list +fantastic-charts https://fantastic-charts.storage.googleapis.com +``` + +If the charts are backed by HTTP basic authentication, you can also supply the +username and password here: + +```console +$ helm repo add fantastic-charts https://fantastic-charts.storage.googleapis.com --username my-username --password my-password +$ helm repo list +fantastic-charts https://fantastic-charts.storage.googleapis.com +``` + +**Note:** A repository will not be added if it does not contain a valid +`index.yaml`. + +**Note:** If your helm repository is e.g. using a self signed +certificate, you can use `helm repo add --insecure-skip-tls-verify ...` in order +to skip the CA verification. + +After that, your users will be able to search through your charts. After you've +updated the repository, they can use the `helm repo update` command to get the +latest chart information. + +*Under the hood, the `helm repo add` and `helm repo update` commands are +fetching the index.yaml file and storing them in the +`$XDG_CACHE_HOME/helm/repository/cache/` directory. This is where the `helm +search` function finds information about charts.* diff --git a/content/en/docs/topics/chart_tests.md b/content/en/docs/topics/chart_tests.md new file mode 100644 index 0000000000..cf9bfec35e --- /dev/null +++ b/content/en/docs/topics/chart_tests.md @@ -0,0 +1,105 @@ +--- +title: "Chart Tests" +description: "Describes how to run and test your charts." +aliases: ["/docs/chart_tests/"] +weight: 3 +--- + +A chart contains a number of Kubernetes resources and components that work +together. As a chart author, you may want to write some tests that validate that +your chart works as expected when it is installed. These tests also help the +chart consumer understand what your chart is supposed to do. + +A **test** in a helm chart lives under the `templates/` directory and is a job +definition that specifies a container with a given command to run. The container +should exit successfully (exit 0) for a test to be considered a success. The job +definition must contain the helm test hook annotation: `helm.sh/hook: test`. + +Note that until Helm v3, the job definition needed to contain one of these helm +test hook annotations: `helm.sh/hook: test-success` or `helm.sh/hook: test-failure`. +`helm.sh/hook: test-success` is still accepted as a backwards-compatible +alternative to `helm.sh/hook: test`. + +Example tests: + +- Validate that your configuration from the values.yaml file was properly + injected. + - Make sure your username and password work correctly + - Make sure an incorrect username and password does not work +- Assert that your services are up and correctly load balancing +- etc. + +You can run the pre-defined tests in Helm on a release using the command `helm +test `. For a chart consumer, this is a great way to check that +their release of a chart (or application) works as expected. + +## Example Test + +The [helm create](/docs/helm/helm_create) command will automatically create a number of folders and files. To try the helm test functionality, first create a demo helm chart. + +```console +$ helm create demo +``` + +You will now be able to see the following structure in your demo helm chart. + +``` +demo/ + Chart.yaml + values.yaml + charts/ + templates/ + templates/tests/test-connection.yaml +``` + +In `demo/templates/tests/test-connection.yaml` you'll see a test you can try. You can see the helm test pod definition here: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "demo.fullname" . }}-test-connection" + labels: + {{- include "demo.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['{{ include "demo.fullname" . }}:{{ .Values.service.port }}'] + restartPolicy: Never + +``` + +## Steps to Run a Test Suite on a Release + +First, install the chart on your cluster to create a release. You may have to +wait for all pods to become active; if you test immediately after this install, +it is likely to show a transitive failure, and you will want to re-test. + +```console +$ helm install demo demo --namespace default +$ helm test demo +NAME: demo +LAST DEPLOYED: Mon Feb 14 20:03:16 2022 +NAMESPACE: default +STATUS: deployed +REVISION: 1 +TEST SUITE: demo-test-connection +Last Started: Mon Feb 14 20:35:19 2022 +Last Completed: Mon Feb 14 20:35:23 2022 +Phase: Succeeded +[...] +``` + +## Notes + +- You can define as many tests as you would like in a single yaml file or spread + across several yaml files in the `templates/` directory. +- You are welcome to nest your test suite under a `tests/` directory like + `/templates/tests/` for more isolation. +- A test is a [Helm hook](/docs/charts_hooks/), so annotations like + `helm.sh/hook-weight` and `helm.sh/hook-delete-policy` may be used with test + resources. diff --git a/content/en/docs/topics/charts.md b/content/en/docs/topics/charts.md new file mode 100644 index 0000000000..cdfb6b09e4 --- /dev/null +++ b/content/en/docs/topics/charts.md @@ -0,0 +1,1124 @@ +--- +title: "Charts" +description: "Explains the chart format, and provides basic guidance for building charts with Helm." +aliases: [ + "docs/developing_charts/", + "developing_charts" +] +weight: 1 +--- + +Helm uses a packaging format called _charts_. A chart is a collection of files +that describe a related set of Kubernetes resources. A single chart might be +used to deploy something simple, like a memcached pod, or something complex, +like a full web app stack with HTTP servers, databases, caches, and so on. + +Charts are created as files laid out in a particular directory tree. They can be +packaged into versioned archives to be deployed. + +If you want to download and look at the files for a published chart, without +installing it, you can do so with `helm pull chartrepo/chartname`. + +This document explains the chart format, and provides basic guidance for +building charts with Helm. + +## The Chart File Structure + +A chart is organized as a collection of files inside of a directory. The +directory name is the name of the chart (without versioning information). Thus, +a chart describing WordPress would be stored in a `wordpress/` directory. + +Inside of this directory, Helm will expect a structure that matches this: + +```text +wordpress/ + Chart.yaml # A YAML file containing information about the chart + LICENSE # OPTIONAL: A plain text file containing the license for the chart + README.md # OPTIONAL: A human-readable README file + values.yaml # The default configuration values for this chart + values.schema.json # OPTIONAL: A JSON Schema for imposing a structure on the values.yaml file + charts/ # A directory containing any charts upon which this chart depends. + crds/ # Custom Resource Definitions + templates/ # A directory of templates that, when combined with values, + # will generate valid Kubernetes manifest files. + templates/NOTES.txt # OPTIONAL: A plain text file containing short usage notes +``` + +Helm reserves use of the `charts/`, `crds/`, and `templates/` directories, and +of the listed file names. Other files will be left as they are. + +## The Chart.yaml File + +The `Chart.yaml` file is required for a chart. It contains the following fields: + +```yaml +apiVersion: The chart API version (required) +name: The name of the chart (required) +version: A SemVer 2 version (required) +kubeVersion: A SemVer range of compatible Kubernetes versions (optional) +description: A single-sentence description of this project (optional) +type: The type of the chart (optional) +keywords: + - A list of keywords about this project (optional) +home: The URL of this projects home page (optional) +sources: + - A list of URLs to source code for this project (optional) +dependencies: # A list of the chart requirements (optional) + - name: The name of the chart (nginx) + version: The version of the chart ("1.2.3") + repository: (optional) The repository URL ("https://example.com/charts") or alias ("@repo-name") + condition: (optional) A yaml path that resolves to a boolean, used for enabling/disabling charts (e.g. subchart1.enabled ) + tags: # (optional) + - Tags can be used to group charts for enabling/disabling together + import-values: # (optional) + - ImportValues holds the mapping of source values to parent key to be imported. Each item can be a string or pair of child/parent sublist items. + alias: (optional) Alias to be used for the chart. Useful when you have to add the same chart multiple times +maintainers: # (optional) + - name: The maintainers name (required for each maintainer) + email: The maintainers email (optional for each maintainer) + url: A URL for the maintainer (optional for each maintainer) +icon: A URL to an SVG or PNG image to be used as an icon (optional). +appVersion: The version of the app that this contains (optional). Needn't be SemVer. Quotes recommended. +deprecated: Whether this chart is deprecated (optional, boolean) +annotations: + example: A list of annotations keyed by name (optional). +``` + +As of [v3.3.2](https://github.com/helm/helm/releases/tag/v3.3.2), additional +fields are not allowed. +The recommended approach is to add custom metadata in `annotations`. + +### Charts and Versioning + +Every chart must have a version number. A version must follow the [SemVer +2](https://semver.org/spec/v2.0.0.html) standard. Unlike Helm Classic, Helm v2 +and later uses version numbers as release markers. Packages in repositories are +identified by name plus version. + +For example, an `nginx` chart whose version field is set to `version: 1.2.3` +will be named: + +```text +nginx-1.2.3.tgz +``` + +More complex SemVer 2 names are also supported, such as `version: +1.2.3-alpha.1+ef365`. But non-SemVer names are explicitly disallowed by the +system. + +**NOTE:** Whereas Helm Classic and Deployment Manager were both very GitHub +oriented when it came to charts, Helm v2 and later does not rely upon or require +GitHub or even Git. Consequently, it does not use Git SHAs for versioning at +all. + +The `version` field inside of the `Chart.yaml` is used by many of the Helm +tools, including the CLI. When generating a package, the `helm package` command +will use the version that it finds in the `Chart.yaml` as a token in the package +name. The system assumes that the version number in the chart package name +matches the version number in the `Chart.yaml`. Failure to meet this assumption +will cause an error. + +### The `apiVersion` Field + +The `apiVersion` field should be `v2` for Helm charts that require at least Helm +3. Charts supporting previous Helm versions have an `apiVersion` set to `v1` and +are still installable by Helm 3. + +Changes from `v1` to `v2`: + +- A `dependencies` field defining chart dependencies, which were located in a + separate `requirements.yaml` file for `v1` charts (see [Chart + Dependencies](#chart-dependencies)). +- The `type` field, discriminating application and library charts (see [Chart + Types](#chart-types)). + +### The `appVersion` Field + +Note that the `appVersion` field is not related to the `version` field. It is a +way of specifying the version of the application. For example, the `drupal` +chart may have an `appVersion: "8.2.1"`, indicating that the version of Drupal +included in the chart (by default) is `8.2.1`. This field is informational, and +has no impact on chart version calculations. Wrapping the version in quotes is highly recommended. It forces the YAML parser to treat the version number as a string. Leaving it unquoted can lead to parsing issues in some cases. For example, YAML interprets `1.0` as a floating point value, and a git commit SHA like `1234e10` as scientific notation. + +As of Helm v3.5.0, `helm create` wraps the default `appVersion` field in quotes. + +### The `kubeVersion` Field + +The optional `kubeVersion` field can define semver constraints on supported +Kubernetes versions. Helm will validate the version constraints when installing +the chart and fail if the cluster runs an unsupported Kubernetes version. + +Version constraints may comprise space separated AND comparisons such as +``` +>= 1.13.0 < 1.15.0 +``` +which themselves can be combined with the OR `||` operator like in the following +example +``` +>= 1.13.0 < 1.14.0 || >= 1.14.1 < 1.15.0 +``` +In this example the version `1.14.0` is excluded, which can make sense if a bug +in certain versions is known to prevent the chart from running properly. + +Apart from version constrains employing operators `=` `!=` `>` `<` `>=` `<=` the +following shorthand notations are supported + + * hyphen ranges for closed intervals, where `1.1 - 2.3.4` is equivalent to `>= + 1.1 <= 2.3.4`. + * wildcards `x`, `X` and `*`, where `1.2.x` is equivalent to `>= 1.2.0 < + 1.3.0`. + * tilde ranges (patch version changes allowed), where `~1.2.3` is equivalent to + `>= 1.2.3 < 1.3.0`. + * caret ranges (minor version changes allowed), where `^1.2.3` is equivalent to + `>= 1.2.3 < 2.0.0`. + +For a detailed explanation of supported semver constraints see +[Masterminds/semver](https://github.com/Masterminds/semver). + +### Deprecating Charts + +When managing charts in a Chart Repository, it is sometimes necessary to +deprecate a chart. The optional `deprecated` field in `Chart.yaml` can be used +to mark a chart as deprecated. If the **latest** version of a chart in the +repository is marked as deprecated, then the chart as a whole is considered to +be deprecated. The chart name can be later reused by publishing a newer version +that is not marked as deprecated. The workflow for deprecating charts is: + +1. Update chart's `Chart.yaml` to mark the chart as deprecated, bumping the + version +2. Release the new chart version in the Chart Repository +3. Remove the chart from the source repository (e.g. git) + +### Chart Types + +The `type` field defines the type of chart. There are two types: `application` +and `library`. Application is the default type and it is the standard chart +which can be operated on fully. The [library chart]({{< ref +"/docs/topics/library_charts.md" >}}) provides utilities or functions for the +chart builder. A library chart differs from an application chart because it is +not installable and usually doesn't contain any resource objects. + +**Note:** An application chart can be used as a library chart. This is enabled +by setting the type to `library`. The chart will then be rendered as a library +chart where all utilities and functions can be leveraged. All resource objects +of the chart will not be rendered. + +## Chart LICENSE, README and NOTES + +Charts can also contain files that describe the installation, configuration, +usage and license of a chart. + +A LICENSE is a plain text file containing the +[license](https://en.wikipedia.org/wiki/Software_license) for the chart. The +chart can contain a license as it may have programming logic in the templates +and would therefore not be configuration only. There can also be separate +license(s) for the application installed by the chart, if required. + +A README for a chart should be formatted in Markdown (README.md), and should +generally contain: + +- A description of the application or service the chart provides +- Any prerequisites or requirements to run the chart +- Descriptions of options in `values.yaml` and default values +- Any other information that may be relevant to the installation or + configuration of the chart + +When hubs and other user interfaces display details about a chart that detail is +pulled from the content in the `README.md` file. + +The chart can also contain a short plain text `templates/NOTES.txt` file that +will be printed out after installation, and when viewing the status of a +release. This file is evaluated as a [template](#templates-and-values), and can +be used to display usage notes, next steps, or any other information relevant to +a release of the chart. For example, instructions could be provided for +connecting to a database, or accessing a web UI. Since this file is printed to +STDOUT when running `helm install` or `helm status`, it is recommended to keep +the content brief and point to the README for greater detail. + +## Chart Dependencies + +In Helm, one chart may depend on any number of other charts. These dependencies +can be dynamically linked using the `dependencies` field in `Chart.yaml` or +brought in to the `charts/` directory and managed manually. + +### Managing Dependencies with the `dependencies` field + +The charts required by the current chart are defined as a list in the +`dependencies` field. + +```yaml +dependencies: + - name: apache + version: 1.2.3 + repository: https://example.com/charts + - name: mysql + version: 3.2.1 + repository: https://another.example.com/charts +``` + +- The `name` field is the name of the chart you want. +- The `version` field is the version of the chart you want. +- The `repository` field is the full URL to the chart repository. Note that you + must also use `helm repo add` to add that repo locally. +- You might use the name of the repo instead of URL + +```console +$ helm repo add fantastic-charts https://charts.helm.sh/incubator +``` + +```yaml +dependencies: + - name: awesomeness + version: 1.0.0 + repository: "@fantastic-charts" +``` + +Once you have defined dependencies, you can run `helm dependency update` and it +will use your dependency file to download all the specified charts into your +`charts/` directory for you. + +```console +$ helm dep up foochart +Hang tight while we grab the latest from your chart repositories... +...Successfully got an update from the "local" chart repository +...Successfully got an update from the "stable" chart repository +...Successfully got an update from the "example" chart repository +...Successfully got an update from the "another" chart repository +Update Complete. Happy Helming! +Saving 2 charts +Downloading apache from repo https://example.com/charts +Downloading mysql from repo https://another.example.com/charts +``` + +When `helm dependency update` retrieves charts, it will store them as chart +archives in the `charts/` directory. So for the example above, one would expect +to see the following files in the charts directory: + +```text +charts/ + apache-1.2.3.tgz + mysql-3.2.1.tgz +``` + +#### Alias field in dependencies + +In addition to the other fields above, each requirements entry may contain the +optional field `alias`. + +Adding an alias for a dependency chart would put a chart in dependencies using +alias as name of new dependency. + +One can use `alias` in cases where they need to access a chart with other +name(s). + +```yaml +# parentchart/Chart.yaml + +dependencies: + - name: subchart + repository: http://localhost:10191 + version: 0.1.0 + alias: new-subchart-1 + - name: subchart + repository: http://localhost:10191 + version: 0.1.0 + alias: new-subchart-2 + - name: subchart + repository: http://localhost:10191 + version: 0.1.0 +``` + +In the above example we will get 3 dependencies in all for `parentchart`: + +```text +subchart +new-subchart-1 +new-subchart-2 +``` + +The manual way of achieving this is by copy/pasting the same chart in the +`charts/` directory multiple times with different names. + +#### Tags and Condition fields in dependencies + +In addition to the other fields above, each requirements entry may contain the +optional fields `tags` and `condition`. + +All charts are loaded by default. If `tags` or `condition` fields are present, +they will be evaluated and used to control loading for the chart(s) they are +applied to. + +Condition - The condition field holds one or more YAML paths (delimited by +commas). If this path exists in the top parent's values and resolves to a +boolean value, the chart will be enabled or disabled based on that boolean +value. Only the first valid path found in the list is evaluated and if no paths +exist then the condition has no effect. + +Tags - The tags field is a YAML list of labels to associate with this chart. In +the top parent's values, all charts with tags can be enabled or disabled by +specifying the tag and a boolean value. + +```yaml +# parentchart/Chart.yaml + +dependencies: + - name: subchart1 + repository: http://localhost:10191 + version: 0.1.0 + condition: subchart1.enabled,global.subchart1.enabled + tags: + - front-end + - subchart1 + - name: subchart2 + repository: http://localhost:10191 + version: 0.1.0 + condition: subchart2.enabled,global.subchart2.enabled + tags: + - back-end + - subchart2 +``` + +```yaml +# parentchart/values.yaml + +subchart1: + enabled: true +tags: + front-end: false + back-end: true +``` + +In the above example all charts with the tag `front-end` would be disabled but +since the `subchart1.enabled` path evaluates to 'true' in the parent's values, +the condition will override the `front-end` tag and `subchart1` will be enabled. + +Since `subchart2` is tagged with `back-end` and that tag evaluates to `true`, +`subchart2` will be enabled. Also note that although `subchart2` has a condition +specified, there is no corresponding path and value in the parent's values so +that condition has no effect. + +##### Using the CLI with Tags and Conditions + +The `--set` parameter can be used as usual to alter tag and condition values. + +```console +helm install --set tags.front-end=true --set subchart2.enabled=false +``` + +##### Tags and Condition Resolution + +- **Conditions (when set in values) always override tags.** The first condition + path that exists wins and subsequent ones for that chart are ignored. +- Tags are evaluated as 'if any of the chart's tags are true then enable the + chart'. +- Tags and conditions values must be set in the top parent's values. +- The `tags:` key in values must be a top level key. Globals and nested `tags:` + tables are not currently supported. + +#### Importing Child Values via dependencies + +In some cases it is desirable to allow a child chart's values to propagate to +the parent chart and be shared as common defaults. An additional benefit of +using the `exports` format is that it will enable future tooling to introspect +user-settable values. + +The keys containing the values to be imported can be specified in the parent +chart's `dependencies` in the field `import-values` using a YAML list. Each item +in the list is a key which is imported from the child chart's `exports` field. + +To import values not contained in the `exports` key, use the +[child-parent](#using-the-child-parent-format) format. Examples of both formats +are described below. + +##### Using the exports format + +If a child chart's `values.yaml` file contains an `exports` field at the root, +its contents may be imported directly into the parent's values by specifying the +keys to import as in the example below: + +```yaml +# parent's Chart.yaml file + +dependencies: + - name: subchart + repository: http://localhost:10191 + version: 0.1.0 + import-values: + - data +``` + +```yaml +# child's values.yaml file + +exports: + data: + myint: 99 +``` + +Since we are specifying the key `data` in our import list, Helm looks in the +`exports` field of the child chart for `data` key and imports its contents. + +The final parent values would contain our exported field: + +```yaml +# parent's values + +myint: 99 +``` + +Please note the parent key `data` is not contained in the parent's final values. +If you need to specify the parent key, use the 'child-parent' format. + +##### Using the child-parent format + +To access values that are not contained in the `exports` key of the child +chart's values, you will need to specify the source key of the values to be +imported (`child`) and the destination path in the parent chart's values +(`parent`). + +The `import-values` in the example below instructs Helm to take any values found +at `child:` path and copy them to the parent's values at the path specified in +`parent:` + +```yaml +# parent's Chart.yaml file + +dependencies: + - name: subchart1 + repository: http://localhost:10191 + version: 0.1.0 + ... + import-values: + - child: default.data + parent: myimports +``` + +In the above example, values found at `default.data` in the subchart1's values +will be imported to the `myimports` key in the parent chart's values as detailed +below: + +```yaml +# parent's values.yaml file + +myimports: + myint: 0 + mybool: false + mystring: "helm rocks!" +``` + +```yaml +# subchart1's values.yaml file + +default: + data: + myint: 999 + mybool: true +``` + +The parent chart's resulting values would be: + +```yaml +# parent's final values + +myimports: + myint: 999 + mybool: true + mystring: "helm rocks!" +``` + +The parent's final values now contains the `myint` and `mybool` fields imported +from subchart1. + +### Managing Dependencies manually via the `charts/` directory + +If more control over dependencies is desired, these dependencies can be +expressed explicitly by copying the dependency charts into the `charts/` +directory. + +A dependency should be an unpacked chart directory but its name cannot start +with `_` or `.`. Such files are ignored by the chart loader. + +For example, if the WordPress chart depends on the Apache chart, the Apache +chart (of the correct version) is supplied in the WordPress chart's `charts/` +directory: + +```yaml +wordpress: + Chart.yaml + # ... + charts/ + apache/ + Chart.yaml + # ... + mysql/ + Chart.yaml + # ... +``` + +The example above shows how the WordPress chart expresses its dependency on +Apache and MySQL by including those charts inside of its `charts/` directory. + +**TIP:** _To drop a dependency into your `charts/` directory, use the `helm +pull` command_ + +### Operational aspects of using dependencies + +The above sections explain how to specify chart dependencies, but how does this +affect chart installation using `helm install` and `helm upgrade`? + +Suppose that a chart named "A" creates the following Kubernetes objects + +- namespace "A-Namespace" +- statefulset "A-StatefulSet" +- service "A-Service" + +Furthermore, A is dependent on chart B that creates objects + +- namespace "B-Namespace" +- replicaset "B-ReplicaSet" +- service "B-Service" + +After installation/upgrade of chart A a single Helm release is created/modified. +The release will create/update all of the above Kubernetes objects in the +following order: + +- A-Namespace +- B-Namespace +- A-Service +- B-Service +- B-ReplicaSet +- A-StatefulSet + +This is because when Helm installs/upgrades charts, the Kubernetes objects from +the charts and all its dependencies are + +- aggregated into a single set; then +- sorted by type followed by name; and then +- created/updated in that order. + +Hence a single release is created with all the objects for the chart and its +dependencies. + +The install order of Kubernetes types is given by the enumeration InstallOrder +in kind_sorter.go (see [the Helm source +file](https://github.com/helm/helm/blob/484d43913f97292648c867b56768775a55e4bba6/pkg/releaseutil/kind_sorter.go)). + +## Templates and Values + +Helm Chart templates are written in the [Go template +language](https://golang.org/pkg/text/template/), with the addition of 50 or so +add-on template functions [from the Sprig +library](https://github.com/Masterminds/sprig) and a few other [specialized +functions]({{< ref "/docs/howto/charts_tips_and_tricks.md" >}}). + +All template files are stored in a chart's `templates/` folder. When Helm +renders the charts, it will pass every file in that directory through the +template engine. + +Values for the templates are supplied two ways: + +- Chart developers may supply a file called `values.yaml` inside of a chart. + This file can contain default values. +- Chart users may supply a YAML file that contains values. This can be provided + on the command line with `helm install`. + +When a user supplies custom values, these values will override the values in the +chart's `values.yaml` file. + +### Template Files + +Template files follow the standard conventions for writing Go templates (see +[the text/template Go package +documentation](https://golang.org/pkg/text/template/) for details). An example +template file might look something like this: + +```yaml +apiVersion: v1 +kind: ReplicationController +metadata: + name: deis-database + namespace: deis + labels: + app.kubernetes.io/managed-by: deis +spec: + replicas: 1 + selector: + app.kubernetes.io/name: deis-database + template: + metadata: + labels: + app.kubernetes.io/name: deis-database + spec: + serviceAccount: deis-database + containers: + - name: deis-database + image: {{ .Values.imageRegistry }}/postgres:{{ .Values.dockerTag }} + imagePullPolicy: {{ .Values.pullPolicy }} + ports: + - containerPort: 5432 + env: + - name: DATABASE_STORAGE + value: {{ default "minio" .Values.storage }} +``` + +The above example, based loosely on +[https://github.com/deis/charts](https://github.com/deis/charts), is a template +for a Kubernetes replication controller. It can use the following four template +values (usually defined in a `values.yaml` file): + +- `imageRegistry`: The source registry for the Docker image. +- `dockerTag`: The tag for the docker image. +- `pullPolicy`: The Kubernetes pull policy. +- `storage`: The storage backend, whose default is set to `"minio"` + +All of these values are defined by the template author. Helm does not require or +dictate parameters. + +To see many working charts, check out the CNCF [Artifact +Hub](https://artifacthub.io/packages/search?kind=0). + +### Predefined Values + +Values that are supplied via a `values.yaml` file (or via the `--set` flag) are +accessible from the `.Values` object in a template. But there are other +pre-defined pieces of data you can access in your templates. + +The following values are pre-defined, are available to every template, and +cannot be overridden. As with all values, the names are _case sensitive_. + +- `Release.Name`: The name of the release (not the chart) +- `Release.Namespace`: The namespace the chart was released to. +- `Release.Service`: The service that conducted the release. +- `Release.IsUpgrade`: This is set to true if the current operation is an + upgrade or rollback. +- `Release.IsInstall`: This is set to true if the current operation is an + install. +- `Chart`: The contents of the `Chart.yaml`. Thus, the chart version is + obtainable as `Chart.Version` and the maintainers are in `Chart.Maintainers`. +- `Files`: A map-like object containing all non-special files in the chart. This + will not give you access to templates, but will give you access to additional + files that are present (unless they are excluded using `.helmignore`). Files + can be accessed using `{{ index .Files "file.name" }}` or using the + `{{.Files.Get name }}` function. You can also access the contents of the file + as `[]byte` using `{{ .Files.GetBytes }}` +- `Capabilities`: A map-like object that contains information about the versions + of Kubernetes (`{{ .Capabilities.KubeVersion }}`) and the supported Kubernetes + API versions (`{{ .Capabilities.APIVersions.Has "batch/v1" }}`) + +**NOTE:** Any unknown `Chart.yaml` fields will be dropped. They will not be +accessible inside of the `Chart` object. Thus, `Chart.yaml` cannot be used to +pass arbitrarily structured data into the template. The values file can be used +for that, though. + +### Values files + +Considering the template in the previous section, a `values.yaml` file that +supplies the necessary values would look like this: + +```yaml +imageRegistry: "quay.io/deis" +dockerTag: "latest" +pullPolicy: "Always" +storage: "s3" +``` + +A values file is formatted in YAML. A chart may include a default `values.yaml` +file. The Helm install command allows a user to override values by supplying +additional YAML values: + +```console +$ helm install --generate-name --values=myvals.yaml wordpress +``` + +When values are passed in this way, they will be merged into the default values +file. For example, consider a `myvals.yaml` file that looks like this: + +```yaml +storage: "gcs" +``` + +When this is merged with the `values.yaml` in the chart, the resulting generated +content will be: + +```yaml +imageRegistry: "quay.io/deis" +dockerTag: "latest" +pullPolicy: "Always" +storage: "gcs" +``` + +Note that only the last field was overridden. + +**NOTE:** The default values file included inside of a chart _must_ be named +`values.yaml`. But files specified on the command line can be named anything. + +**NOTE:** If the `--set` flag is used on `helm install` or `helm upgrade`, those +values are simply converted to YAML on the client side. + +**NOTE:** If any required entries in the values file exist, they can be declared +as required in the chart template by using the ['required' function]({{< ref +"/docs/howto/charts_tips_and_tricks.md" >}}) + +Any of these values are then accessible inside of templates using the `.Values` +object: + +```yaml +apiVersion: v1 +kind: ReplicationController +metadata: + name: deis-database + namespace: deis + labels: + app.kubernetes.io/managed-by: deis +spec: + replicas: 1 + selector: + app.kubernetes.io/name: deis-database + template: + metadata: + labels: + app.kubernetes.io/name: deis-database + spec: + serviceAccount: deis-database + containers: + - name: deis-database + image: {{ .Values.imageRegistry }}/postgres:{{ .Values.dockerTag }} + imagePullPolicy: {{ .Values.pullPolicy }} + ports: + - containerPort: 5432 + env: + - name: DATABASE_STORAGE + value: {{ default "minio" .Values.storage }} +``` + +### Scope, Dependencies, and Values + +Values files can declare values for the top-level chart, as well as for any of +the charts that are included in that chart's `charts/` directory. Or, to phrase +it differently, a values file can supply values to the chart as well as to any +of its dependencies. For example, the demonstration WordPress chart above has +both `mysql` and `apache` as dependencies. The values file could supply values +to all of these components: + +```yaml +title: "My WordPress Site" # Sent to the WordPress template + +mysql: + max_connections: 100 # Sent to MySQL + password: "secret" + +apache: + port: 8080 # Passed to Apache +``` + +Charts at a higher level have access to all of the variables defined beneath. So +the WordPress chart can access the MySQL password as `.Values.mysql.password`. +But lower level charts cannot access things in parent charts, so MySQL will not +be able to access the `title` property. Nor, for that matter, can it access +`apache.port`. + +Values are namespaced, but namespaces are pruned. So for the WordPress chart, it +can access the MySQL password field as `.Values.mysql.password`. But for the +MySQL chart, the scope of the values has been reduced and the namespace prefix +removed, so it will see the password field simply as `.Values.password`. + +#### Global Values + +As of 2.0.0-Alpha.2, Helm supports special "global" value. Consider this +modified version of the previous example: + +```yaml +title: "My WordPress Site" # Sent to the WordPress template + +global: + app: MyWordPress + +mysql: + max_connections: 100 # Sent to MySQL + password: "secret" + +apache: + port: 8080 # Passed to Apache +``` + +The above adds a `global` section with the value `app: MyWordPress`. This value +is available to _all_ charts as `.Values.global.app`. + +For example, the `mysql` templates may access `app` as `{{ +.Values.global.app}}`, and so can the `apache` chart. Effectively, the values +file above is regenerated like this: + +```yaml +title: "My WordPress Site" # Sent to the WordPress template + +global: + app: MyWordPress + +mysql: + global: + app: MyWordPress + max_connections: 100 # Sent to MySQL + password: "secret" + +apache: + global: + app: MyWordPress + port: 8080 # Passed to Apache +``` + +This provides a way of sharing one top-level variable with all subcharts, which +is useful for things like setting `metadata` properties like labels. + +If a subchart declares a global variable, that global will be passed _downward_ +(to the subchart's subcharts), but not _upward_ to the parent chart. There is no +way for a subchart to influence the values of the parent chart. + +Also, global variables of parent charts take precedence over the global +variables from subcharts. + +### Schema Files + +Sometimes, a chart maintainer might want to define a structure on their values. +This can be done by defining a schema in the `values.schema.json` file. A schema +is represented as a [JSON Schema](https://json-schema.org/). It might look +something like this: + +```json +{ + "$schema": "https://json-schema.org/draft-07/schema#", + "properties": { + "image": { + "description": "Container Image", + "properties": { + "repo": { + "type": "string" + }, + "tag": { + "type": "string" + } + }, + "type": "object" + }, + "name": { + "description": "Service name", + "type": "string" + }, + "port": { + "description": "Port", + "minimum": 0, + "type": "integer" + }, + "protocol": { + "type": "string" + } + }, + "required": [ + "protocol", + "port" + ], + "title": "Values", + "type": "object" +} +``` + +This schema will be applied to the values to validate it. Validation occurs when +any of the following commands are invoked: + +- `helm install` +- `helm upgrade` +- `helm lint` +- `helm template` + +An example of a `values.yaml` file that meets the requirements of this schema +might look something like this: + +```yaml +name: frontend +protocol: https +port: 443 +``` + +Note that the schema is applied to the final `.Values` object, and not just to +the `values.yaml` file. This means that the following `yaml` file is valid, +given that the chart is installed with the appropriate `--set` option shown +below. + +```yaml +name: frontend +protocol: https +``` + +```console +helm install --set port=443 +``` + +Furthermore, the final `.Values` object is checked against *all* subchart +schemas. This means that restrictions on a subchart can't be circumvented by a +parent chart. This also works backwards - if a subchart has a requirement that +is not met in the subchart's `values.yaml` file, the parent chart *must* satisfy +those restrictions in order to be valid. + +### References + +When it comes to writing templates, values, and schema files, there are several +standard references that will help you out. + +- [Go templates](https://godoc.org/text/template) +- [Extra template functions](https://godoc.org/github.com/Masterminds/sprig) +- [The YAML format](https://yaml.org/spec/) +- [JSON Schema](https://json-schema.org/) + +## Custom Resource Definitions (CRDs) + +Kubernetes provides a mechanism for declaring new types of Kubernetes objects. +Using CustomResourceDefinitions (CRDs), Kubernetes developers can declare custom +resource types. + +In Helm 3, CRDs are treated as a special kind of object. They are installed +before the rest of the chart, and are subject to some limitations. + +CRD YAML files should be placed in the `crds/` directory inside of a chart. +Multiple CRDs (separated by YAML start and end markers) may be placed in the +same file. Helm will attempt to load _all_ of the files in the CRD directory +into Kubernetes. + +CRD files _cannot be templated_. They must be plain YAML documents. + +When Helm installs a new chart, it will upload the CRDs, pause until the CRDs +are made available by the API server, and then start the template engine, render +the rest of the chart, and upload it to Kubernetes. Because of this ordering, +CRD information is available in the `.Capabilities` object in Helm templates, +and Helm templates may create new instances of objects that were declared in +CRDs. + +For example, if your chart had a CRD for `CronTab` in the `crds/` directory, you +may create instances of the `CronTab` kind in the `templates/` directory: + +```text +crontabs/ + Chart.yaml + crds/ + crontab.yaml + templates/ + mycrontab.yaml +``` + +The `crontab.yaml` file must contain the CRD with no template directives: + +```yaml +kind: CustomResourceDefinition +metadata: + name: crontabs.stable.example.com +spec: + group: stable.example.com + versions: + - name: v1 + served: true + storage: true + scope: Namespaced + names: + plural: crontabs + singular: crontab + kind: CronTab +``` + +Then the template `mycrontab.yaml` may create a new `CronTab` (using templates +as usual): + +```yaml +apiVersion: stable.example.com +kind: CronTab +metadata: + name: {{ .Values.name }} +spec: + # ... +``` + +Helm will make sure that the `CronTab` kind has been installed and is available +from the Kubernetes API server before it proceeds installing the things in +`templates/`. + +### Limitations on CRDs + +Unlike most objects in Kubernetes, CRDs are installed globally. For that reason, +Helm takes a very cautious approach in managing CRDs. CRDs are subject to the +following limitations: + +- CRDs are never reinstalled. If Helm determines that the CRDs in the `crds/` + directory are already present (regardless of version), Helm will not attempt + to install or upgrade. +- CRDs are never installed on upgrade or rollback. Helm will only create CRDs on + installation operations. +- CRDs are never deleted. Deleting a CRD automatically deletes all of the CRD's + contents across all namespaces in the cluster. Consequently, Helm will not + delete CRDs. + +Operators who want to upgrade or delete CRDs are encouraged to do this manually +and with great care. + +## Using Helm to Manage Charts + +The `helm` tool has several commands for working with charts. + +It can create a new chart for you: + +```console +$ helm create mychart +Created mychart/ +``` + +Once you have edited a chart, `helm` can package it into a chart archive for +you: + +```console +$ helm package mychart +Archived mychart-0.1.-.tgz +``` + +You can also use `helm` to help you find issues with your chart's formatting or +information: + +```console +$ helm lint mychart +No issues found +``` + +## Chart Repositories + +A _chart repository_ is an HTTP server that houses one or more packaged charts. +While `helm` can be used to manage local chart directories, when it comes to +sharing charts, the preferred mechanism is a chart repository. + +Any HTTP server that can serve YAML files and tar files and can answer GET +requests can be used as a repository server. The Helm team has tested some +servers, including Google Cloud Storage with website mode enabled, and S3 with +website mode enabled. + +A repository is characterized primarily by the presence of a special file called +`index.yaml` that has a list of all of the packages supplied by the repository, +together with metadata that allows retrieving and verifying those packages. + +On the client side, repositories are managed with the `helm repo` commands. +However, Helm does not provide tools for uploading charts to remote repository +servers. This is because doing so would add substantial requirements to an +implementing server, and thus raise the barrier for setting up a repository. + +## Chart Starter Packs + +The `helm create` command takes an optional `--starter` option that lets you +specify a "starter chart". + +Starters are just regular charts, but are located in +`$XDG_DATA_HOME/helm/starters`. As a chart developer, you may author charts that +are specifically designed to be used as starters. Such charts should be designed +with the following considerations in mind: + +- The `Chart.yaml` will be overwritten by the generator. +- Users will expect to modify such a chart's contents, so documentation should + indicate how users can do so. +- All occurrences of `` will be replaced with the specified chart + name so that starter charts can be used as templates. + +Currently the only way to add a chart to `$XDG_DATA_HOME/helm/starters` is to +manually copy it there. In your chart's documentation, you may want to explain +that process. diff --git a/content/en/docs/topics/charts_hooks.md b/content/en/docs/topics/charts_hooks.md new file mode 100644 index 0000000000..d289e89355 --- /dev/null +++ b/content/en/docs/topics/charts_hooks.md @@ -0,0 +1,206 @@ +--- +title: "Chart Hooks" +description: "Describes how to work with chart hooks." +aliases: ["/docs/charts_hooks/"] +weight: 2 +--- + +Helm provides a _hook_ mechanism to allow chart developers to intervene at +certain points in a release's life cycle. For example, you can use hooks to: + +- Load a ConfigMap or Secret during install before any other charts are loaded. +- Execute a Job to back up a database before installing a new chart, and then + execute a second job after the upgrade in order to restore data. +- Run a Job before deleting a release to gracefully take a service out of + rotation before removing it. + +Hooks work like regular templates, but they have special annotations that cause +Helm to utilize them differently. In this section, we cover the basic usage +pattern for hooks. + +## The Available Hooks + +The following hooks are defined: + +| Annotation Value | Description | +| ---------------- | ----------------------------------------------------------------------------------------------------- | +| `pre-install` | Executes after templates are rendered, but before any resources are created in Kubernetes | +| `post-install` | Executes after all resources are loaded into Kubernetes | +| `pre-delete` | Executes on a deletion request before any resources are deleted from Kubernetes | +| `post-delete` | Executes on a deletion request after all of the release's resources have been deleted | +| `pre-upgrade` | Executes on an upgrade request after templates are rendered, but before any resources are updated | +| `post-upgrade` | Executes on an upgrade request after all resources have been upgraded | +| `pre-rollback` | Executes on a rollback request after templates are rendered, but before any resources are rolled back | +| `post-rollback` | Executes on a rollback request after all resources have been modified | +| `test` | Executes when the Helm test subcommand is invoked ([view test docs](/docs/chart_tests/)) | + +_Note that the `crd-install` hook has been removed in favor of the `crds/` +directory in Helm 3._ + +## Hooks and the Release Lifecycle + +Hooks allow you, the chart developer, an opportunity to perform operations at +strategic points in a release lifecycle. For example, consider the lifecycle for +a `helm install`. By default, the lifecycle looks like this: + +1. User runs `helm install foo` +2. The Helm library install API is called +3. After some verification, the library renders the `foo` templates +4. The library loads the resulting resources into Kubernetes +5. The library returns the release object (and other data) to the client +6. The client exits + +Helm defines two hooks for the `install` lifecycle: `pre-install` and +`post-install`. If the developer of the `foo` chart implements both hooks, the +lifecycle is altered like this: + +1. User runs `helm install foo` +2. The Helm library install API is called +3. CRDs in the `crds/` directory are installed +4. After some verification, the library renders the `foo` templates +5. The library prepares to execute the `pre-install` hooks (loading hook + resources into Kubernetes) +6. The library sorts hooks by weight (assigning a weight of 0 by default), + by resource kind and finally by name in ascending order. +7. The library then loads the hook with the lowest weight first (negative to + positive) +8. The library waits until the hook is "Ready" (except for CRDs) +9. The library loads the resulting resources into Kubernetes. Note that if the + `--wait` flag is set, the library will wait until all resources are in a + ready state and will not run the `post-install` hook until they are ready. +10. The library executes the `post-install` hook (loading hook resources) +11. The library waits until the hook is "Ready" +12. The library returns the release object (and other data) to the client +13. The client exits + +What does it mean to wait until a hook is ready? This depends on the resource +declared in the hook. If the resource is a `Job` or `Pod` kind, Helm will wait +until it successfully runs to completion. And if the hook fails, the release +will fail. This is a _blocking operation_, so the Helm client will pause while +the Job is run. + +For all other kinds, as soon as Kubernetes marks the resource as loaded (added +or updated), the resource is considered "Ready". When many resources are +declared in a hook, the resources are executed serially. If they have hook +weights (see below), they are executed in weighted order. +Starting from Helm 3.2.0 hook resources with same weight are installed in the same +order as normal non-hook resources. Otherwise, ordering is +not guaranteed. (In Helm 2.3.0 and after, they are sorted alphabetically. That +behavior, though, is not considered binding and could change in the future.) It +is considered good practice to add a hook weight, and set it to `0` if weight is +not important. + +### Hook resources are not managed with corresponding releases + +The resources that a hook creates are currently not tracked or managed as part +of the release. Once Helm verifies that the hook has reached its ready state, it +will leave the hook resource alone. Garbage collection of hook resources when +the corresponding release is deleted may be added to Helm 3 in the future, so +any hook resources that must never be deleted should be annotated with +`helm.sh/resource-policy: keep`. + +Practically speaking, this means that if you create resources in a hook, you +cannot rely upon `helm uninstall` to remove the resources. To destroy such +resources, you need to either [add a custom `helm.sh/hook-delete-policy` +annotation](#hook-deletion-policies) to the hook template file, or [set the time +to live (TTL) field of a Job +resource](https://kubernetes.io/docs/concepts/workloads/controllers/ttlafterfinished/). + +## Writing a Hook + +Hooks are just Kubernetes manifest files with special annotations in the +`metadata` section. Because they are template files, you can use all of the +normal template features, including reading `.Values`, `.Release`, and +`.Template`. + +For example, this template, stored in `templates/post-install-job.yaml`, +declares a job to be run on `post-install`: + +```yaml +apiVersion: batch/v1 +kind: Job +metadata: + name: "{{ .Release.Name }}" + labels: + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + annotations: + # This is what defines this resource as a hook. Without this line, the + # job is considered part of the release. + "helm.sh/hook": post-install + "helm.sh/hook-weight": "-5" + "helm.sh/hook-delete-policy": hook-succeeded +spec: + template: + metadata: + name: "{{ .Release.Name }}" + labels: + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + spec: + restartPolicy: Never + containers: + - name: post-install-job + image: "alpine:3.3" + command: ["/bin/sleep","{{ default "10" .Values.sleepyTime }}"] + +``` + +What makes this template a hook is the annotation: + +```yaml +annotations: + "helm.sh/hook": post-install +``` + +One resource can implement multiple hooks: + +```yaml +annotations: + "helm.sh/hook": post-install,post-upgrade +``` + +Similarly, there is no limit to the number of different resources that may +implement a given hook. For example, one could declare both a secret and a +config map as a pre-install hook. + +When subcharts declare hooks, those are also evaluated. There is no way for a +top-level chart to disable the hooks declared by subcharts. + +It is possible to define a weight for a hook which will help build a +deterministic executing order. Weights are defined using the following +annotation: + +```yaml +annotations: + "helm.sh/hook-weight": "5" +``` + +Hook weights can be positive or negative numbers but must be represented as +strings. When Helm starts the execution cycle of hooks of a particular Kind it +will sort those hooks in ascending order. + +### Hook deletion policies + +It is possible to define policies that determine when to delete corresponding +hook resources. Hook deletion policies are defined using the following +annotation: + +```yaml +annotations: + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +``` + +You can choose one or more defined annotation values: + +| Annotation Value | Description | +| ---------------------- | -------------------------------------------------------------------- | +| `before-hook-creation` | Delete the previous resource before a new hook is launched (default) | +| `hook-succeeded` | Delete the resource after the hook is successfully executed | +| `hook-failed` | Delete the resource if the hook failed during execution | + +If no hook deletion policy annotation is specified, the `before-hook-creation` +behavior applies by default. diff --git a/content/en/docs/topics/kubernetes_apis.md b/content/en/docs/topics/kubernetes_apis.md new file mode 100644 index 0000000000..ecaeac76b0 --- /dev/null +++ b/content/en/docs/topics/kubernetes_apis.md @@ -0,0 +1,166 @@ +--- +title: "Deprecated Kubernetes APIs" +description: "Explains deprecated Kubernetes APIs in Helm" +aliases: ["docs/k8s_apis/"] +--- + +Kubernetes is an API-driven system and the API evolves over time to reflect the +evolving understanding of the problem space. This is common practice across +systems and their APIs. An important part of evolving APIs is a good deprecation +policy and process to inform users of how changes to APIs are implemented. In +other words, consumers of your API need to know in advance and in what release +an API will be removed or changed. This removes the element of surprise and +breaking changes to consumers. + +The [Kubernetes deprecation +policy](https://kubernetes.io/docs/reference/using-api/deprecation-policy/) +documents how Kubernetes handles the changes to its API versions. The policy for +deprecation states the timeframe that API versions will be supported following a +deprecation announcement. It is therefore important to be aware of deprecation +announcements and know when API versions will be removed, to help minimize the +effect. + +This is an example of an announcement [for the removal of deprecated API +versions in Kubernetes +1.16](https://kubernetes.io/blog/2019/07/18/api-deprecations-in-1-16/) and was +advertised a few months prior to the release. These API versions would have been +announced for deprecation prior to this again. This shows that there is a good +policy in place which informs consumers of API version support. + +Helm templates specify a [Kubernetes API +group](https://kubernetes.io/docs/concepts/overview/kubernetes-api/#api-groups) +when defining a Kubernetes object, similar to a Kubernetes manifest file. It is +specified in the `apiVersion` field of the template and it identifies the API +version of the Kubernetes object. This means that Helm users and chart +maintainers need to be aware when Kubernetes API versions have been deprecated +and in what Kubernetes version they will be removed. + +## Chart Maintainers + +You should audit your charts checking for Kubernetes API versions that are +deprecated or are removed in a Kubernetes version. The API versions found as due +to be or that are now out of support, should be updated to the supported version +and a new version of the chart released. The API version is defined by the +`kind` and `apiVersion` fields. For example, here is a removed `Deployment` +object API version in Kubernetes 1.16: + +```yaml +apiVersion: apps/v1beta1 +kind: Deployment +``` + +## Helm Users + +You should audit the charts that you use (similar to [chart +maintainers](#chart-maintainers)) and identify any charts where API versions are +deprecated or removed in a Kubernetes version. For the charts identified, you +need to check for the latest version of the chart (which has supported API +versions) or update the chart yourself. + +Additionally, you also need to audit any charts deployed (i.e. Helm releases) +checking again for any deprecated or removed API versions. This can be done by +getting details of a release using the `helm get manifest` command. + +The means for updating a Helm release to supported APIs depends on your findings +as follows: + +1. If you find deprecated API versions only then: + - Perform a `helm upgrade` with a version of the chart with supported + Kubernetes API versions + - Add a description in the upgrade, something along the lines to not perform a + rollback to a Helm version prior to this current version +2. If you find any API version(s) that is/are removed in a Kubernetes version + then: + - If you are running a Kubernetes version where the API version(s) are still + available (for example, you are on Kubernetes 1.15 and found you use APIs + that will be removed in Kubernetes 1.16): + - Follow the step 1 procedure + - Otherwise (for example, you are already running a Kubernetes version where + some API versions reported by `helm get manifest` are no longer available): + - You need to edit the release manifest that is stored in the cluster to + update the API versions to supported APIs. See [Updating API Versions of a + Release Manifest](#updating-api-versions-of-a-release-manifest) for more + details + +> Note: In all cases of updating a Helm release with supported APIs, you should +never rollback the release to a version prior to the release version with the +supported APIs. + +> Recommendation: The best practice is to upgrade releases using deprecated API +versions to supported API versions, prior to upgrading to a kubernetes cluster +that removes those API versions. + +If you don't update a release as suggested previously, you will have an error +similar to the following when trying to upgrade a release in a Kubernetes +version where its API version(s) is/are removed: + +``` +Error: UPGRADE FAILED: current release manifest contains removed kubernetes api(s) +for this kubernetes version and it is therefore unable to build the kubernetes +objects for performing the diff. error from kubernetes: unable to recognize "": +no matches for kind "Deployment" in version "apps/v1beta1" +``` + +Helm fails in this scenario because it attempts to create a diff patch between +the current deployed release (which contains the Kubernetes APIs that are +removed in this Kubernetes version) against the chart you are passing with the +updated/supported API versions. The underlying reason for failure is that when +Kubernetes removes an API version, the Kubernetes Go client library can no +longer parse the deprecated objects and Helm therefore fails when calling the +library. Helm unfortunately is unable to recover from this situation and is no +longer able to manage such a release. See [Updating API Versions of a Release +Manifest](#updating-api-versions-of-a-release-manifest) for more details on how +to recover from this scenario. + +## Updating API Versions of a Release Manifest + +The manifest is a property of the Helm release object which is stored in the +data field of a Secret (default) or ConfigMap in the cluster. The data field +contains a gzipped object which is base 64 encoded (there is an additional base +64 encoding for a Secret). There is a Secret/ConfigMap per release +version/revision in the namespace of the release. + +You can use the Helm [mapkubeapis](https://github.com/helm/helm-mapkubeapis) +plugin to perform the update of a release to supported APIs. Check out the +readme for more details. + +Alternatively, you can follow these manual steps to perform an update of the API +versions of a release manifest. Depending on your configuration you will follow +the steps for the Secret or ConfigMap backend. + +- Get the name of the Secret or Configmap associated with the latest deployed + release: + - Secrets backend: `kubectl get secret -l + owner=helm,status=deployed,name= --namespace + | awk '{print $1}' | grep -v NAME` + - ConfigMap backend: `kubectl get configmap -l + owner=helm,status=deployed,name= --namespace + | awk '{print $1}' | grep -v NAME` +- Get latest deployed release details: + - Secrets backend: `kubectl get secret -n + -o yaml > release.yaml` + - ConfigMap backend: `kubectl get configmap -n + -o yaml > release.yaml` +- Backup the release in case you need to restore if something goes wrong: + - `cp release.yaml release.bak` + - In case of emergency, restore: `kubectl apply -f release.bak -n + ` +- Decode the release object: + - Secrets backend:`cat release.yaml | grep -oP '(?<=release: ).*' | base64 -d + | base64 -d | gzip -d > release.data.decoded` + - ConfigMap backend: `cat release.yaml | grep -oP '(?<=release: ).*' | base64 + -d | gzip -d > release.data.decoded` +- Change API versions of the manifests. Can use any tool (e.g. editor) to make + the changes. This is in the `manifest` field of your decoded release object + (`release.data.decoded`) +- Encode the release object: + - Secrets backend: `cat release.data.decoded | gzip | base64 | base64` + - ConfigMap backend: `cat release.data.decoded | gzip | base64` +- Replace `data.release` property value in the deployed release file + (`release.yaml`) with the new encoded release object +- Apply file to namespace: `kubectl apply -f release.yaml -n + ` +- Perform a `helm upgrade` with a version of the chart with supported Kubernetes + API versions +- Add a description in the upgrade, something along the lines to not perform a + rollback to a Helm version prior to this current version diff --git a/content/en/docs/topics/kubernetes_distros.md b/content/en/docs/topics/kubernetes_distros.md new file mode 100644 index 0000000000..5ee61c9581 --- /dev/null +++ b/content/en/docs/topics/kubernetes_distros.md @@ -0,0 +1,104 @@ +--- +title: "Kubernetes Distribution Guide" +description: "Captures information about using Helm in specific Kubernetes environments." +aliases: ["/docs/kubernetes_distros/"] +weight: 10 +--- + +Helm should work with any [conformant version of +Kubernetes](https://github.com/cncf/k8s-conformance) (whether +[certified](https://www.cncf.io/certification/software-conformance/) or not). + +This document captures information about using Helm in specific Kubernetes +environments. Please contribute more details about any distros (sorted +alphabetically) if desired. + + +## AKS + +Helm works with [Azure Kubernetes +Service](https://docs.microsoft.com/en-us/azure/aks/kubernetes-helm). + +## DC/OS + +Helm has been tested and is working on Mesospheres DC/OS 1.11 Kubernetes +platform, and requires no additional configuration. + +## EKS + +Helm works with Amazon Elastic Kubernetes Service (Amazon EKS): +[Using Helm with Amazon +EKS](https://docs.aws.amazon.com/eks/latest/userguide/helm.html). + +## GKE + +Google's GKE hosted Kubernetes platform is known to work with Helm, and requires +no additional configuration. + +## `scripts/local-cluster` and Hyperkube + +Hyperkube configured via `scripts/local-cluster.sh` is known to work. For raw +Hyperkube you may need to do some manual configuration. + +## IKS + +Helm works with [IBM Cloud Kubernetes +Service](https://cloud.ibm.com/docs/containers?topic=containers-helm). + +## KIND (Kubernetes IN Docker) + +Helm is regularly tested on [KIND](https://github.com/kubernetes-sigs/kind). + +## KubeOne + +Helm works in clusters that are set up by KubeOne without caveats. + +## Kubermatic + +Helm works in user clusters that are created by Kubermatic without caveats. +Since seed cluster can be set up in different ways Helm support depends on their +configuration. + +## MicroK8s + +Helm can be enabled in [MicroK8s](https://microk8s.io) using the command: +`microk8s.enable helm3` + +## Minikube + +Helm is tested and known to work with +[Minikube](https://github.com/kubernetes/minikube). It requires no additional +configuration. + +## Openshift + +Helm works straightforward on OpenShift Online, OpenShift Dedicated, OpenShift +Container Platform (version >= 3.6) or OpenShift Origin (version >= 3.6). To +learn more read [this +blog](https://blog.openshift.com/getting-started-helm-openshift/) post. + +## Platform9 + +Helm is pre-installed with [Platform9 Managed +Kubernetes](https://platform9.com/managed-kubernetes/?utm_source=helm_distro_notes). +Platform9 provides access to all official Helm charts through the App Catalog UI +and native Kubernetes CLI. Additional repositories can be manually added. +Further details are available in this [Platform9 App Catalog +article](https://platform9.com/support/deploying-kubernetes-apps-platform9-managed-kubernetes/?utm_source=helm_distro_notes). + +## Ubuntu with `kubeadm` + +Kubernetes bootstrapped with `kubeadm` is known to work on the following Linux +distributions: + +- Ubuntu 16.04 +- Fedora release 25 + +Some versions of Helm (v2.0.0-beta2) require you to `export +KUBECONFIG=/etc/kubernetes/admin.conf` or create a `~/.kube/config`. + +## VMware Tanzu Kubernetes Grid + +Helm runs on VMware Tanzu Kubernetes Grid, TKG, without needing configuration changes. +The Tanzu CLI can manage installing packages for [helm-controller](https://fluxcd.io/flux/components/helm/) allowing for declaratively managing Helm chart releases. +Further details available in the TKG documentation for [CLI-Managed Packages](https://docs.vmware.com/en/VMware-Tanzu-Kubernetes-Grid/1.6/vmware-tanzu-kubernetes-grid-16/GUID-packages-user-managed-index.html#package-locations-and-dependencies-5). diff --git a/content/en/docs/topics/library_charts.md b/content/en/docs/topics/library_charts.md new file mode 100644 index 0000000000..dbdca8691d --- /dev/null +++ b/content/en/docs/topics/library_charts.md @@ -0,0 +1,409 @@ +--- +title: "Library Charts" +description: "Explains library charts and examples of usage" +aliases: ["docs/library_charts/"] +weight: 4 +--- + +A library chart is a type of [Helm chart]({{< ref "/docs/topics/charts.md" >}}) +that defines chart primitives or definitions which can be shared by Helm +templates in other charts. This allows users to share snippets of code that can +be re-used across charts, avoiding repetition and keeping charts +[DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself). + +The library chart was introduced in Helm 3 to formally recognize common or +helper charts that have been used by chart maintainers since Helm 2. By +including it as a chart type, it provides: +- A means to explicitly distinguish between common and application charts +- Logic to prevent installation of a common chart +- No rendering of templates in a common chart which may contain release + artifacts +- Allow for dependent charts to use the importer's context + +A chart maintainer can define a common chart as a library chart and now be +confident that Helm will handle the chart in a standard consistent fashion. It +also means that definitions in an application chart can be shared by changing +the chart type. + +## Create a Simple Library Chart + +As mentioned previously, a library chart is a type of [Helm chart]({{< ref +"/docs/topics/charts.md" >}}). This means that you can start off by creating a +scaffold chart: + +```console +$ helm create mylibchart +Creating mylibchart +``` + +You will first remove all the files in `templates` directory as we will create +our own templates definitions in this example. + +```console +$ rm -rf mylibchart/templates/* +``` + +The values file will not be required either. + +```console +$ rm -f mylibchart/values.yaml +``` + +Before we jump into creating common code, lets do a quick review of some +relevant Helm concepts. A [named template]({{< ref +"/docs/chart_template_guide/named_templates.md" >}}) (sometimes called a partial +or a subtemplate) is simply a template defined inside of a file, and given a +name. In the `templates/` directory, any file that begins with an underscore(_) +is not expected to output a Kubernetes manifest file. So by convention, helper +templates and partials are placed in a `_*.tpl` or `_*.yaml` files. + +In this example, we will code a common ConfigMap which creates an empty +ConfigMap resource. We will define the common ConfigMap in file +`mylibchart/templates/_configmap.yaml` as follows: + +```yaml +{{- define "mylibchart.configmap.tpl" -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name | printf "%s-%s" .Chart.Name }} +data: {} +{{- end -}} +{{- define "mylibchart.configmap" -}} +{{- include "mylibchart.util.merge" (append . "mylibchart.configmap.tpl") -}} +{{- end -}} +``` + +The ConfigMap construct is defined in named template `mylibchart.configmap.tpl`. +It is a simple ConfigMap with an empty resource, `data`. Within this file there +is another named template called `mylibchart.configmap`. This named template +includes another named template `mylibchart.util.merge` which will take 2 named +templates as arguments, the template calling `mylibchart.configmap` and +`mylibchart.configmap.tpl`. + +The helper function `mylibchart.util.merge` is a named template in +`mylibchart/templates/_util.yaml`. It is a handy util from [The Common Helm +Helper Chart](#the-common-helm-helper-chart) because it merges the 2 templates +and overrides any common parts in both: + +```yaml +{{- /* +mylibchart.util.merge will merge two YAML templates and output the result. +This takes an array of three values: +- the top context +- the template name of the overrides (destination) +- the template name of the base (source) +*/}} +{{- define "mylibchart.util.merge" -}} +{{- $top := first . -}} +{{- $overrides := fromYaml (include (index . 1) $top) | default (dict ) -}} +{{- $tpl := fromYaml (include (index . 2) $top) | default (dict ) -}} +{{- toYaml (merge $overrides $tpl) -}} +{{- end -}} +``` + +This is important when a chart wants to use common code that it needs to +customize with its configuration. + +Finally, lets change the chart type to `library`. This requires editing +`mylibchart/Chart.yaml` as follows: + +```yaml +apiVersion: v2 +name: mylibchart +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +# type: application +type: library + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application and it is recommended to use it with quotes. +appVersion: "1.16.0" +``` + +The library chart is now ready to be shared and its ConfigMap definition to be +re-used. + +Before moving on, it is worth checking if Helm recognizes the chart as a library +chart: + +```console +$ helm install mylibchart mylibchart/ +Error: library charts are not installable +``` + +## Use the Simple Library Chart + +It is time to use the library chart. This means creating a scaffold chart again: + +```console +$ helm create mychart +Creating mychart +``` + +Lets clean out the template files again as we want to create a ConfigMap only: + +```console +$ rm -rf mychart/templates/* +``` + +When we want to create a simple ConfigMap in a Helm template, it could look +similar to the following: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name | printf "%s-%s" .Chart.Name }} +data: + myvalue: "Hello World" +``` + +We are however going to re-use the common code already created in `mylibchart`. +The ConfigMap can be created in the file `mychart/templates/configmap.yaml` as +follows: + +```yaml +{{- include "mylibchart.configmap" (list . "mychart.configmap") -}} +{{- define "mychart.configmap" -}} +data: + myvalue: "Hello World" +{{- end -}} +``` + +You can see that it simplifies the work we have to do by inheriting the common +ConfigMap definition which adds standard properties for ConfigMap. In our +template we add the configuration, in this case the data key `myvalue` and its +value. The configuration override the empty resource of the common ConfigMap. +This is feasible because of the helper function `mylibchart.util.merge` we +mentioned in the previous section. + +To be able to use the common code, we need to add `mylibchart` as a dependency. +Add the following to the end of the file `mychart/Chart.yaml`: + +```yaml +# My common code in my library chart +dependencies: +- name: mylibchart + version: 0.1.0 + repository: file://../mylibchart +``` + +This includes the library chart as a dynamic dependency from the filesystem +which is at the same parent path as our application chart. As we are including +the library chart as a dynamic dependency, we need to run `helm dependency +update`. It will copy the library chart into your `charts/` directory. + +```console +$ helm dependency update mychart/ +Hang tight while we grab the latest from your chart repositories... +...Successfully got an update from the "stable" chart repository +Update Complete. ⎈Happy Helming!⎈ +Saving 1 charts +Deleting outdated charts +``` + +We are now ready to deploy our chart. Before installing, it is worth checking +the rendered template first. + +```console +$ helm install mydemo mychart/ --debug --dry-run +install.go:159: [debug] Original chart version: "" +install.go:176: [debug] CHART PATH: /root/test/helm-charts/mychart + +NAME: mydemo +LAST DEPLOYED: Tue Mar 3 17:48:47 2020 +NAMESPACE: default +STATUS: pending-install +REVISION: 1 +TEST SUITE: None +USER-SUPPLIED VALUES: +{} + +COMPUTED VALUES: +affinity: {} +fullnameOverride: "" +image: + pullPolicy: IfNotPresent + repository: nginx +imagePullSecrets: [] +ingress: + annotations: {} + enabled: false + hosts: + - host: chart-example.local + paths: [] + tls: [] +mylibchart: + global: {} +nameOverride: "" +nodeSelector: {} +podSecurityContext: {} +replicaCount: 1 +resources: {} +securityContext: {} +service: + port: 80 + type: ClusterIP +serviceAccount: + annotations: {} + create: true + name: null +tolerations: [] + +HOOKS: +MANIFEST: +--- +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +data: + myvalue: Hello World +kind: ConfigMap +metadata: + labels: + app: mychart + chart: mychart-0.1.0 + release: mydemo + name: mychart-mydemo +``` + +This looks like the ConfigMap we want with data override of `myvalue: Hello +World`. Lets install it: + +```console +$ helm install mydemo mychart/ +NAME: mydemo +LAST DEPLOYED: Tue Mar 3 17:52:40 2020 +NAMESPACE: default +STATUS: deployed +REVISION: 1 +TEST SUITE: None +``` + +We can retrieve the release and see that the actual template was loaded. + +```console +$ helm get manifest mydemo +--- +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +data: + myvalue: Hello World +kind: ConfigMap +metadata: + labels: + app: mychart + chart: mychart-0.1.0 + release: mydemo + name: mychart-mydemo + ``` + +## Library Chart Benefits +Because of their inability to act as standalone charts, library charts can leverage the following functionality: +- The `.Files` object references the file paths on the parent chart, rather than the path local to the library chart +- The `.Values` object is the same as the parent chart, in contrast to application [subcharts]({{< ref +"/docs/chart_template_guide/subcharts_and_globals.md" >}}) which receive the section of values configured under their header in the parent. + + +## The Common Helm Helper Chart + +```markdown +Note: The Common Helm Helper Chart repo on Github is no longer actively maintained, and the repo has been deprecated and archived. +``` + +This [chart](https://github.com/helm/charts/tree/master/incubator/common) was +the original pattern for common charts. It provides utilities that reflect best +practices of Kubernetes chart development. Best of all it can be used off the +bat by you when developing your charts to give you handy shared code. + +Here is a quick way to use it. For more details, have a look at the +[README](https://github.com/helm/charts/blob/master/incubator/common/README.md). + +Create a scaffold chart again: + +```console +$ helm create demo +Creating demo +``` + +Lets use the common code from the helper chart. First, edit deployment +`demo/templates/deployment.yaml` as follows: + +```yaml +{{- template "common.deployment" (list . "demo.deployment") -}} +{{- define "demo.deployment" -}} +## Define overrides for your Deployment resource here, e.g. +apiVersion: apps/v1 +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + {{- include "demo.selectorLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "demo.selectorLabels" . | nindent 8 }} + +{{- end -}} +``` + +And now the service file, `demo/templates/service.yaml` as follows: + +```yaml +{{- template "common.service" (list . "demo.service") -}} +{{- define "demo.service" -}} +## Define overrides for your Service resource here, e.g. +# metadata: +# labels: +# custom: label +# spec: +# ports: +# - port: 8080 +{{- end -}} +``` + +These templates show how inheriting the common code from the helper chart +simplifies your coding down to your configuration or customization of the +resources. + +To be able to use the common code, we need to add `common` as a dependency. Add +the following to the end of the file `demo/Chart.yaml`: + +```yaml +dependencies: +- name: common + version: "^0.0.5" + repository: "https://charts.helm.sh/incubator/" +``` + +Note: You will need to add the `incubator` repo to the Helm repository list +(`helm repo add`). + +As we are including the chart as a dynamic dependency, we need to run `helm +dependency update`. It will copy the helper chart into your `charts/` directory. + +As helper chart is using some Helm 2 constructs, you will need to add the +following to `demo/values.yaml` to enable the `nginx` image to be loaded as this +was updated in Helm 3 scaffold chart: + +```yaml +image: + tag: 1.16.0 +``` + +You can test that the chart templates are correct prior to deploying using the `helm lint` and `helm template` commands. + +If it's good to go, deploy away using `helm install`! + diff --git a/content/en/docs/topics/permissions_sql_storage_backend.md b/content/en/docs/topics/permissions_sql_storage_backend.md new file mode 100644 index 0000000000..e90060377e --- /dev/null +++ b/content/en/docs/topics/permissions_sql_storage_backend.md @@ -0,0 +1,64 @@ +--- +title: "Permissions management for SQL storage backend" +description: "Get to know how to setup permissions when using SQL storage backend." +aliases: ["/docs/permissions_sql_storage_backend/"] +--- + +This document aims to provide guidance to users for setting up and managing +permissions when using the SQL storage backend. + +## Introduction + +To handle permissions, Helm leverages the RBAC feature of Kubernetes. When using +the SQL storage backend, Kubernetes' roles can't be used to determine whether or +not an user can access a given resource. This document shows how to create and +manage these permissions. + +## Initialization + +The first time the Helm CLI will make connect to your database, the client will +make sure that it was previously initialized. If it is not, it will take care of +the necessary setup automatically. This initialization requires admin privileges +on the public schema, or at least to be able to: + +* create a table +* grant privileges on the public schema + +After the migration was run against your database, all the other roles can use +the client. + +## Grant privileges to a non admin user in PostgreSQL + +To manage permissions, the SQL backend driver leverages the +[RLS](https://www.postgresql.org/docs/9.5/ddl-rowsecurity.html)(Row Security +Level) feature of PostgreSQL. RLS allows all users to be able to read/write +from/to the same table, without being able to manipulate the same rows if they +are not explicitly allowed to. By default, any role that has not been +explicitly granted with the right privileges will always return an empty list +when running `helm list` and will not be able to retrieve or modify any resource +in the cluster. + +Let's see how to grant a given role access to specific namespaces: + +```sql +CREATE POLICY ON releases_v1 FOR ALL TO USING (namespace = 'default'); +``` + +This command will grant the permissions to read and write all resources that +meet the `namespace = 'default'` condition to the role `role`. After creating +this policy, the user being connected to the database on the behalf of the role +`role` will therefore be able to see all the releases living in the `default` +namespace when running `helm list`, and to modify and delete them. + +Privileges can be managed granularly with RLS, and one might be interested in +restraining access given the different columns of the table: +* key +* type +* body +* name +* namespace +* version +* status +* owner +* createdAt +* modifiedAt diff --git a/content/en/docs/topics/plugins.md b/content/en/docs/topics/plugins.md new file mode 100644 index 0000000000..cc97c8e828 --- /dev/null +++ b/content/en/docs/topics/plugins.md @@ -0,0 +1,411 @@ +--- +title: "The Helm Plugins Guide" +description: "Introduces how to use and create plugins to extend Helm's functionality." +aliases: ["/docs/plugins/"] +weight: 12 +--- + +A Helm plugin is a tool that can be accessed through the `helm` CLI, but which +is not part of the built-in Helm codebase. + +Existing plugins can be found on [related]({{< ref "related.md#helm-plugins" +>}}) section or by searching +[GitHub](https://github.com/search?q=topic%3Ahelm-plugin&type=Repositories). + +This guide explains how to use and create plugins. + +## An Overview + +Helm plugins are add-on tools that integrate seamlessly with Helm. They provide +a way to extend the core feature set of Helm, but without requiring every new +feature to be written in Go and added to the core tool. + +Helm plugins have the following features: + +- They can be added and removed from a Helm installation without impacting the + core Helm tool. +- They can be written in any programming language. +- They integrate with Helm, and will show up in `helm help` and other places. + +Helm plugins live in `$HELM_PLUGINS`. You can find the current value of this, +including the default value when not set in the environment, using the +`helm env` command. + +The Helm plugin model is partially modeled on Git's plugin model. To that end, +you may sometimes hear `helm` referred to as the _porcelain_ layer, with plugins +being the _plumbing_. This is a shorthand way of suggesting that Helm provides +the user experience and top level processing logic, while the plugins do the +"detail work" of performing a desired action. + +## Installing a Plugin + +Plugins are installed using the `$ helm plugin install ` command. You +can pass in a path to a plugin on your local file system or a url of a remote +VCS repo. The `helm plugin install` command clones or copies the plugin at the +path/url given into `$HELM_PLUGINS` + +```console +$ helm plugin install https://github.com/adamreese/helm-env +``` + +If you have a plugin tar distribution, simply untar the plugin into the +`$HELM_PLUGINS` directory. You can also install tarball plugins +directly from url by issuing `helm plugin install +https://domain/path/to/plugin.tar.gz` + +## Building Plugins + +In many ways, a plugin is similar to a chart. Each plugin has a top-level +directory, and then a `plugin.yaml` file. + +``` +$HELM_PLUGINS/ + |- last/ + | + |- plugin.yaml + |- last.sh + +``` + +In the example above, the `last` plugin is contained inside of a directory +named `last`. It has two files: `plugin.yaml` (required) and an executable +script, `last.sh` (optional). + +The core of a plugin is a simple YAML file named `plugin.yaml`. Here is a plugin +YAML for a plugin that helps get the last release name: + +```yaml +name: "last" +version: "0.1.0" +usage: "get the last release name" +description: "get the last release name" +ignoreFlags: false +command: "$HELM_BIN --host $TILLER_HOST list --short --max 1 --date -r" +platformCommand: + - os: linux + arch: i386 + command: "$HELM_BIN list --short --max 1 --date -r" + - os: linux + arch: amd64 + command: "$HELM_BIN list --short --max 1 --date -r" + - os: windows + arch: amd64 + command: "$HELM_BIN list --short --max 1 --date -r" +``` + +The `name` is the name of the plugin. When Helm executes this plugin, this is +the name it will use (e.g. `helm NAME` will invoke this plugin). + +_`name` should match the directory name._ In our example above, that means the +plugin with `name: last` should be contained in a directory named `last`. + +Restrictions on `name`: + +- `name` cannot duplicate one of the existing `helm` top-level commands. +- `name` must be restricted to the characters ASCII a-z, A-Z, 0-9, `_` and `-`. + +`version` is the SemVer 2 version of the plugin. `usage` and `description` are +both used to generate the help text of a command. + +The `ignoreFlags` switch tells Helm to _not_ pass flags to the plugin. So if a +plugin is called with `helm myplugin --foo` and `ignoreFlags: true`, then +`--foo` is silently discarded. + +Finally, and most importantly, `platformCommand` or `command` is the command +that this plugin will execute when it is called. The `platformCommand` section +defines the OS/Architecture specific variations of a command. The following +rules will apply in deciding which command to use: + +- If `platformCommand` is present, it will be searched first. +- If both `os` and `arch` match the current platform, search will stop and the + command will be used. +- If `os` matches and there is no more specific `arch` match, the command will + be used. +- If no `platformCommand` match is found, the default `command` will be used. +- If no matches are found in `platformCommand` and no `command` is present, Helm + will exit with an error. + +Environment variables are interpolated before the plugin is executed. The +pattern above illustrates the preferred way to indicate where the plugin program +lives. + +There are some strategies for working with plugin commands: + +- If a plugin includes an executable, the executable for a `platformCommand:` or + a `command:` should be packaged in the plugin directory. +- The `platformCommand:` or `command:` line will have any environment variables + expanded before execution. `$HELM_PLUGIN_DIR` will point to the plugin + directory. +- The command itself is not executed in a shell. So you can't oneline a shell + script. +- Helm injects lots of configuration into environment variables. Take a look at + the environment to see what information is available. +- Helm makes no assumptions about the language of the plugin. You can write it + in whatever you prefer. +- Commands are responsible for implementing specific help text for `-h` and + `--help`. Helm will use `usage` and `description` for `helm help` and `helm + help myplugin`, but will not handle `helm myplugin --help`. + +## Downloader Plugins +By default, Helm is able to pull Charts using HTTP/S. As of Helm 2.4.0, plugins +can have a special capability to download Charts from arbitrary sources. + +Plugins shall declare this special capability in the `plugin.yaml` file (top +level): + +```yaml +downloaders: +- command: "bin/mydownloader" + protocols: + - "myprotocol" + - "myprotocols" +``` + +If such plugin is installed, Helm can interact with the repository using the +specified protocol scheme by invoking the `command`. The special repository +shall be added similarly to the regular ones: `helm repo add favorite +myprotocol://example.com/` The rules for the special repos are the same to the +regular ones: Helm must be able to download the `index.yaml` file in order to +discover and cache the list of available Charts. + +The defined command will be invoked with the following scheme: `command certFile +keyFile caFile full-URL`. The SSL credentials are coming from the repo +definition, stored in `$HELM_REPOSITORY_CONFIG` +(i.e., `$HELM_CONFIG_HOME/repositories.yaml`). A Downloader plugin +is expected to dump the raw content to stdout and report errors on stderr. + +The downloader command also supports sub-commands or arguments, allowing you to +specify for example `bin/mydownloader subcommand -d` in the `plugin.yaml`. This +is useful if you want to use the same executable for the main plugin command and +the downloader command, but with a different sub-command for each. + +## Environment Variables + +When Helm executes a plugin, it passes the outer environment to the plugin, and +also injects some additional environment variables. + +Variables like `KUBECONFIG` are set for the plugin if they are set in the outer +environment. + +The following variables are guaranteed to be set: + +- `HELM_PLUGINS`: The path to the plugins directory. +- `HELM_PLUGIN_NAME`: The name of the plugin, as invoked by `helm`. So `helm + myplug` will have the short name `myplug`. +- `HELM_PLUGIN_DIR`: The directory that contains the plugin. +- `HELM_BIN`: The path to the `helm` command (as executed by the user). +- `HELM_DEBUG`: Indicates if the debug flag was set by helm. +- `HELM_REGISTRY_CONFIG`: The location for the registry configuration (if + using). Note that the use of Helm with registries is an experimental feature. +- `HELM_REPOSITORY_CACHE`: The path to the repository cache files. +- `HELM_REPOSITORY_CONFIG`: The path to the repository configuration file. +- `HELM_NAMESPACE`: The namespace given to the `helm` command (generally using + the `-n` flag). +- `HELM_KUBECONTEXT`: The name of the Kubernetes config context given to the + `helm` command. + +Additionally, if a Kubernetes configuration file was explicitly specified, it +will be set as the `KUBECONFIG` variable + +## A Note on Flag Parsing + +When executing a plugin, Helm will parse global flags for its own use. None of +these flags are passed on to the plugin. + +- `--debug`: If this is specified, `$HELM_DEBUG` is set to `1` +- `--registry-config`: This is converted to `$HELM_REGISTRY_CONFIG` +- `--repository-cache`: This is converted to `$HELM_REPOSITORY_CACHE` +- `--repository-config`: This is converted to `$HELM_REPOSITORY_CONFIG` +- `--namespace` and `-n`: This is converted to `$HELM_NAMESPACE` +- `--kube-context`: This is converted to `$HELM_KUBECONTEXT` +- `--kubeconfig`: This is converted to `$KUBECONFIG` + +Plugins _should_ display help text and then exit for `-h` and `--help`. In all +other cases, plugins may use flags as appropriate. + +## Providing shell auto-completion + +As of Helm 3.2, a plugin can optionally provide support for shell +auto-completion as part of Helm's existing auto-completion mechanism. + +### Static auto-completion + +If a plugin provides its own flags and/or sub-commands, it can inform Helm of +them by having a `completion.yaml` file located in the plugin's root directory. +The `completion.yaml` file has the form: + +```yaml +name: +flags: +- +- +validArgs: +- +- +commands: + name: + flags: + - + - + validArgs: + - + - + commands: + +``` + +Notes: +1. All sections are optional but should be provided if applicable. +1. Flags should not include the `-` or `--` prefix. +1. Both short and long flags can and should be specified. A short flag need not + be associated with its corresponding long form, but both forms should be + listed. +1. Flags need not be ordered in any way, but need to be listed at the correct + point in the sub-command hierarchy of the file. +1. Helm's existing global flags are already handled by Helm's auto-completion + mechanism, therefore plugins need not specify the following flags `--debug`, + `--namespace` or `-n`, `--kube-context`, and `--kubeconfig`, or any other + global flag. +1. The `validArgs` list provides a static list of possible completions for the + first parameter following a sub-command. It is not always possible to + provide such a list in advance (see the [Dynamic + Completion](#dynamic-completion) section below), in which case the + `validArgs` section can be omitted. + +The `completion.yaml` file is entirely optional. If it is not provided, Helm +will simply not provide shell auto-completion for the plugin (unless [Dynamic +Completion](#dynamic-completion) is supported by the plugin). Also, adding a +`completion.yaml` file is backwards-compatible and will not impact the behavior +of the plugin when using older helm versions. + +As an example, for the [`fullstatus +plugin`](https://github.com/marckhouzam/helm-fullstatus) which has no +sub-commands but accepts the same flags as the `helm status` command, the +`completion.yaml` file is: + +```yaml +name: fullstatus +flags: +- o +- output +- revision +``` + +A more intricate example for the [`2to3 +plugin`](https://github.com/helm/helm-2to3), has a `completion.yaml` file of: + +```yaml +name: 2to3 +commands: +- name: cleanup + flags: + - config-cleanup + - dry-run + - l + - label + - release-cleanup + - s + - release-storage + - tiller-cleanup + - t + - tiller-ns + - tiller-out-cluster +- name: convert + flags: + - delete-v2-releases + - dry-run + - l + - label + - s + - release-storage + - release-versions-max + - t + - tiller-ns + - tiller-out-cluster +- name: move + commands: + - name: config + flags: + - dry-run +``` + +### Dynamic completion + +Also starting with Helm 3.2, plugins can provide their own dynamic shell +auto-completion. Dynamic shell auto-completion is the completion of parameter +values or flag values that cannot be defined in advance. For example, +completion of the names of helm releases currently available on the cluster. + +For the plugin to support dynamic auto-completion, it must provide an +**executable** file called `plugin.complete` in its root directory. When the +Helm completion script requires dynamic completions for the plugin, it will +execute the `plugin.complete` file, passing it the command-line that needs to be +completed. The `plugin.complete` executable will need to have the logic to +determine what the proper completion choices are and output them to standard +output to be consumed by the Helm completion script. + +The `plugin.complete` file is entirely optional. If it is not provided, Helm +will simply not provide dynamic auto-completion for the plugin. Also, adding a +`plugin.complete` file is backwards-compatible and will not impact the behavior +of the plugin when using older helm versions. + +The output of the `plugin.complete` script should be a new-line separated list +such as: + +``` +rel1 +rel2 +rel3 +``` + +When `plugin.complete` is called, the plugin environment is set just like when +the plugin's main script is called. Therefore, the variables `$HELM_NAMESPACE`, +`$HELM_KUBECONTEXT`, and all other plugin variables will already be set, and +their corresponding global flags will be removed. + +The `plugin.complete` file can be in any executable form; it can be a shell +script, a Go program, or any other type of program that Helm can execute. The +`plugin.complete` file ***must*** have executable permissions for the user. The +`plugin.complete` file ***must*** exit with a success code (value 0). + +In some cases, dynamic completion will require to obtain information from the +Kubernetes cluster. For example, the `helm fullstatus` plugin requires a +release name as input. In the `fullstatus` plugin, for its `plugin.complete` +script to provide completion for current release names, it can simply run `helm +list -q` and output the result. + +If it is desired to use the same executable for plugin execution and for plugin +completion, the `plugin.complete` script can be made to call the main plugin +executable with some special parameter or flag; when the main plugin executable +detects the special parameter or flag, it will know to run the completion. In +our example, `plugin.complete` could be implemented like this: + +```sh +#!/usr/bin/env sh + +# "$@" is the entire command-line that requires completion. +# It is important to double-quote the "$@" variable to preserve a possibly empty last parameter. +$HELM_PLUGIN_DIR/status.sh --complete "$@" +``` + +The `fullstatus` plugin's real script (`status.sh`) must then look for the +`--complete` flag and if found, printout the proper completions. + +### Tips and tricks + +1. The shell will automatically filter out completion choices that don't match + user input. A plugin can therefore return all relevant completions without + removing the ones that don't match the user input. For example, if the + command-line is `helm fullstatus ngin`, the `plugin.complete` script can + print *all* release names (of the `default` namespace), not just the ones + starting with `ngin`; the shell will only retain the ones starting with + `ngin`. +1. To simplify dynamic completion support, especially if you have a complex + plugin, you can have your `plugin.complete` script call your main plugin + script and request completion choices. See the [Dynamic + Completion](#dynamic-completion) section above for an example. +1. To debug dynamic completion and the `plugin.complete` file, one can run the + following to see the completion results : + - `helm __complete `. For example: + - `helm __complete fullstatus --output js`, + - `helm __complete fullstatus -o json ""` diff --git a/content/en/docs/topics/provenance.md b/content/en/docs/topics/provenance.md new file mode 100644 index 0000000000..adf542da16 --- /dev/null +++ b/content/en/docs/topics/provenance.md @@ -0,0 +1,291 @@ +--- +title: "Helm Provenance and Integrity" +description: "Describes how to verify the integrity and origin of a Chart." +aliases: ["/docs/provenance/"] +weight: 5 +--- + +Helm has provenance tools which help chart users verify the integrity and origin +of a package. Using industry-standard tools based on PKI, GnuPG, and +well-respected package managers, Helm can generate and verify signature files. + +## Overview + +Integrity is established by comparing a chart to a provenance record. Provenance +records are stored in _provenance files_, which are stored alongside a packaged +chart. For example, if a chart is named `myapp-1.2.3.tgz`, its provenance file +will be `myapp-1.2.3.tgz.prov`. + +Provenance files are generated at packaging time (`helm package --sign ...`), +and can be checked by multiple commands, notably `helm install --verify`. + +## The Workflow + +This section describes a potential workflow for using provenance data +effectively. + +Prerequisites: + +- A valid PGP keypair in a binary (not ASCII-armored) format +- The `helm` command line tool +- GnuPG command line tools (optional) +- Keybase command line tools (optional) + +**NOTE:** If your PGP private key has a passphrase, you will be prompted to +enter that passphrase for any commands that support the `--sign` option. + +Creating a new chart is the same as before: + +```console +$ helm create mychart +Creating mychart +``` + +Once ready to package, add the `--sign` flag to `helm package`. Also, specify +the name under which the signing key is known and the keyring containing the +corresponding private key: + +```console +$ helm package --sign --key 'John Smith' --keyring path/to/keyring.secret mychart +``` + +**Note:** The value of the `--key` argument must be a substring of the desired +key's `uid` (in the output of `gpg --list-keys`), for example the name or email. +**The fingerprint _cannot_ be used.** + +**TIP:** for GnuPG users, your secret keyring is in `~/.gnupg/secring.gpg`. You +can use `gpg --list-secret-keys` to list the keys you have. + +**Warning:** the GnuPG v2 store your secret keyring using a new format `kbx` on +the default location `~/.gnupg/pubring.kbx`. Please use the following command +to convert your keyring to the legacy gpg format: + +```console +$ gpg --export >~/.gnupg/pubring.gpg +$ gpg --export-secret-keys >~/.gnupg/secring.gpg +``` + +At this point, you should see both `mychart-0.1.0.tgz` and +`mychart-0.1.0.tgz.prov`. Both files should eventually be uploaded to your +desired chart repository. + +You can verify a chart using `helm verify`: + +```console +$ helm verify mychart-0.1.0.tgz +``` + +A failed verification looks like this: + +```console +$ helm verify topchart-0.1.0.tgz +Error: sha256 sum does not match for topchart-0.1.0.tgz: "sha256:1939fbf7c1023d2f6b865d137bbb600e0c42061c3235528b1e8c82f4450c12a7" != "sha256:5a391a90de56778dd3274e47d789a2c84e0e106e1a37ef8cfa51fd60ac9e623a" +``` + +To verify during an install, use the `--verify` flag. + +```console +$ helm install --generate-name --verify mychart-0.1.0.tgz +``` + +If the keyring containing the public key associated with the signed chart is not +in the default location, you may need to point to the keyring with `--keyring +PATH` as in the `helm package` example. + +If verification fails, the install will be aborted before the chart is even +rendered. + +### Using Keybase.io credentials + +The [Keybase.io](https://keybase.io) service makes it easy to establish a chain +of trust for a cryptographic identity. Keybase credentials can be used to sign +charts. + +Prerequisites: + +- A configured Keybase.io account +- GnuPG installed locally +- The `keybase` CLI installed locally + +#### Signing packages + +The first step is to import your keybase keys into your local GnuPG keyring: + +```console +$ keybase pgp export -s | gpg --import +``` + +This will convert your Keybase key into the OpenPGP format, and then import it +locally into your `~/.gnupg/secring.gpg` file. + +You can double check by running `gpg --list-secret-keys`. + +```console +$ gpg --list-secret-keys +/Users/mattbutcher/.gnupg/secring.gpg +------------------------------------- +sec 2048R/1FC18762 2016-07-25 +uid technosophos (keybase.io/technosophos) +ssb 2048R/D125E546 2016-07-25 +``` + +Note that your secret key will have an identifier string: + +``` +technosophos (keybase.io/technosophos) +``` + +That is the full name of your key. + +Next, you can package and sign a chart with `helm package`. Make sure you use at +least part of that name string in `--key`. + +```console +$ helm package --sign --key technosophos --keyring ~/.gnupg/secring.gpg mychart +``` + +As a result, the `package` command should produce both a `.tgz` file and a +`.tgz.prov` file. + +#### Verifying packages + +You can also use a similar technique to verify a chart signed by someone else's +Keybase key. Say you want to verify a package signed by +`keybase.io/technosophos`. To do this, use the `keybase` tool: + +```console +$ keybase follow technosophos +$ keybase pgp pull +``` + +The first command above tracks the user `technosophos`. Next `keybase pgp pull` +downloads the OpenPGP keys of all of the accounts you follow, placing them in +your GnuPG keyring (`~/.gnupg/pubring.gpg`). + +At this point, you can now use `helm verify` or any of the commands with a +`--verify` flag: + +```console +$ helm verify somechart-1.2.3.tgz +``` + +### Reasons a chart may not verify + +These are common reasons for failure. + +- The `.prov` file is missing or corrupt. This indicates that something is + misconfigured or that the original maintainer did not create a provenance + file. +- The key used to sign the file is not in your keyring. This indicate that the + entity who signed the chart is not someone you've already signaled that you + trust. +- The verification of the `.prov` file failed. This indicates that something is + wrong with either the chart or the provenance data. +- The file hashes in the provenance file do not match the hash of the archive + file. This indicates that the archive has been tampered with. + +If a verification fails, there is reason to distrust the package. + +## The Provenance File + +The provenance file contains a chart’s YAML file plus several pieces of +verification information. Provenance files are designed to be automatically +generated. + +The following pieces of provenance data are added: + +* The chart file (`Chart.yaml`) is included to give both humans and tools an + easy view into the contents of the chart. +* The signature (SHA256, just like Docker) of the chart package (the `.tgz` + file) is included, and may be used to verify the integrity of the chart + package. +* The entire body is signed using the algorithm used by OpenPGP (see + [Keybase.io](https://keybase.io) for an emerging way of making crypto + signing and verification easy). + +The combination of this gives users the following assurances: + +* The package itself has not been tampered with (checksum package `.tgz`). +* The entity who released this package is known (via the GnuPG/PGP signature). + +The format of the file looks something like this: + +``` +Hash: SHA512 + +apiVersion: v2 +appVersion: "1.16.0" +description: Sample chart +name: mychart +type: application +version: 0.1.0 + +... +files: + mychart-0.1.0.tgz: sha256:d31d2f08b885ec696c37c7f7ef106709aaf5e8575b6d3dc5d52112ed29a9cb92 +-----BEGIN PGP SIGNATURE----- + +wsBcBAEBCgAQBQJdy0ReCRCEO7+YH8GHYgAAfhUIADx3pHHLLINv0MFkiEYpX/Kd +nvHFBNps7hXqSocsg0a9Fi1LRAc3OpVh3knjPfHNGOy8+xOdhbqpdnB+5ty8YopI +mYMWp6cP/Mwpkt7/gP1ecWFMevicbaFH5AmJCBihBaKJE4R1IX49/wTIaLKiWkv2 +cR64bmZruQPSW83UTNULtdD7kuTZXeAdTMjAK0NECsCz9/eK5AFggP4CDf7r2zNi +hZsNrzloIlBZlGGns6mUOTO42J/+JojnOLIhI3Psd0HBD2bTlsm/rSfty4yZUs7D +qtgooNdohoyGSzR5oapd7fEvauRQswJxOA0m0V+u9/eyLR0+JcYB8Udi1prnWf8= +=aHfz +-----END PGP SIGNATURE----- +``` + +Note that the YAML section contains two documents (separated by `...\n`). The +first file is the content of `Chart.yaml`. The second is the checksums, a map of +filenames to SHA-256 digests of that file's content at packaging time. + +The signature block is a standard PGP signature, which provides [tamper +resistance](https://www.rossde.com/PGP/pgp_signatures.html). + +## Chart Repositories + +Chart repositories serve as a centralized collection of Helm charts. + +Chart repositories must make it possible to serve provenance files over HTTP via +a specific request, and must make them available at the same URI path as the +chart. + +For example, if the base URL for a package is +`https://example.com/charts/mychart-1.2.3.tgz`, the provenance file, if it +exists, MUST be accessible at +`https://example.com/charts/mychart-1.2.3.tgz.prov`. + +From the end user's perspective, `helm install --verify myrepo/mychart-1.2.3` +should result in the download of both the chart and the provenance file with no +additional user configuration or action. + +## Establishing Authority and Authenticity + +When dealing with chain-of-trust systems, it is important to be able to +establish the authority of a signer. Or, to put this plainly, the system above +hinges on the fact that you trust the person who signed the chart. That, in +turn, means you need to trust the public key of the signer. + +One of the design decisions with Helm has been that the Helm project would not +insert itself into the chain of trust as a necessary party. We don't want to be +"the certificate authority" for all chart signers. Instead, we strongly favor a +decentralized model, which is part of the reason we chose OpenPGP as our +foundational technology. So when it comes to establishing authority, we have +left this step more-or-less undefined in Helm 2 (a decision carried forward in +Helm 3). + +However, we have some pointers and recommendations for those interested in using +the provenance system: + +- The [Keybase](https://keybase.io) platform provides a public centralized + repository for trust information. + - You can use Keybase to store your keys or to get the public keys of others. + - Keybase also has fabulous documentation available + - While we haven't tested it, Keybase's "secure website" feature could be used + to serve Helm charts. + - The basic idea is that an official "chart reviewer" signs charts with her or + his key, and the resulting provenance file is then uploaded to the chart + repository. + - There has been some work on the idea that a list of valid signing keys may + be included in the `index.yaml` file of a repository. + diff --git a/content/en/docs/topics/rbac.md b/content/en/docs/topics/rbac.md new file mode 100644 index 0000000000..494388b28a --- /dev/null +++ b/content/en/docs/topics/rbac.md @@ -0,0 +1,209 @@ +--- +title: "Role-based Access Control" +description: "Explains how Helm interacts with Kubernetes' Role-Based Access Control." +aliases: ["/docs/rbac/"] +weight: 11 +--- + +In Kubernetes, granting roles to a user or an application-specific service +account is a best practice to ensure that your application is operating in the +scope that you have specified. Read more about service account permissions [in +the official Kubernetes +docs](https://kubernetes.io/docs/admin/authorization/rbac/#service-account-permissions). + +From Kubernetes 1.6 onwards, Role-based Access Control is enabled by default. +RBAC allows you to specify which types of actions are permitted depending on the +user and their role in your organization. + +With RBAC, you can + +- grant privileged operations (creating cluster-wide resources, like new roles) + to administrators +- limit a user's ability to create resources (pods, persistent volumes, + deployments) to specific namespaces, or in cluster-wide scopes (resource + quotas, roles, custom resource definitions) +- limit a user's ability to view resources either in specific namespaces or at a + cluster-wide scope. + +This guide is for administrators who want to restrict the scope of a user's +interaction with the Kubernetes API. + +## Managing user accounts + +All Kubernetes clusters have two categories of users: service accounts managed +by Kubernetes, and normal users. + +Normal users are assumed to be managed by an outside, independent service. An +administrator distributing private keys, a user store like Keystone or Google +Accounts, even a file with a list of usernames and passwords. In this regard, +Kubernetes does not have objects which represent normal user accounts. Normal +users cannot be added to a cluster through an API call. + +In contrast, service accounts are users managed by the Kubernetes API. They are +bound to specific namespaces, and created automatically by the API server or +manually through API calls. Service accounts are tied to a set of credentials +stored as Secrets, which are mounted into pods allowing in-cluster processes to +talk to the Kubernetes API. + +API requests are tied to either a normal user or a service account, or are +treated as anonymous requests. This means every process inside or outside the +cluster, from a human user typing `kubectl` on a workstation, to kubelets on +nodes, to members of the control plane, must authenticate when making requests +to the API server, or be treated as an anonymous user. + +## Roles, ClusterRoles, RoleBindings, and ClusterRoleBindings + +In Kubernetes, user accounts and service accounts can only view and edit +resources they have been granted access to. This access is granted through the +use of Roles and RoleBindings. Roles and RoleBindings are bound to a particular +namespace, which grant users the ability to view and/or edit resources within +that namespace the Role provides them access to. + +At a cluster scope, these are called ClusterRoles and ClusterRoleBindings. +Granting a user a ClusterRole grants them access to view and/or edit resources +across the entire cluster. It is also required to view and/or edit resources at +the cluster scope (namespaces, resource quotas, nodes). + +ClusterRoles can be bound to a particular namespace through reference in a +RoleBinding. The `admin`, `edit` and `view` default ClusterRoles are commonly +used in this manner. + +These are a few ClusterRoles available by default in Kubernetes. They are +intended to be user-facing roles. They include super-user roles +(`cluster-admin`), and roles with more granular access (`admin`, `edit`, +`view`). + +| Default ClusterRole | Default ClusterRoleBinding | Description +|---------------------|----------------------------|------------- +| `cluster-admin` | `system:masters` group | Allows super-user access to perform any action on any resource. When used in a ClusterRoleBinding, it gives full control over every resource in the cluster and in all namespaces. When used in a RoleBinding, it gives full control over every resource in the rolebinding's namespace, including the namespace itself. +| `admin` | None | Allows admin access, intended to be granted within a namespace using a RoleBinding. If used in a RoleBinding, allows read/write access to most resources in a namespace, including the ability to create roles and rolebindings within the namespace. It does not allow write access to resource quota or to the namespace itself. +| `edit` | None | Allows read/write access to most objects in a namespace. It does not allow viewing or modifying roles or rolebindings. +| `view` | None | Allows read-only access to see most objects in a namespace. It does not allow viewing roles or rolebindings. It does not allow viewing secrets, since those are escalating. + +## Restricting a user account's access using RBAC + +Now that we understand the basics of Role-based Access Control, let's discuss +how an administrator can restrict a user's scope of access. + +### Example: Grant a user read/write access to a particular namespace + +To restrict a user's access to a particular namespace, we can use either the +`edit` or the `admin` role. If your charts create or interact with Roles and +Rolebindings, you'll want to use the `admin` ClusterRole. + +Additionally, you may also create a RoleBinding with `cluster-admin` access. +Granting a user `cluster-admin` access at the namespace scope provides full +control over every resource in the namespace, including the namespace itself. + +For this example, we will create a user with the `edit` Role. First, create the +namespace: + +```console +$ kubectl create namespace foo +``` + +Now, create a RoleBinding in that namespace, granting the user the `edit` role. + +```console +$ kubectl create rolebinding sam-edit + --clusterrole edit \​ + --user sam \​ + --namespace foo +``` + +### Example: Grant a user read/write access at the cluster scope + +If a user wishes to install a chart that installs cluster-scope resources +(namespaces, roles, custom resource definitions, etc.), they will require +cluster-scope write access. + +To do that, grant the user either `admin` or `cluster-admin` access. + +Granting a user `cluster-admin` access grants them access to absolutely every +resource available in Kubernetes, including node access with `kubectl drain` and +other administrative tasks. It is highly recommended to consider providing the +user `admin` access instead, or to create a custom ClusterRole tailored to their +needs. + +```console +$ kubectl create clusterrolebinding sam-view + --clusterrole view \​ + --user sam + +$ kubectl create clusterrolebinding sam-secret-reader + --clusterrole secret-reader \​ + --user sam +``` + +### Example: Grant a user read-only access to a particular namespace + +You might've noticed that there is no ClusterRole available for viewing secrets. +The `view` ClusterRole does not grant a user read access to Secrets due to +escalation concerns. Helm stores release metadata as Secrets by default. + +In order for a user to run `helm list`, they need to be able to read these +secrets. For that, we will create a special `secret-reader` ClusterRole. + +Create the file `cluster-role-secret-reader.yaml` and write the following +content into the file: + +```yaml +apiVersion: rbac.authorization.k8s.io/v1​ +kind: ClusterRole​ +metadata:​ + name: secret-reader​ +rules:​ +- apiGroups: [""]​ + resources: ["secrets"]​ + verbs: ["get", "watch", "list"] +``` + +Then, create the ClusterRole using + +```console +$ kubectl create -f clusterrole-secret-reader.yaml​ +``` + +Once that's done, we can grant a user read access to most resources, and then +grant them read access to secrets: + +```console +$ kubectl create namespace foo + +$ kubectl create rolebinding sam-view + --clusterrole view \​ + --user sam \​ + --namespace foo + +$ kubectl create rolebinding sam-secret-reader + --clusterrole secret-reader \​ + --user sam \​ + --namespace foo +``` + +### Example: Grant a user read-only access at the cluster scope + +In certain scenarios, it may be beneficial to grant a user cluster-scope access. +For example, if a user wants to run the command `helm list --all-namespaces`, +the API requires the user has cluster-scope read access. + +To do that, grant the user both `view` and `secret-reader` access as described +above, but with a ClusterRoleBinding. + +```console +$ kubectl create clusterrolebinding sam-view + --clusterrole view \​ + --user sam + +$ kubectl create clusterrolebinding sam-secret-reader + --clusterrole secret-reader \​ + --user sam +``` + +## Additional Thoughts + +The examples shown above utilize the default ClusterRoles provided with +Kubernetes. For more fine-grained control over what resources users are granted +access to, have a look at [the Kubernetes +documentation](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) on +creating your own custom Roles and ClusterRoles. diff --git a/content/en/docs/topics/registries.md b/content/en/docs/topics/registries.md new file mode 100644 index 0000000000..af5c08dfe0 --- /dev/null +++ b/content/en/docs/topics/registries.md @@ -0,0 +1,246 @@ +--- +title: "Use OCI-based registries" +description: "Describes how to use OCI for Chart distribution." +aliases: ["/docs/registries/"] +weight: 7 +--- + +Beginning in Helm 3, you can use container registries with [OCI](https://www.opencontainers.org/) support to store and share chart packages. Beginning in Helm v3.8.0, OCI support is enabled by default. + + +## OCI support prior to v3.8.0 + +OCI support graduated from experimental to general availability with Helm v3.8.0. In prior versions of Helm, OCI support behaved differently. If you were using OCI support prior to Helm v3.8.0, its important to understand what has changed with different versions of Helm. + +### Enabling OCI support prior to v3.8.0 + +Prior to Helm v3.8.0, OCI support is *experimental* and must be enabled. + +To enable OCI experimental support for Helm versions prior to v3.8.0, set `HELM_EXPERIMENTAL_OCI` in your environment. For example: + +```console +export HELM_EXPERIMENTAL_OCI=1 +``` + +### OCI feature deprecation and behavior changes with v3.8.0 + +The release of [Helm v3.8.0](https://github.com/helm/helm/releases/tag/v3.8.0), the following features and behaviors are different from previous versions of Helm: + +- When setting a chart in the dependencies as OCI, the version can be set to a range like other dependencies. +- SemVer tags that include build information can be pushed and used. OCI registries don't support `+` as a tag character. Helm translates the `+` to `_` when stored as a tag. +- The `helm registry login` command now follows the same structure as the Docker CLI for storing credentials. The same location for registry configuration can be passed to both Helm and the Docker CLI. + +### OCI feature deprecation and behavior changes with v3.7.0 + +The release of [Helm v3.7.0](https://github.com/helm/helm/releases/tag/v3.7.0) included the implementation of [HIP 6](https://github.com/helm/community/blob/main/hips/hip-0006.md) for OCI support. As a result, the following features and behaviors are different from previous versions of Helm: + +- The `helm chart` subcommand has been removed. +- The chart cache has been removed (no `helm chart list` etc.). +- OCI registry references are now always prefixed with `oci://`. +- The basename of the registry reference must *always* match the chart's name. +- The tag of the registry reference must *always* match the chart's semantic version (i.e. no `latest` tags). +- The chart layer media type was switched from `application/tar+gzip` to `application/vnd.cncf.helm.chart.content.v1.tar+gzip`. + + +## Using an OCI-based registry + +### Helm repositories in OCI-based registries + +A [Helm repository]({{< ref "chart_repository.md" >}}) is a way to house and distribute packaged Helm charts. An OCI-based registry can contain zero or more Helm repositories and each of those repositories can contain zero or more packaged Helm charts. + +### Use hosted registries + +There are several hosted container registries with OCI support that you can use for your Helm charts. For example: + +- [Amazon ECR](https://docs.aws.amazon.com/AmazonECR/latest/userguide/push-oci-artifact.html) +- [Azure Container Registry](https://docs.microsoft.com/azure/container-registry/container-registry-helm-repos#push-chart-to-registry-as-oci-artifact) +- [Docker Hub](https://docs.docker.com/docker-hub/oci-artifacts/) +- [Google Artifact Registry](https://cloud.google.com/artifact-registry/docs/helm/manage-charts) +- [IBM Cloud Container Registry](https://cloud.ibm.com/docs/Registry?topic=Registry-registry_helm_charts) +- [JFrog Artifactory](https://www.jfrog.com/confluence/display/JFROG/Docker+Registry) + +Follow the hosted container registry provider's documentation to create and configure a registry with OCI support. + +**Note:** You can run [Docker Registry](https://docs.docker.com/registry/deploying/) or [`zot`](https://github.com/project-zot/zot), which are OCI-based registries, on your development computer. Running an OCI-based registry on your development computer should only be used for testing purposes. + +## Commands for working with registries + +### The `registry` subcommand + +#### `login` + +login to a registry (with manual password entry) + +```console +$ helm registry login -u myuser localhost:5000 +Password: +Login succeeded +``` + +#### `logout` + +logout from a registry + +```console +$ helm registry logout localhost:5000 +Logout succeeded +``` + +### The `push` subcommand + +Upload a chart to an OCI-based registry: + +```console +$ helm push mychart-0.1.0.tgz oci://localhost:5000/helm-charts +Pushed: localhost:5000/helm-charts/mychart:0.1.0 +Digest: sha256:ec5f08ee7be8b557cd1fc5ae1a0ac985e8538da7c93f51a51eff4b277509a723 +``` + +The `push` subcommand can only be used against `.tgz` files +created ahead of time using `helm package`. + +When using `helm push` to upload a chart an OCI registry, the reference +must be prefixed with `oci://` and must not contain the basename or tag. + +The registry reference basename is inferred from the chart's name, +and the tag is inferred from the chart's semantic version. This is +currently a strict requirement. + +Certain registries require the repository and/or namespace (if specified) +to be created beforehand. Otherwise, an error will be produced during the + `helm push` operation. + +If you have created a [provenance file]({{< ref "provenance.md" >}}) (`.prov`), and it is present next to the chart `.tgz` file, it will +automatically be uploaded to the registry upon `push`. This results in +an extra layer on [the Helm chart manifest](#helm-chart-manifest). + +Users of the [helm-push plugin](https://github.com/chartmuseum/helm-push) (for uploading charts to [ChartMuseum]({{< ref "chart_repository.md" >}}#chartmuseum-repository-server)) +may experience issues, since the plugin conflicts with the new, built-in `push`. +As of version v0.10.0, the plugin has been renamed to `cm-push`. + +### Other subcommands + +Support for the `oci://` protocol is also available in various other subcommands. +Here is a complete list: + +- `helm pull` +- `helm show ` +- `helm template` +- `helm install` +- `helm upgrade` + +The basename (chart name) of the registry reference *is* +included for any type of action involving chart download +(vs. `helm push` where it is omitted). + +Here are a few examples of using the subcommands listed above against +OCI-based charts: + +``` +$ helm pull oci://localhost:5000/helm-charts/mychart --version 0.1.0 +Pulled: localhost:5000/helm-charts/mychart:0.1.0 +Digest: sha256:0be7ec9fb7b962b46d81e4bb74fdcdb7089d965d3baca9f85d64948b05b402ff + +$ helm show all oci://localhost:5000/helm-charts/mychart --version 0.1.0 +apiVersion: v2 +appVersion: 1.16.0 +description: A Helm chart for Kubernetes +name: mychart +... + +$ helm template myrelease oci://localhost:5000/helm-charts/mychart --version 0.1.0 +--- +# Source: mychart/templates/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount +... + +$ helm install myrelease oci://localhost:5000/helm-charts/mychart --version 0.1.0 +NAME: myrelease +LAST DEPLOYED: Wed Oct 27 15:11:40 2021 +NAMESPACE: default +STATUS: deployed +REVISION: 1 +NOTES: +... + +$ helm upgrade myrelease oci://localhost:5000/helm-charts/mychart --version 0.2.0 +Release "myrelease" has been upgraded. Happy Helming! +NAME: myrelease +LAST DEPLOYED: Wed Oct 27 15:12:05 2021 +NAMESPACE: default +STATUS: deployed +REVISION: 2 +NOTES: +... +``` + +## Specifying dependencies + +Dependencies of a chart can be pulled from a registry using the `dependency update` subcommand. + +The `repository` for a given entry in `Chart.yaml` is specified as the registry reference without the basename: + +``` +dependencies: + - name: mychart + version: "2.7.0" + repository: "oci://localhost:5000/myrepo" +``` +This will fetch `oci://localhost:5000/myrepo/mychart:2.7.0` when `dependency update` is executed. + +## Helm chart manifest + +Example Helm chart manifest as represented in a registry +(note the `mediaType` fields): +```json +{ + "schemaVersion": 2, + "config": { + "mediaType": "application/vnd.cncf.helm.config.v1+json", + "digest": "sha256:8ec7c0f2f6860037c19b54c3cfbab48d9b4b21b485a93d87b64690fdb68c2111", + "size": 117 + }, + "layers": [ + { + "mediaType": "application/vnd.cncf.helm.chart.content.v1.tar+gzip", + "digest": "sha256:1b251d38cfe948dfc0a5745b7af5ca574ecb61e52aed10b19039db39af6e1617", + "size": 2487 + } + ] +} +``` + +The following example contains a +[provenance file]({{< ref "provenance.md" >}}) +(note the extra layer): + +```json +{ + "schemaVersion": 2, + "config": { + "mediaType": "application/vnd.cncf.helm.config.v1+json", + "digest": "sha256:8ec7c0f2f6860037c19b54c3cfbab48d9b4b21b485a93d87b64690fdb68c2111", + "size": 117 + }, + "layers": [ + { + "mediaType": "application/vnd.cncf.helm.chart.content.v1.tar+gzip", + "digest": "sha256:1b251d38cfe948dfc0a5745b7af5ca574ecb61e52aed10b19039db39af6e1617", + "size": 2487 + }, + { + "mediaType": "application/vnd.cncf.helm.chart.provenance.v1.prov", + "digest": "sha256:3e207b409db364b595ba862cdc12be96dcdad8e36c59a03b7b3b61c946a5741a", + "size": 643 + } + ] +} +``` + +## Migrating from chart repos + +Migrating from classic [chart repositories]({{< ref "chart_repository.md" >}}) +(index.yaml-based repos) is as simple using `helm pull`, then using `helm push` to upload the resulting `.tgz` files to a registry. + + diff --git a/content/en/docs/topics/release_policy.md b/content/en/docs/topics/release_policy.md new file mode 100644 index 0000000000..3d5dcc4563 --- /dev/null +++ b/content/en/docs/topics/release_policy.md @@ -0,0 +1,57 @@ +--- +title: "Release schedule policy" +description: "Describes Helm's release schedule policy." +--- + +For the benefit of its users, Helm defines and announces release dates in +advance. This document describes the policy governing Helm's release schedule. + +## Release calendar + +A public calendar showing the upcoming Helm releases can be found [here](https://helm.sh/calendar/release). +## Semantic versioning + +Helm versions are expressed as `x.y.z`, where `x` is the major version, `y` is +the minor version, and `z` is the patch version, following [Semantic +Versioning](https://semver.org/spec/v2.0.0.html) terminology. + +## Patch releases + +Patch releases provide users with bug fixes and security fixes. They do not +contain new features. + +A new patch release relating to the latest minor/major release will normally be +done once a month on the second Wednesday of each month. + +A patch release to fix a high priority regression or security issue can be done +whenever needed. + +A patch release will be cancelled for any of the following reasons: +- if there is no new content since the previous release +- if the patch release date falls within one week before the first release candidate (RC1) of an upcoming minor release +- if the patch release date falls within four weeks following a minor release + +## Minor releases + +Minor releases contain security and bug fixes as well as new features. They +are backwards compatible with respect to the API and the CLI usage. + +To align with Kubernetes releases, a minor helm release will be done every +4 months (3 releases a year). + +Extra minor releases can be done if needed but will not affect the timeline of +an announced future release, unless the announced release is less than 7 days +away. + +At the same time as a release is published, the date of the next minor release +will be announced and posted to Helm's main web page. + +## Major releases + +Major releases contain breaking changes. Such releases are rare but are +sometimes necessary to allow helm to continue to evolve in important new +directions. + +Major releases can be difficult to plan. With that in mind, a final release +date will only be chosen and announced once the first beta version of such a +release is available. \ No newline at end of file diff --git a/content/en/docs/topics/v2_v3_migration.md b/content/en/docs/topics/v2_v3_migration.md new file mode 100644 index 0000000000..35e311354f --- /dev/null +++ b/content/en/docs/topics/v2_v3_migration.md @@ -0,0 +1,127 @@ +--- +title: "Migrating Helm v2 to v3" +description: "Learn how to migrate Helm v2 to v3." +weight: 13 +--- + +This guide shows how to migrate Helm v2 to v3. Helm v2 needs to be installed +and managing releases in one or more clusters. + +## Overview of Helm 3 Changes + +The full list of changes from Helm 2 to 3 are documented in the [FAQ +section](https://v3.helm.sh/docs/faq/#changes-since-helm-2). The following is a +summary of some of those changes that a user should be aware of before and +during migration: + +1. Removal of Tiller: + - Replaces client/server with client/library architecture (`helm` binary + only) + - Security is now on per user basis (delegated to Kubernetes user cluster + security) + - Releases are now stored as in-cluster secrets and the release object + metadata has changed + - Releases are persisted on a release namespace basis and not in the Tiller + namespace anymore +2. Chart repository updated: + - `helm search` now supports both local repository searches and making search + queries against Artifact Hub +3. Chart apiVersion bumped to "v2" for following specification changes: + - Dynamically linked chart dependencies moved to `Chart.yaml` + (`requirements.yaml` removed and requirements --> dependencies) + - Library charts (helper/common charts) can now be added as dynamically + linked chart dependencies + - Charts have a `type` metadata field to define the chart to be of an + `application` or `library` chart. It is application by default which means + it is renderable and installable + - Helm 2 charts (apiVersion=v1) are still installable +4. XDG directory specification added: + - Helm home removed and replaced with XDG directory specification for storing + configuration files + - No longer need to initialize Helm + - `helm init` and `helm home` removed +5. Additional changes: + - Helm install/set-up is simplified: + - Helm client (helm binary) only (no Tiller) + - Run-as-is paradigm + - `local` or `stable` repositories are not set-up by default + - `crd-install` hook removed and replaced with `crds` directory in chart + where all CRDs defined in it will be installed before any rendering of the + chart + - `test-failure` hook annotation value removed, and `test-success` + deprecated. Use `test` instead + - Commands removed/replaced/added: + - delete --> uninstall : removes all release history by default + (previously needed `--purge`) + - fetch --> pull + - home (removed) + - init (removed) + - install: requires release name or `--generate-name` argument + - inspect --> show + - reset (removed) + - serve (removed) + - template: `-x`/`--execute` argument renamed to `-s`/`--show-only` + - upgrade: Added argument `--history-max` which limits the maximum number + of revisions saved per release (0 for no limit) + - Helm 3 Go library has undergone a lot of changes and is incompatible with + the Helm 2 library + - Release binaries are now hosted on `get.helm.sh` + +## Migration Use Cases + +The migration use cases are as follows: + +1. Helm v2 and v3 managing the same cluster: + - This use case is only recommended if you intend to phase out Helm v2 + gradually and do not require v3 to manage any releases deployed by v2. All + new releases being deployed should be performed by v3 and existing v2 + deployed releases are updated/removed by v2 only + - Helm v2 and v3 can quite happily manage the same cluster. The Helm versions + can be installed on the same or separate systems + - If installing Helm v3 on the same system, you need to perform an additional + step to ensure that both client versions can co-exist until ready to remove + Helm v2 client. Rename or put the Helm v3 binary in a different folder to + avoid conflict + - Otherwise there are no conflicts between both versions because of the + following distinctions: + - v2 and v3 release (history) storage are independent of each other. The + changes include the Kubernetes resource for storage and the release + object metadata contained in the resource. Releases will also be on a per + user namespace instead of using the Tiller namespace (for example, v2 + default Tiller namespace kube-system). v2 uses "ConfigMaps" or "Secrets" + under the Tiller namespace and `TILLER`ownership. v3 uses "Secrets" in + the user namespace and `helm` ownership. Releases are incremental in both + v2 and v3 + - The only issue could be if Kubernetes cluster scoped resources (e.g. + `clusterroles.rbac`) are defined in a chart. The v3 deployment would then + fail even if unique in the namespace as the resources would clash + - v3 configuration no longer uses `$HELM_HOME` and uses XDG directory + specification instead. It is also created on the fly as need be. It is + therefore independent of v2 configuration. This is applicable only when + both versions are installed on the same system + +2. Migrating Helm v2 to Helm v3: + - This use case applies when you want Helm v3 to manage existing Helm v2 + releases + - It should be noted that a Helm v2 client: + - can manage 1 to many Kubernetes clusters + - can connect to 1 to many Tiller instances for a cluster + - This means that you have to be aware of this when migrating as releases + are deployed into clusters by Tiller and its namespace. You have to + therefore be aware of migrating for each cluster and each Tiller instance + that is managed by the Helm v2 client instance + - The recommended data migration path is as follows: + 1. Backup v2 data + 2. Migrate Helm v2 configuration + 3. Migrate Helm v2 releases + 4. When confident that Helm v3 is managing all Helm v2 data (for all + clusters and Tiller instances of the Helm v2 client instance) as + expected, then clean up Helm v2 data + - The migration process is automated by the Helm v3 + [2to3](https://github.com/helm/helm-2to3) plugin + +## Reference + + - Helm v3 [2to3](https://github.com/helm/helm-2to3) plugin + - Blog [post](https://helm.sh/blog/migrate-from-helm-v2-to-helm-v3/) + explaining `2to3` plugin usage with examples diff --git a/content/en/docs/topics/version_skew.md b/content/en/docs/topics/version_skew.md new file mode 100644 index 0000000000..c52988eb56 --- /dev/null +++ b/content/en/docs/topics/version_skew.md @@ -0,0 +1,77 @@ +--- +title: "Helm Version Support Policy" +description: "Describes Helm's patch release policy as well as the maximum version skew supported between Helm and Kubernetes." +--- + +This document describes the maximum version skew supported between Helm and +Kubernetes. + +## Supported Versions + +Helm versions are expressed as `x.y.z`, where `x` is the major version, `y` is +the minor version, and `z` is the patch version, following [Semantic +Versioning](https://semver.org/spec/v2.0.0.html) terminology. + +The Helm project maintains a release branch for the most recent minor release. +Applicable fixes, including security fixes, are cherry-picked into the release +branch, depending on severity and feasibility. More details can be found in +[Helm's release policy](release_policy.md). + +## Supported Version Skew + +When a new version of Helm is released, it is compiled against a particular +minor version of Kubernetes. For example, Helm 3.0.0 interacts with Kubernetes +using the Kubernetes 1.16.2 client, so it is compatible with Kubernetes 1.16. + +As of Helm 3, Helm is assumed to be compatible with `n-3` versions of Kubernetes +it was compiled against. Due to Kubernetes' changes between minor versions, Helm +2's support policy is slightly stricter, assuming to be compatible with `n-1` +versions of Kubernetes. + +For example, if you are using a version of Helm 3 that was compiled against the +Kubernetes 1.17 client APIs, then it should be safe to use with Kubernetes 1.17, +1.16, 1.15, and 1.14. If you are using a version of Helm 2 that was compiled +against the Kubernetes 1.16 client APIs, then it should be safe to use with +Kubernetes 1.16 and 1.15. + +It is not recommended to use Helm with a version of Kubernetes that is newer +than the version it was compiled against, as Helm does not make any forward +compatiblility guarantees. + +If you choose to use Helm with a version of Kubernetes that it does not support, +you are using it at your own risk. + +Please refer to the table below to determine what version of Helm is compatible +with your cluster. + +| Helm Version | Supported Kubernetes Versions | +|--------------|-------------------------------| +| 3.11.x | 1.26.x - 1.23.x | +| 3.10.x | 1.25.x - 1.22.x | +| 3.9.x | 1.24.x - 1.21.x | +| 3.8.x | 1.23.x - 1.20.x | +| 3.7.x | 1.22.x - 1.19.x | +| 3.6.x | 1.21.x - 1.18.x | +| 3.5.x | 1.20.x - 1.17.x | +| 3.4.x | 1.19.x - 1.16.x | +| 3.3.x | 1.18.x - 1.15.x | +| 3.2.x | 1.18.x - 1.15.x | +| 3.1.x | 1.17.x - 1.14.x | +| 3.0.x | 1.16.x - 1.13.x | +| 2.16.x | 1.16.x - 1.15.x | +| 2.15.x | 1.15.x - 1.14.x | +| 2.14.x | 1.14.x - 1.13.x | +| 2.13.x | 1.13.x - 1.12.x | +| 2.12.x | 1.12.x - 1.11.x | +| 2.11.x | 1.11.x - 1.10.x | +| 2.10.x | 1.10.x - 1.9.x | +| 2.9.x | 1.10.x - 1.9.x | +| 2.8.x | 1.9.x - 1.8.x | +| 2.7.x | 1.8.x - 1.7.x | +| 2.6.x | 1.7.x - 1.6.x | +| 2.5.x | 1.6.x - 1.5.x | +| 2.4.x | 1.6.x - 1.5.x | +| 2.3.x | 1.5.x - 1.4.x | +| 2.2.x | 1.5.x - 1.4.x | +| 2.1.x | 1.5.x - 1.4.x | +| 2.0.x | 1.4.x - 1.3.x | diff --git a/content/es/docs/_index.md b/content/es/docs/_index.md new file mode 100644 index 0000000000..e0a8a2a88a --- /dev/null +++ b/content/es/docs/_index.md @@ -0,0 +1,28 @@ +--- +title: "Docs Inicio" +description: "Todo lo que necesita saber sobre cómo está organizada la documentación." +--- + +# Bienvenidos + +Bienvenidos a la documentación de [Helm](https://helm.sh/). Helm es el administrador +de paquetes de Kubernetes, y puedes leer información de antecedentes detallados en +el [CNCF Informe de Viaje del Proyecto de Helm](https://www.cncf.io/cncf-helm-project-journey/). + +# Cómo está organizada la documentación + +Helm tiene mucha documentación. Una descripción general de alto nivel de cómo está +organizado lo ayudará a saber dónde buscar ciertas cosas: + +- [Tutoriales](intro) te llevan de la mano a través de una serie de pasos para crear + tu primer Helm chart. Empieza aquí si eres nuevo en Helm. +- [Guías de temas](topics) discute temas y + conceptos clave a un nivel bastante alto y proporcionar información de antecedentes + y explicaciones útiles. +- [Guías de la comunidad]({{< relref path="/docs/community" lang="en" >}}) discute + temas centrados en la comunidad de Helm. Comience aquí si desea obtener más información + sobre el proceso de desarrollo de Helm y cómo puede contribuir. +- [Guías prácticas](howto) son recetas. Le + guían a través de los pasos necesarios para abordar problemas clave y casos de uso. + Son más avanzados que los tutoriales y asumen cierto conocimiento de cómo funciona + Helm. diff --git a/content/es/docs/howto/_index.md b/content/es/docs/howto/_index.md new file mode 100644 index 0000000000..b0888aa4dd --- /dev/null +++ b/content/es/docs/howto/_index.md @@ -0,0 +1,11 @@ +--- +title: "Cómo Hacer" +weight: 2 +--- + +# Guías de Cómo Hacer + +Aquí encontrará respuestas breves a preguntas del tipo “¿Cómo hago para ...?”. +Estas guías prácticas no cubren temas en profundidad; encontrará ese material en +las [Guías de Temas](../topics). Sin embargo, +estas guías lo ayudarán a realizar rápidamente tareas comunes. diff --git a/content/es/docs/howto/chart_releaser_action.md b/content/es/docs/howto/chart_releaser_action.md new file mode 100644 index 0000000000..45df8d6e39 --- /dev/null +++ b/content/es/docs/howto/chart_releaser_action.md @@ -0,0 +1,89 @@ +--- +title: "Chart Releaser Action para automatizar página GitHub de Charts" +description: "Describe como utilizar Chart Releaser Action para automatizar releasing charts a través de la páginas de GitHub." +weight: 3 +--- + +Esta guía describe cómo utilizar [Chart Releaser +Action](https://github.com/marketplace/actions/helm-chart-releaser) para automatizar +el releasing charts a través de las páginas GitHub. Chart Releaser Action es una GitHub Action +workflow para converitrun proyecto GitHub en un repositorio de chart de Helm autoalojados, utilizando la herramienta +[helm/chart-releaser](https://github.com/helm/chart-releaser) CLI. + +## Cambios en el repositorio + +Crear un repositorio Git en tu organización GitHub. Puedes dar el nombre del repositorio como `helm-charts`, aunque también son aceptables otros nombres. Las fuentes de todos los Charts pueden colocarse en la rama `main`. Los charts deben colocarse en el directorio `/charts` en el nivel superior del árbol de directorios. + +Debe haber otra rama llamada `gh-pages` para publicar los charts. Los cambios en esa rama serán creados automáticamente por Chart Releaser Action como se describe a continuación. Sin embargo, puede crear esa `gh-branch` y añadir el fichero `README.md`, que será visible para los usuarios que visiten la página. + +Puedes añadir instrucciones en el `README.md` para la instalación de charts de la siguiente manera +(sustituye ``, ``, y ``): + + +## Uso + +[Helm](https://helm.sh) debe estar instalado para usar los charts. Por favor, consulte la [documentación](https://helm.sh/docs) de Helm para emprezar. + +Una vez que Helm ha sido configurado correctamente, añada el repo como sigue: +``` +helm repo add https://.github.io/helm-charts +``` +Si ya ha añadido este repositorio anteriormente, ejecute `helm repo update` para recuperar +las últimas versiones de los paquetes. A continuación, puede ejecutar `helm search repo +` para ver los gráficos. + +Para instalar el chart : +``` +helm install my- / +``` +Para desinstalar el chart: +``` +helm delete my- +``` + +Los charts se publicarán en un sitio web con una URL como esta: +``` +https://.github.io/helm-charts +``` + +## GitHub Actions Workflow + +Crear fichero de GitHub Actions workflow en la rama `main` en +`.github/workflows/release.yml` + +``` +name: Release Charts + +on: + push: + branches: + - main + +jobs: + release: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Configure Git + run: | + git config user.name "$GITHUB_ACTOR" + git config user.email "$GITHUB_ACTOR@users.noreply.github.com" + + - name: Run chart-releaser + uses: helm/chart-releaser-action@v1.5.0 + env: + CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}" +``` + +La configuración anterior utiliza [@helm/chart-releaser-action](https://github.com/helm/chart-releaser-action) para converitr su proyecto GitHub en un repositorio de Helm chart autoalojado. Lo hace - durante cada push a main - comprobando cada chart en su proyecto, y siempre que la nueva versión de chart, crea una versión correspondiente en GitHub con el nombre de la versión del chart, añade artefactos de Helm chart al release, y crea o actualiza un fichero `index.yaml` con metadatos sobre esas releases, que luego se alojan en la páginas de GitHub. + +El número de versión de la Chart Releaser Action utilizado en el ejemplo anterior es `v1.5.0`. +Puedes cambiarlo por la [última versión disponible](https://github.com/helm/chart-releaser-action/releases). + +Nota: El Chart Releaser Action se utiliza casi siempre junto con [Helm Testing +Action](https://github.com/marketplace/actions/helm-chart-testing) y [Kind +Action](https://github.com/marketplace/actions/kind-cluster). diff --git a/content/es/docs/howto/chart_repository_sync_example.md b/content/es/docs/howto/chart_repository_sync_example.md new file mode 100644 index 0000000000..332447575d --- /dev/null +++ b/content/es/docs/howto/chart_repository_sync_example.md @@ -0,0 +1,102 @@ +--- +title: "Sincronizar tu Repositorio de Charts" +description: "Describe cómo sincronizar tus repositorios de charts locales y remotos." +weight: 2 +--- + +*Nota: Este ejemplo es específico para un bucket de Google Cloud Storage (GCS) +que sirve como repositorio de charts.* + +## Requisitos Previos + +* Instalar la herramienta [gsutil](https://cloud.google.com/storage/docs/gsutil). + *Dependemos en gran medida de la funcionalidad de gsutil rsync* +* Asegúrese de tener acceso al binario de Helm +* _Opcional: Le recomendamos que establezca [control de versiones del + objeto](https://cloud.google.com/storage/docs/gsutil/addlhelp/ObjectVersioningandConcurrencyControl#top_of_page) + en su bucket de GCS en caso de que elimine algo accidentalmente._ + +## Configurar un directorio de repositorio de charts local + +Cree un directorio local como lo hicimos en [la guía del repositorio de charts]({{< relref path="/docs/topics/chart_repository.md" lang="en" >}}) +, y coloque sus charts empaquetados en ese directorio. + +Por ejemplo: + +```console +$ mkdir fantastic-charts +$ mv alpine-0.1.0.tgz fantastic-charts/ +``` + +## Genere un index.yaml actualizado + +Utilice Helm para generar un archivo index.yaml actualizado pasando la ruta del +directorio y la URL del repositorio remoto al comando `helm repo index` de esta +manera: + +```console +$ helm repo index fantastic-charts/ --url https://fantastic-charts.storage.googleapis.com +``` + +Esto generará un archivo index.yaml actualizado y lo colocará en el directorio +`fantastic-charts /`. + +## Sincronice sus repositorios de charts locales y remotos + +Sube el contenido del directorio a tu bucket de GCS ejecutando `scripts/sync-repo.sh` +y pase el nombre del directorio local y el nombre del bucket de GCS. + +Por ejemplo: + +```console +$ pwd +/Users/me/code/go/src/helm.sh/helm +$ scripts/sync-repo.sh fantastic-charts/ fantastic-charts +Getting ready to sync your local directory (fantastic-charts/) to a remote repository at gs://fantastic-charts +Verifying Prerequisites.... +Thumbs up! Looks like you have gsutil. Let's continue. +Building synchronization state... +Starting synchronization +Would copy file://fantastic-charts/alpine-0.1.0.tgz to gs://fantastic-charts/alpine-0.1.0.tgz +Would copy file://fantastic-charts/index.yaml to gs://fantastic-charts/index.yaml +Are you sure you would like to continue with these changes?? [y/N]} y +Building synchronization state... +Starting synchronization +Copying file://fantastic-charts/alpine-0.1.0.tgz [Content-Type=application/x-tar]... +Uploading gs://fantastic-charts/alpine-0.1.0.tgz: 740 B/740 B +Copying file://fantastic-charts/index.yaml [Content-Type=application/octet-stream]... +Uploading gs://fantastic-charts/index.yaml: 347 B/347 B +Congratulations your remote chart repository now matches the contents of fantastic-charts/ +``` + +## Actualizar su repositorio de chart + +Querrá mantener una copia local del contenido de su repositorio de chart o usar +`gsutil rsync` para copiar el contenido de su repositorio de chart remoto a un +directorio local. + +Por ejemplo: + +```console +$ gsutil rsync -d -n gs://bucket-name local-dir/ # la bandera -n hace un ensayo +Building synchronization state... +Starting synchronization +Would copy gs://bucket-name/alpine-0.1.0.tgz to file://local-dir/alpine-0.1.0.tgz +Would copy gs://bucket-name/index.yaml to file://local-dir/index.yaml + +$ gsutil rsync -d gs://bucket-name local-dir/ # realiza las acciones de copia +Building synchronization state... +Starting synchronization +Copying gs://bucket-name/alpine-0.1.0.tgz... +Downloading file://local-dir/alpine-0.1.0.tgz: 740 B/740 B +Copying gs://bucket-name/index.yaml... +Downloading file://local-dir/index.yaml: 346 B/346 B +``` + +Enlaces Útiles: + +* Documentación sobre [gsutil rsync](https://cloud.google.com/storage/docs/gsutil/commands/rsync#description) +* [La Guía del Repositorio de Charts]({{< relref path="/docs/topics/chart_repository.md" lang="en" >}}) +* Documentación sobre [Control de versiones de objetos y control de + simultaneidad](https://cloud.google.com/storage/docs/gsutil/addlhelp/ObjectVersioningandConcurrencyControl#overview) + en Google Cloud Storage diff --git a/content/es/docs/howto/charts_tips_and_tricks.md b/content/es/docs/howto/charts_tips_and_tricks.md new file mode 100644 index 0000000000..bc312d9ab9 --- /dev/null +++ b/content/es/docs/howto/charts_tips_and_tricks.md @@ -0,0 +1,340 @@ +--- +title: "Consejos y Trucos para el Desarrollo de Charts" +description: "Covers some of the tips and tricks Helm chart developers have learned while building production-quality charts." +description: "Cubre algunos de los consejos y trucos que los desarrolladores de charts de Helm han aprendido al crear charts con calidad de producción." +weight: 1 +--- + +Esta guía cubre algunos de los consejos y trucos que los desarrolladores de charts +de Helm han aprendido al crear charts con calidad de producción. + +## Conozca las funciones de plantilla + +Helm usa [plantillas Go](https://godoc.org/text/template) para crear plantillas +para sus archivos de recursos. Si bien Go incluye varias funciones integradas, +hemos agregado muchas otras. + +Primero, agregamos todas las funciones en la [biblioteca +Sprig](https://masterminds.github.io/sprig/). + +También agregamos dos funciones de plantilla especiales: `include` y +`required`. La función `include` le permite traer otra plantilla y luego pasar +los resultados a otras funciones de la plantilla. + +Por ejemplo, este fragmento de plantilla incluye una plantilla llamada `mytpl`, +luego pone el resultado en minúsculas y luego lo envuelve entre comillas dobles. + +```yaml +value: {{ include "mytpl" . | lower | quote }} +``` + +La función `required` le permite declarar una entrada de valores particulares según +sea necesario para la representación de la plantilla. Si el valor está vacío, +la representación de la plantilla fallará con un mensaje de error enviado al +usuario. + +The following example of the `required` function declares an entry for +.Values.who is required, and will print an error message when that entry is +missing: + +El siguiente ejemplo de la función `required` declara que una entrada para +.Values.who es obligatoria e imprimirá un mensaje de error cuando falte esa entrada: + +```yaml +value: {{ required "A valid .Values.who entry required!" .Values.who }} +``` + +## Envuelve en comillas Candeas, no Enteros + +Cuando trabaja con cadenas de carácteres, siempre es más seguro envolverlas entre +comillas dobles que dejarlas como palabras sueltas: + +```yaml +name: {{ .Values.MyName | quote }} +``` + +Pero cuando trabaje con números enteros, _no envuelva entre comillas dobles los +valores._ Eso puede, en muchos casos, causar errores de análisis dentro de Kubernetes. + +```yaml +port: {{ .Values.Port }} +``` + +Esta observación no se aplica a los valores de las variables de entorno que se espera +que sean cadenas, incluso si representan números enteros: + +```yaml +env: + - name: HOST + value: "http://host" + - name: PORT + value: "1234" +``` + +## Utilizar la Función 'include' + +Go proporciona una forma de incluir una plantilla en otra utilizando la directiva +incorporada `template`. Sin embargo, la directiva incorporada no se puede utilizar +en las canalizaciones de plantilla de Go. + +Para que sea posible incluir una plantilla y luego realizar una operación en la +salida de esa plantilla, Helm tiene una función `include` especial: + +``` +{{ include "toYaml" $value | indent 2 }} +``` + +Lo anterior incluye una plantilla llamada `toYaml`, le pasa `$value` y luego pasa +la salida de esa plantilla a la función `indent`. + +Debido a que YAML atribuye importancia a los niveles de sangría y los espacios +en blanco, esta es una excelente manera de incluir fragmentos de código, pero +manejar la sangría en un contexto relevante. + +## Utilizar la Función 'required' + +Go proporciona una forma de configurar opciones de plantilla para controlar el +comportamiento cuando un mapa se indexa con una clave que no está presente en el +mapa. Por lo general, esto se establece con `template.Options("missingkey=option")`, +donde `option` puede ser `default`, `zero` o `error`. Si bien establecer esta opción +en error detendrá la ejecución con un error, esto se aplicaría a todas las claves +que faltan en el mapa. Puede haber situaciones en las que un desarrollador de charts +quiera aplicar este comportamiento para valores seleccionados en el archivo `values.yaml`. + +La función `required` brinda a los desarrolladores la capacidad de declarar una +entrada de valor según sea necesario para la renderización de la plantilla. Si +la entrada está vacía en `values.yaml`, la plantilla no se procesará y devolverá +un mensaje de error proporcionado por el desarrollador. + +Por ejemplo: + +``` +{{ required "A valid foo is required!" .Values.foo }} +``` + +Lo anterior renderizará la plantilla cuando se defina `.Values.foo`, pero fallará +en renderizar y se cerrará cuando `.Values.foo` no esté definido. + +## Utilizar la Función 'tpl' + +The `tpl` function allows developers to evaluate strings as templates inside a +template. This is useful to pass a template string as a value to a chart or +render external configuration files. Syntax: `{{ tpl TEMPLATE_STRING VALUES }}` + +La función `tpl` permite a los desarrolladores evaluar cadenas como plantillas +dentro de una plantilla. Esto es útil para pasar una cadena de plantilla como +valor a un chart o representar archivos de configuración externos. Sintaxis: +`{{tpl TEMPLATE_STRING VALUES}}` + +Ejemplos: + +```yaml +# valores +template: "{{ .Values.name }}" +name: "Tom" + +# plantilla +{{ tpl .Values.template . }} + +# salida +Tom +``` + +Renderizar un archivo de configuración externo: + +```yaml +# archivo de configuración externo conf/app.conf +firstName={{ .Values.firstName }} +lastName={{ .Values.lastName }} + +# valores +firstName: Peter +lastName: Parker + +# plantilla +{{ tpl (.Files.Get "conf/app.conf") . }} + +# salida +firstName=Peter +lastName=Parker +``` + +## Creando Image Pull Secrets + +Los Image Pull Secrets son esencialmente una combinación de _registro_, +_username_ y _password_. Es posible que los necesite en una aplicación que está +implementando, pero para crearlos es necesario ejecutar `base64` un par de veces. +Podemos escribir una plantilla auxiliar para componer el archivo de configuración +de Docker y usarlo como carga útil del Secret. Aquí hay un ejemplo: + +Primero, suponga que las credenciales están definidas en el archivo `values.yaml` +así: + +```yaml +imageCredentials: + registry: quay.io + username: someone + password: sillyness + email: someone@host.com +``` + +Luego definimos nuestra plantilla auxiliar de la siguiente manera: + +``` +{{- define "imagePullSecret" }} +{{- with .Values.imageCredentials }} +{{- printf "{\"auths\":{\"%s\":{\"username\":\"%s\",\"password\":\"%s\",\"email\":\"%s\",\"auth\":\"%s\"}}}" .registry .username .password .email (printf "%s:%s" .username .password | b64enc) | b64enc }} +{{- end }} +{{- end }} +``` + +Finalmente, usamos la plantilla auxiliar en una plantilla más grande para crear +el manifiesto del Secret: + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: myregistrykey +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +``` + +## Despliegue de Deployments Automáticamente + +Often times ConfigMaps or Secrets are injected as configuration files in +containers or there are other external dependency changes that require rolling +pods. Depending on the application a restart may be required should those be +updated with a subsequent `helm upgrade`, but if the deployment spec itself +didn't change the application keeps running with the old configuration resulting +in an inconsistent deployment. + +A menudo, los ConfigMaps o Secrets se inyectan como archivos de configuración en +contenedores o hay otros cambios de dependencia externa que requieren recrear pods. +Dependiendo de la aplicación, es posible que sea necesario reiniciar si se actualizan +con un `helm upgrade` posterior, pero si el Deployments Spec en sí no cambia, la +aplicación sigue ejecutándose con la configuración anterior, lo que da como resultado +un despliegue inconsistente. + +La función `sha256sum` se puede utilizar para garantizar que la sección de +anotaciones de una implementación se actualice si cambia otro archivo: + +```yaml +kind: Deployment +spec: + template: + metadata: + annotations: + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} +[...] +``` + +En el caso de que siempre desee lanzar su Deployment, puede usar un paso de anotación +similar al anterior, en lugar de reemplazarlo con una cadena aleatoria para que siempre +cambie y haga que la implementación se lance: + +```yaml +kind: Deployment +spec: + template: + metadata: + annotations: + rollme: {{ randAlphaNum 5 | quote }} +[...] +``` + +Cada invocación de la función de plantilla generará una cadena aleatoria única. +Esto significa que si es necesario sincronizar las cadenas aleatorias utilizadas +por varios recursos, todos los recursos relevantes deberán estar en el mismo +archivo de plantilla. + +Ambos métodos permiten que su Deployment aproveche la lógica de la estrategia +de actualización incorporada para evitar tener tiempo de inactividad. + +NOTA: En el pasado, recomendamos usar la marca `--recreate-pods` como otra opción. +Esta bandera se ha marcado como obsoleta en Helm 3 a favor del método más +declarativo anterior. + +## Dígale a Helm que No Desinstale un Recurso + +A veces hay recursos que no deben desinstalarse cuando Helm ejecuta un +`helm uninstall`. Los desarrolladores de charts pueden agregar una anotación +a un recurso para evitar que se desinstale. + +```yaml +kind: Secret +metadata: + annotations: + "helm.sh/resource-policy": keep +[...] +``` + +(Se requieren comillas) + +La anotación `"helm.sh/resource-policy": keep` indica a Helm que omita la +eliminación de este recurso cuando una operación de helm (como `helm uninstall`, +`helm upgrade` o `helm rollback`) resulte en su eliminación. _Sin embargo_, este +recurso queda huérfano. Helm ya no lo administrará de ninguna manera. Esto puede +ocasionar problemas si se usa `helm install --replace` en una versión que ya se +ha desinstalado, pero que ha conservado los recursos. + +## Utilizar "Parciales" (Partials) e Incluir Plantillas + +A veces, desea crear algunas partes reutilizables en tus charts, ya sean bloques +o parciales de plantilla. Y, a menudo, es más limpio mantenerlos en sus propios archivos. + +En el directorio `templates /`, no se espera que ningún archivo que comience con +un guión bajo (`_`) genere un archivo de manifiesto de Kubernetes. Entonces, por +convención, las plantillas auxiliares y los parciales se colocan en un archivo +`_helpers.tpl`. + +## Charts Complejos con Muchas Dependencias + +Muchos de los charts de [Artifact Hub](https://artifacthub.io/packages/search?kind=0) +de la CNCF son "bloques de construcción" para crear aplicaciones más avanzadas. +Pero los charts pueden usarse para crear instancias de aplicaciones a gran escala. +En tales casos, un solo chart general puede tener múltiples sub-charts, cada uno +de los cuales funciona como una parte del todo. + +The current best practice for composing a complex application from discrete +parts is to create a top-level umbrella chart that exposes the global +configurations, and then use the `charts/` subdirectory to embed each of the +components. + +La mejor práctica actual para componer una aplicación compleja a partir de partes +discretas es crear un chart general de nivel superior que exponga las configuraciones +globales, y luego usar el subdirectorio `charts/` para incrustar cada uno de los +componentes. + +## YAML es un Superconjunto de JSON + +Según la especificación YAML, YAML es un superconjunto de JSON. Eso significa que +cualquier estructura JSON válida debería ser válida en YAML. + +Esto tiene una ventaja: a veces, a los desarrolladores de plantillas les puede +resultar más fácil expresar una estructura de datos con una sintaxis similar a +JSON en lugar de lidiar con la sensibilidad de los espacios en blanco de YAML. + +Como práctica recomendada, las plantillas deben seguir una sintaxis similar a YAML, +_a menos que_ la sintaxis JSON reduzca sustancialmente el riesgo de problemas de +formato. + +## Tenga Cuidado con la Generación de Valores Aleatorios + +Hay funciones en Helm que le permiten generar datos aleatorios, +claves criptográficas, etc. Está bien usarlos. Pero tenga en cuenta que durante +las actualizaciones, las plantillas se vuelven a ejecutar. Cuando la ejecución de +una plantilla genera datos que difieren de la última ejecución, se activará una +actualización de ese recurso. + +## Instalar o Actualizar un Release con un Comando + +Helm proporciona una forma de realizar una instalación o actualización como un solo +comando. Utilice `helm upgrade` con el comando `--install`. Esto hará que Helm vea +si la versión ya está instalada. De lo contrario, ejecutará una instalación. Si es +así, se actualizará el Release existente. + +```console +$ helm upgrade --install --values +``` diff --git a/content/es/docs/intro/_index.md b/content/es/docs/intro/_index.md new file mode 100644 index 0000000000..9fe64440f5 --- /dev/null +++ b/content/es/docs/intro/_index.md @@ -0,0 +1,8 @@ +--- +title: "Introducción" +weight: 1 +--- + +# Introducción a Helm + +¿Eres nuevo en Helm? ¡Este es el lugar para comenzar! diff --git a/content/es/docs/intro/install.md b/content/es/docs/intro/install.md new file mode 100755 index 0000000000..341e58549b --- /dev/null +++ b/content/es/docs/intro/install.md @@ -0,0 +1,157 @@ +--- +title: "Instalar Helm" +description: "Aprenda a instalar y poner Helm en funcionamiento." +weight: 2 +--- + +Esta guía muestra cómo instalar Helm CLI. Helm se puede instalar desde la fuente +o desde versiones binarias preconstruidas. + +## Desde el Proyecto Helm + +El proyecto Helm proporciona dos formas de obtener e instalar Helm. Estos son los +métodos oficiales para obtener lanzamientos de Helm. Además de eso, la comunidad +de Helm proporciona métodos para instalar Helm a través de diferentes administradores +de paquetes. La instalación a través de esos métodos se puede encontrar debajo +de los métodos oficiales. + +### De los Lanzamientos Binarios + +Cada [lanzamiento](https://github.com/helm/helm/releases) de Helm proporciona +binarios de lanzamiento para una variedad de sistemas operativos. Estas versiones +binarias se pueden descargar e instalar manualmente. + +1. Descarga tu [versión deseada](https://github.com/helm/helm/releases) +2. Desempaquétala (`tar -zxvf helm-v3.0.0-linux-amd64.tar.gz`) +3. Encuentra el binario `helm` en el directorio desempaquetado, y muévelo a su +destino deseado (`mv linux-amd64/helm /usr/local/bin/helm`) + +De ahí, debes ser capaz de correr el cliente y +[agregar repos estables](https://helm.sh/docs/intro/quickstart/#initialize-a-helm-chart-repository): +`helm help`. + +**Nota:** Las pruebas automatizadas de Helm se realizan para Linux AMD64 solo durante +las compilaciones y lanzamientes de CircleCi. Las pruebas de otros sistemas operativos +son responsabilidad de la comunidad que solicita Helm para el sistema operativo +en cuestión. + +### Desde Script + +Helm ahora tiene un script de instalación que automáticamente tomará la última versión +de Helm y [la instalará localmente](https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3). + +Puede recuperar ese script y luego ejecutarlo localmente. Está bien documentado para +que puedas leerlo y comprender lo que está haciendo antes de ejecutarlo. + +```console +$ curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 +$ chmod 700 get_helm.sh +$ ./get_helm.sh +``` + +Sí, puedes `curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash`si +quieres vivir al límite. + +## A Través de Administradores de Paquetes + +La comunidad de Helm ofrece la posibilidad de instalar Helm a través de administradores +de paquetes del sistema operativo. Estos no son soportados por el proyecto Helm y +no se consideran terceros de confianza. + +### Desde Homebrew (macOS) + +Los miembros de la comunidad de Helm han contribuido con una fórmula de Helm a Homebrew. +Esta fórmula generalmente está actualizada. + +```console +brew install helm +``` + +(Nota: también hay una fórmula para emacs-helm, que es un proyecto diferente). + +### Desde Chocolatey (Windows) + +Los miembros de la comunidad Helm han contribuido con un +[paquete Helm](https://chocolatey.org/packages/kubernetes-helm) construido para +[Chocolatey](https://chocolatey.org/). Este paquete generalmente está actualizado. + +```console +choco install kubernetes-helm +``` + +### Desde Apt (Debian/Ubuntu) + +Los miembros de la comunidad Helm han contribuido con un +[paquete Helm](https://helm.baltorepo.com/stable/debian/) para Apt. +Este paquete generalmente está actualizado. + +```console +curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null +sudo apt-get install apt-transport-https --yes +echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list +sudo apt-get update +sudo apt-get install helm +``` + +### Desde Snap + +La comunidad [Snapcrafters](https://github.com/snapcrafters) mantiene la +versión Snap del [paquete Helm](https://snapcraft.io/helm): + +```console +sudo snap install helm --classic +``` + +### Desde pkg (FreeBSD) + +Los miembros de la comunidad FreeBSD han contribuido con una compilación de +[paquete Helm](https://www.freshports.org/sysutils/helm) a la +[Colección de Ports de FreeBSD](https://man.freebsd.org/ports) + +```console +pkg install helm +``` + +### Builds de Desarrollo + +Además de los lanzamientos, puede descargar o instalar versiones de desarrollo de +Helm. + +### Desde Canary Builds + +Los "Canary" builds son versiones del software Helm que se crean a partir lo último +de la rama main. No son lanzamientos oficiales y pueden no ser estables. Sin embargo, +ofrecen la oportunidad de probar las funciones de vanguardia. + +Los binarios Canary builds se guardan en [get.helm.sh](https://get.helm.sh). Aquí +hay enlaces a las compilaciones comunes: + +- [Linux AMD64](https://get.helm.sh/helm-canary-linux-amd64.tar.gz) +- [macOS AMD64](https://get.helm.sh/helm-canary-darwin-amd64.tar.gz) +- [Windows Experimental AMD64](https://get.helm.sh/helm-canary-windows-amd64.zip) + +### Desde los Fuentes (Linux, macOS) + +Construir Helm desde los fuentes es un poco más complicado, pero es la mejor +manera de hacerlo si desea probar la última versión (prelanzamiento) de Helm. + +Debe tener un entorno de trabajo de Go. + +```console +$ git clone https://github.com/helm/helm.git +$ cd helm +$ make +``` + +Si es necesario, buscará las dependencias, las almacenará en caché y validará +la configuración. Luego compilará `helm` y lo colocará en `bin/helm`. + +## Conclusión + +En la mayoría de los casos, la instalación es tan simple como obtener un binario +`helm` preconstruido. Este documento cubre casos adicionales para aquellos que +desean hacer cosas más sofisticadas con Helm. + +Una vez que tenga el cliente de Helm instalado correctamente, puede continuar con +el uso de Helm para administrar Charts y[agregar el repositorio +estable](https://helm.sh/docs/intro/quickstart/#initialize-a-helm-chart-repository). diff --git a/content/es/docs/intro/quickstart.md b/content/es/docs/intro/quickstart.md new file mode 100644 index 0000000000..d5704e3ebb --- /dev/null +++ b/content/es/docs/intro/quickstart.md @@ -0,0 +1,130 @@ +--- +title: "Guía de inicio rápido" +description: "Cómo instalar y comenzar con Helm, incluidas instrucciones para distribuciones, preguntas frecuentes y complementos." +weight: 1 +--- + +Esta guía explica cómo empezar a utilizar Helm rápidamente. + +## Requisitos Previos + +Los siguientes requisitos previos son necesarios para un uso exitoso y seguro +de Helm. + +1. Un cluster Kubernetes +2. Decidir qué configuraciones de seguridad aplicar a su instalación, si corresponde +3. Instalar y configurar Helm. + +### Instalar Kubernetes o tener acceso a un clúster + +- Debe tener Kubernetes instalado. Para la última versión de Helm, recomendamos +la última versión estable de Kubernetes, que en la mayoría de los casos es la +segunda versión menor más reciente. +- También debe tener una copia configurada localmente de `kubectl`. + +Consulte la [Política de Soporte de Versión de Helm](https://helm.sh/docs/topics/version_skew/) +para conocer el sesgo de versión máximo admitido entre Helm y Kubernetes. + +## Instalar Helm + +Descargue una versión binaria del cliente Helm. Puedes usar herramientas como +`homebrew`, o mirar [la página de lanzamientos +oficiales](https://github.com/helm/helm/releases). + +Para obtener más detalles u otras opciones, consulte [la guía de +instalación]({{< ref "install.md" >}}). + +## Inicializar un Repositorio de Helm Chart + +Una vez que tengas Helm listo, puede agregar un repositorio de Charts. Consulta +[Artifact Hub](https://artifacthub.io/packages/search?kind=0) para conocer los +repositorios de Helm Chart disponibles. + +```console +$ helm repo add stable https://charts.helm.sh/stable +``` + +Una vez que esté instalado, podrá enumerar los Charts que puedes instalar: + +```console +$ helm search repo stable +NAME CHART VERSION APP VERSION DESCRIPTION +stable/acs-engine-autoscaler 2.2.2 2.1.1 DEPRECATED Scales worker nodes within agent pools +stable/aerospike 0.2.8 v4.5.0.5 A Helm chart for Aerospike in Kubernetes +stable/airflow 4.1.0 1.10.4 Airflow is a platform to programmatically autho... +stable/ambassador 4.1.0 0.81.0 A Helm chart for Datawire Ambassador +# ... y muchos más +``` + +## Instalar un Chart de Ejemplo + +Para instalar un chart, puede ejecutar el comando `helm install`. Helm tiene varias +formas de buscar e instalar un chart, pero la más fácil es utilizar uno de los charts +`stable` oficiales. + +```console +$ helm repo update # Asegúrese de obtener la última lista de charts +$ helm install stable/mysql --generate-name +Released smiling-penguin +``` + +En el ejemplo anterior, se lanzó el chart `stable/mysql` y el nombre de nuestro +nuevo release es `smiling-penguin`. + +Puedes obtener una idea simple de las características de este chart de MySQL ejecutando +`helm show chart stable/mysql`. O puedes ejecutar `helm show all stable/mysql` +para obtener toda la información sobre el chart. + +Siempre que instales un chart, se crea un nuevo release. Por lo tanto, un chart +se puede instalar varias veces en el mismo cluster. Y cada uno se puede administrar +y actualizar de forma independiente. + +El comando `helm install` es un comando muy poderoso con muchas capacidades. +Para obtener más información al respecto, consulte la [Guía de Uso de +Helm]({{< ref "using_helm.md" >}}) + +## Más Información sobre Releases + +Es fácil ver lo que se ha lanzado utilizando Helm: + +```console +$ helm ls +NAME VERSION UPDATED                   STATUS   CHART +smiling-penguin 1 Wed Sep 28 12:59:46 2016 DEPLOYED mysql-0.1.0 +``` + +La función `helm list` le mostrará una lista de todos los releases desplegados. + +## Desinstalar un Release + +Para desinstalar un release, utilice el comando `helm uninstall`: + +```console +$ helm uninstall smiling-penguin +Removed smiling-penguin +``` + +Esto desinstalará `smiling-penguin` de Kubernetes, lo que eliminará todos los +recursos asociados con el release, así como el historial del release. + +Si la bandera `--keep-history` es utilizada, el historial del release será mantenido. +Podrás solicitar información sobre ese release: + +```console +$ helm status smiling-penguin +Status: UNINSTALLED +... +``` + +Debido a que Helm realiza un seguimiento de sus releases incluso después de haberlos +desinstalado, puede auditar el historial de un clúster e incluso recuperar un release +(con `helm rollback`). + +## Leer el Texto de Ayuda + +Para obtener más información sobre los comandos disponibles de Helm, utiliza +`helm help` o escribe un comando seguido de la bandera `-h`: + +```console +$ helm get -h +``` diff --git a/content/es/docs/intro/using_helm.md b/content/es/docs/intro/using_helm.md new file mode 100755 index 0000000000..ad73ab9848 --- /dev/null +++ b/content/es/docs/intro/using_helm.md @@ -0,0 +1,507 @@ +--- +title: "Uso de Helm" +description: "Explica los conceptos básicos de Helm.." +weight: 3 +--- + +Esta guía explica los conceptos básicos del uso de Helm para administrar paquetes +en su clúster de Kubernetes. Asume que ya has [instalado]({{< ref +"install.md" >}}) el cliente de Helm. + +Si simplemente está interesado en ejecutar algunos comandos rápidos, es posible +que desee comenzar con la [Guía de inicio rápido]({{< ref "quickstart.md" >}}). +Este capítulo cubre los detalles de los comandos de Helm y explica cómo usar Helm. + +## Tres Grandes Conceptos + +Un *Chart* es un paquete de Helm. Contiene todas las definiciones de recursos +necesarias para ejecutar una aplicación, herramienta o servicio dentro de un +clúster de Kubernetes. Piense en él como el equivalente de Kubernetes de una +fórmula Homebrew, un Apt de dpkg o un archivo Yum de RPM. + +Un *Repositorio* es el lugar donde se pueden recopilar y compartir Charts. +Es como el [archivo CPAN](https://www.cpan.org) de Perl o la [Base de Datos de +Paquetes de Fedora](https://src.fedoraproject.org/), pero para los paquetes +de Kubernetes. + +Un *Release* es una instancia de un Chart que se ejecuta en un clúster de +Kubernetes. A menudo, un Chart se puede instalar muchas veces en el mismo clúster. +Y cada vez que se instala, se crea un nuevo _release_. Considere un Chart MySQL. +Si desea que se ejecuten dos bases de datos en su clúster, puede instalar ese +Chart dos veces. Cada uno tendrá su propio _release_, que a su vez tendrá su propio +_nombre de release_. + +Con estos conceptos en mente, ahora podemos explicar Helm así: + +Helm instala _charts_ en Kubernetes, creando nuevos _release_ para cada +instalacion. Y para encontrar nuevos charts, puedes buscar en los _repositorios_ +de charts de Helm. + +## 'helm search': Buscando Charts + +Helm viene con un poderoso comando de búsqueda. Se puede utilizar para buscar +dos tipos diferentes de fuentes: + +- `helm search hub` buscar en [Artifact Hub](https://artifacthub.io), que + enumera charts de Helm de docenas de repositorios diferentes. +- `helm search repo` busca en los repositorios que ha agregado a su cliente + de helm local (con `helm repo add`). Esta búsqueda se realiza a través de + datos locales y no se necesita una conexión de red pública. + +Puede encontrar charts disponibles públicamente ejecutando `helm search hub`: + +```console +$ helm search hub wordpress +URL CHART VERSION APP VERSION DESCRIPTION +https://hub.helm.sh/charts/bitnami/wordpress 7.6.7 5.2.4 Web publishing platform for building blogs and ... +https://hub.helm.sh/charts/presslabs/wordpress-... v0.6.3 v0.6.3 Presslabs WordPress Operator Helm Chart +https://hub.helm.sh/charts/presslabs/wordpress-... v0.7.1 v0.7.1 A Helm chart for deploying a WordPress site on ... +``` + +Lo anterior busca todos los charts de `wordpress` en Artifact Hub. + +Sin filtro, `helm search hub` muestra todos los charts disponibles. + +Usando `helm search repo`, puede encontrar los nombres de los charts en los +repositorios que ya has agregado: + +```console +$ helm repo add brigade https://brigadecore.github.io/charts +"brigade" has been added to your repositories +$ helm search repo brigade +NAME CHART VERSION APP VERSION DESCRIPTION +brigade/brigade 1.3.2 v1.2.1 Brigade provides event-driven scripting of Kube... +brigade/brigade-github-app 0.4.1 v0.2.1 The Brigade GitHub App, an advanced gateway for... +brigade/brigade-github-oauth 0.2.0 v0.20.0 The legacy OAuth GitHub Gateway for Brigade +brigade/brigade-k8s-gateway 0.1.0 A Helm chart for Kubernetes +brigade/brigade-project 1.0.0 v1.0.0 Create a Brigade project +brigade/kashti 0.4.0 v0.4.0 A Helm chart for Kubernetes +``` + +Helm search utiliza un algoritmo de coincidencia de cadenas difusas, por lo +que puede escribir partes de palabras o frases: + +```console +$ helm search repo kash +NAME CHART VERSION APP VERSION DESCRIPTION +brigade/kashti 0.4.0 v0.4.0 A Helm chart for Kubernetes +``` + +El comando search es una buena forma de encontrar paquetes disponibles. Una vez que +haya encontrado el paquete que desea instalar, puede usar `helm install` para instalarlo. + +## 'helm install': Instalando un Package + +Para instalar un nuevo paquete, use el comando `helm install`. En su forma más simple, +se necesitan dos argumentos: un nombre de release que elijas y el nombre del chart +que deseas instalar. + +```console +$ helm install happy-panda bitnami/wordpress +NAME: happy-panda +LAST DEPLOYED: Tue Jan 26 10:27:17 2021 +NAMESPACE: default +STATUS: deployed +REVISION: 1 +NOTES: +** Please be patient while the chart is being deployed ** + +Your WordPress site can be accessed through the following DNS name from within your cluster: + + happy-panda-wordpress.default.svc.cluster.local (port 80) + +To access your WordPress site from outside the cluster follow the steps below: + +1. Get the WordPress URL by running these commands: + + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + Watch the status with: 'kubectl get svc --namespace default -w happy-panda-wordpress' + + export SERVICE_IP=$(kubectl get svc --namespace default happy-panda-wordpress --template "{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}") + echo "WordPress URL: http://$SERVICE_IP/" + echo "WordPress Admin URL: http://$SERVICE_IP/admin" + +2. Open a browser and access WordPress using the obtained URL. + +3. Login with the following credentials below to see your blog: + + echo Username: user + echo Password: $(kubectl get secret --namespace default happy-panda-wordpress -o jsonpath="{.data.wordpress-password}" | base64 --decode) +``` + +Ahora el chart `wordpress` está instalado. Tenga en cuenta que la instalación de +un chart crea un nuevo objeto _release_. El release anterior se llama `happy-panda`. +(Si desea que Helm genere un nombre por usted, omita el nombre del release y +use `--generate-name`). + +Durante la instalación, el cliente `helm` imprimirá información útil sobre qué +recursos se crearon, cuál es el estado del release y también si hay pasos de +configuración adicionales que puede o debe tomar. + +Helm no espera hasta que todos los recursos se estén ejecutando antes de salir. +Muchos charts requieren imágenes de Docker que tienen un tamaño superior a 600M +y pueden tardar mucho en instalarse en el clúster. + +Para realizar un seguimiento del estado de un release o para volver a leer la +información de configuración, puede utilizar `helm status`: + +```console +$ helm status happy-panda +NAME: happy-panda +LAST DEPLOYED: Tue Jan 26 10:27:17 2021 +NAMESPACE: default +STATUS: deployed +REVISION: 1 +NOTES: +** Please be patient while the chart is being deployed ** + +Your WordPress site can be accessed through the following DNS name from within your cluster: + + happy-panda-wordpress.default.svc.cluster.local (port 80) + +To access your WordPress site from outside the cluster follow the steps below: + +1. Get the WordPress URL by running these commands: + + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + Watch the status with: 'kubectl get svc --namespace default -w happy-panda-wordpress' + + export SERVICE_IP=$(kubectl get svc --namespace default happy-panda-wordpress --template "{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}") + echo "WordPress URL: http://$SERVICE_IP/" + echo "WordPress Admin URL: http://$SERVICE_IP/admin" + +2. Open a browser and access WordPress using the obtained URL. + +3. Login with the following credentials below to see your blog: + + echo Username: user + echo Password: $(kubectl get secret --namespace default happy-panda-wordpress -o jsonpath="{.data.wordpress-password}" | base64 --decode) +``` + +Lo anterior muestra el estado actual de su release. + +### Personalización del Charts antes de la instalación + +La instalación de la forma que tenemos aquí solo usará las opciones de +configuración predeterminadas para este chart. Muchas veces, querrás +personalizar el chart para usar tu configuración preferida. + +Para ver qué opciones se pueden configurar en un chart, use `helm show values`: + +```console +$ helm show values bitnami/wordpress +## Global Docker image parameters +## Please, note that this will override the image parameters, including dependencies, configured to use the global value +## Current available global Docker image parameters: imageRegistry and imagePullSecrets +## +# global: +# imageRegistry: myRegistryName +# imagePullSecrets: +# - myRegistryKeySecretName +# storageClass: myStorageClass + +## Bitnami WordPress image version +## ref: https://hub.docker.com/r/bitnami/wordpress/tags/ +## +image: + registry: docker.io + repository: bitnami/wordpress + tag: 5.6.0-debian-10-r35 + [..] +``` + +Luego, puedes sobreescribir cualquiera de estas configuraciones en un archivo +con formato YAML y luego pasar ese archivo durante la instalación. + +```console +$ echo '{mariadb.auth.database: user0db, mariadb.auth.username: user0}' > values.yaml +$ helm install -f values.yaml bitnami/wordpress --generate-name +``` + +Lo anterior creará un usuario MariaDB predeterminado con el nombre `user0`, +y otorgará a este usuario acceso a una base de datos `user0db` recién creada, +pero aceptará el resto de los valores predeterminados para ese chart. + +Hay dos formas de pasar los datos de configuración durante la instalación: + +- `--values` (o `-f`): Especifique un archivo YAML con sobreescrituras. Esto se + puede especificar varias veces y el archivo más a la derecha tendrá prioridad +- `--set`: Especifique sobreescrituras en la línea de comando. + +Si se utilizan ambos, los valores pasados en `--set` se fusionan con los pasados +en `--values` con mayor precedencia. Las sobreescrituras especificadas con `--set` +se guardan en un ConfigMap. Los valores que han sido pasados con `--set` se pueden +ver para un release determinado con `helm get values `. Los valores +que han sido pasados con `--set` se pueden borrar ejecutando `helm upgrade` +especificando `--reset-values`. + +#### El Formato y Limitaciones de `--set` + +La opción `--set` toma cero o más pares de nombre/valor. En su forma más simple, +se usa así: `--set name=value`. El equivalente YAML de eso es: + +```yaml +name: value +``` + +Múltiples valores son separados por el caracteres `,`. Entonces, `--set a=b,c=d` +se convierte en: + +```yaml +a: b +c: d +``` + +Expresiones más complejas son soportadas. Por ejemplo, `--set outer.inner=value` +es traducida a esto: + +```yaml +outer: + inner: value +``` + +Las lista pueden ser expresadas +Las listas se pueden expresar encerrando valores en `{` y `}`. Por ejemplo, +`--set name={a, b, c}` se traduce a: + +```yaml +name: + - a + - b + - c +``` + +A partir de Helm 2.5.0, es posible acceder a los elementos de la lista utilizando +una sintaxis de índice de arreglo. Por ejemplo, `--set servers[0].port=80` se +convierte en: + +```yaml +servers: + - port: 80 +``` + +De esta forma se pueden configurar varios valores. La línea `--set +servers[0].port=80,servers[0].host=example` se vuelve: + +```yaml +servers: + - port: 80 + host: example +``` + +A veces es necesario utilizar caracteres especiales en sus líneas `--set`. Puede +usar una barra invertida para escapar de los caracteres; `--set name=value1\,value2` +se convertirá en: + +```yaml +name: "value1,value2" +``` + +De manera similar, también puede escapar de las secuencias de puntos, lo que +puede resultar útil cuando los chats usan la función `toYaml` para analizar +anotaciones, etiquetas y selectores de nodos. La sintaxis para +`--set nodeSelector."kubernetes\.io/role"=master` se convertirá en: + +```yaml +nodeSelector: + kubernetes.io/role: master +``` + +Las estructuras de datos profundamente anidadas pueden ser difíciles de expresar +usando `--set`. Se alienta a los diseñadores de charts a considerar el uso de +`--set` al diseñar el formato de un archivo `values.yaml` +(lea más sobre [Archivos Values]({{< relref path="/docs/chart_template_guide/values_files/_index.md" lang="en" >}})). + +### Más Métodos de Instalación + +El comando `helm install` puede instalar desde varias fuentes: + +- Un repositorio de charts (como hemos visto anteriormente) +- Un archivo de chart local (`helm install foo foo-0.1.1.tgz`) +- Un directorio de chart descomprimido (`helm install foo path/to/foo`) +- Una URL completa (`helm install foo https://example.com/charts/foo-1.2.3.tgz`) + +## 'helm upgrade' y 'helm rollback': Actualizar un Release y Revertir un Fallo + +Cuando se lanza una nueva versión de un chart, o cuando desea cambiar la configuración +de su release, puede usar el comando `helm upgrade`. + +Una actualización toma un release existente y lo actualiza de acuerdo con la +información que proporcione. Dado que los charts de Kubernetes pueden ser grandes +y complejos, Helm intenta realizar la actualización menos invasiva. Solo actualizará +las cosas que hayan cambiado desde el último release. + +```console +$ helm upgrade -f panda.yaml happy-panda bitnami/wordpress +``` + +En el caso anterior, la versión `happy-panda` se actualiza con el mismo chart, +pero con un nuevo archivo YAML: + +```yaml +mariadb.auth.username: user1 +``` + +Podemos usar `helm get values` para ver si esa nueva configuración entró en vigencia. + +```console +$ helm get values happy-panda +mariadb: + auth: + username: user1 +``` + +El comando `helm get` es una herramienta útil para ver un release en el clúster. +Y como podemos ver arriba, muestra que nuestros nuevos valores de `panda.yaml` +se desplegaron en el clúster. + +Ahora, si algo no sale según lo planeado durante un release, es fácil retroceder +a un release anterior usando `helm rollback [RELEASE] [REVISION]`. + +```console +$ helm rollback happy-panda 1 +``` + +Lo anterior hace retroceder a nuestro release happy-panda a su primera versión de +release. La versión de release es una revisión incremental. Cada vez que ocurre +una instalación, actualización o reversión, el número de revisión se incrementa +en 1. El primer número de revisión es siempre 1. Y podemos usar +`helm history [RELEASE]` para ver los números de revisión de un determinado release. + +## Opciones Útiles para Instalar/Actualizar/Revertir + +Hay varias otras opciones útiles que puede especificar para personalizar el +comportamiento de Helm durante una instalación/actualización/reversión. Tenga en +cuenta que esta no es una lista completa de banderas del cliente. Para ver una +descripción de todos las banderas, simplemente ejecute `helm --help`. + +- `--timeout`: Un valor de [duración de Go](https://golang.org/pkg/time/#ParseDuration) + para esperar a que se completen los comandos de Kubernetes. El valor por + defecto es `5m0s`. +- `--wait`: Espera hasta que todos los pods estén listos, los PVC están vinculados, + los Depolyments tengan el mínimo (`Desired` menos `maxUnavailable`) Pods en estado + listo y los Services tengan una dirección IP (e Ingress si es un `LoadBalancer`) + antes de marcar el release como exitoso. Esperará tanto tiempo como el valor + `--timeout`. Si se alcanza el tiempo de espera, el release se marcará como + `FAILED` (Fallida). Nota: En escenarios donde el Deployment tiene `replicas` + configuradas en 1 y `maxUnavailable` no está configurado en 0 como parte de la + estrategia de actualización continua, `--wait` regresará tan pronto como haya + satisfecho la condición de mínimo de Pods listos. +- `--no-hooks`: Esto omite la ejecución de ganchos para el comando +- `--recreate-pods` (sólo disponible para `upgrade` y `rollback`): Esta bandera + hará que se vuelvan a crear todos los Pods (con la excepción de los Pods que + pertenecen a Deployments). (DEPRECADO en Helm 3) + +## 'helm uninstall': Desinstalar un Release + +Cuando sea el momento de desinstalar un release del clúster, use el comando +`helm uninstall`: + +```console +$ helm uninstall happy-panda +``` + +Esto eliminará el release del clúster. Puedes ver todas tus releases implementados +actualmente con el comando `helm list`: + +```console +$ helm list +NAME VERSION UPDATED STATUS CHART +inky-cat 1 Wed Sep 28 12:59:46 2016 DEPLOYED alpine-0.1.0 +``` + +En el resultado anterior, podemos ver que se desinstaló el release `happy-panda`. + +En versiones anteriores de Helm, cuando se eliminaba un release, quedaba un registro +de su eliminación. En Helm 3, la eliminación también elimina el registro del release. +Si desea mantener un registro de eliminación del release, use +`helm uninstall --keep-history`. El uso de `helm list --uninstalled` solo mostrará +los releases que se desinstalaron con la bandera `--keep-history`. + +La bandera `helm list --all` le mostrará todos los registros de releases que Helm +ha retenido, incluidos los registros de elementos fallidos o eliminados (si se +especificó `--keep-history`): + +```console +$ helm list --all +NAME VERSION UPDATED STATUS CHART +happy-panda 2 Wed Sep 28 12:47:54 2016 UNINSTALLED wordpress-10.4.5.6.0 +inky-cat 1 Wed Sep 28 12:59:46 2016 DEPLOYED alpine-0.1.0 +kindred-angelf 2 Tue Sep 27 16:16:10 2016 UNINSTALLED alpine-0.1.0 +``` + +Tenga en cuenta que debido a que los releases ahora se eliminan de forma +predeterminada, ya no es posible revertir un recurso desinstalado. + +## 'helm repo': Trabajar con Repositorios + +Helm 3 ya no viene con un repositorio de charts predeterminado. El grupo de +comandos `helm repo` proporciona comandos para agregar, enumerar y eliminar repositorios. + +Puede ver qué repositorios están configurados usando `helm repo list`: + +```console +$ helm repo list +NAME URL +stable https://charts.helm.sh/stable +mumoshu https://mumoshu.github.io/charts +``` + +Y se pueden agregar nuevos repositorios con `helm repo add`: + +```console +$ helm repo add dev https://example.com/dev-charts +``` + +Debido a que los repositorios de charts cambian con frecuencia, en cualquier +momento puede asegurarse de que su cliente Helm esté actualizado ejecutando +`helm repo update`. + +Los repositorios se pueden eliminar con `helm repo remove`. + +## Creación de sus Propios Charts + +La [Guía de Desarrollo de Chart]({{< relref path="/docs/topics/charts.md" lang="en" >}}) +explica cómo desarrollar sus propios charts. Pero puede comenzar rápidamente usando +el comando `helm create`: + +```console +$ helm create deis-workflow +Creating deis-workflow +``` + +Ahora hay un chart en `./deis-workflow`. Puede editarlo y crear sus propias plantillas. + +A medida que editas tu chart, puede validar que está bien formado ejecutando +`helm lint`. + +Cuando llegue el momento de empaquetar el chart para su distribución, puedes +ejecutar el comando `helm package`: + +```console +$ helm package deis-workflow +deis-workflow-0.1.0.tgz +``` + +Y este chart ahora se puede instalar fácilmente con `helm install`: + +```console +$ helm install deis-workflow ./deis-workflow-0.1.0.tgz +... +``` + +Los Charts empaquetados se pueden cargar en repositorios de charts. Consulte la +documentación de los [Repositorios de Charts de Helm]({{< ref path="/docs/topics/chart_repository.md" lang="en" >}}) +para obtener más detalles. + +## Conclusión + +Este capítulo ha cubierto los patrones de uso básicos del cliente `helm`, incluida +la búsqueda, instalación, actualización y desinstalación. También ha cubierto comandos +útiles de utilidad como `helm status`, `helm get` y `helm repo`. + +Para obtener más información sobre estos comandos, consulte la ayuda incorporada +de Helm: `helm help`. + +En el [capítulo siguiente]({{< relref path="/docs/howto/charts_tips_and_tricks/_index.md" lang="en" >}}), +analizamos el proceso de desarrollo de charts. diff --git a/content/es/docs/topics/_index.md b/content/es/docs/topics/_index.md new file mode 100644 index 0000000000..4acff27dc6 --- /dev/null +++ b/content/es/docs/topics/_index.md @@ -0,0 +1,9 @@ +--- +title: "Temas" +weight: 3 +--- + +# Guías de Temas + +Aquí encontrará una introducción a todas las partes clave de Helm que necesitará +o querrá saber. diff --git a/content/es/docs/topics/advanced.md b/content/es/docs/topics/advanced.md new file mode 100644 index 0000000000..f089687ec7 --- /dev/null +++ b/content/es/docs/topics/advanced.md @@ -0,0 +1,151 @@ +--- +title: "Técnicas avanzadas de Helm" +description: "Explica varias características avanzadas para usuarios de Helm" +aliases: ["/docs/advanced_helm_techniques"] +weight: 9 +--- + +Esta sección explica varias características avanzadas y técnicas para usar Helm. +La información de esta sección está pensada para "usuarios avanzados" de Helm que quieren personalización avanzada y manipulación de sus Charts y releases. Cada una de estas funciones avanzadas tiene sus propias desventajas y advertencias, por lo que cada una debe usarse con cuidado y con un profundo conocimiento de Helm. O en otras palabras, recuerde el [principio de Peter Parker](https://en.wikipedia.org/wiki/With_great_power_comes_great_responsibility) + +## Post renderizado +El post renderizado da a los instaladores de charts la capacidad de manipular manualmente, configurar y/o validar manifiestos renderizados antes de que sean instalados por Helm. Esto permite a los usuarios con necesidades de configuración avanzada poder usar herramientas como [`kustomize`](https://kustomize.io) para aplicar cambios de configuración sin necesidad de un fork a un chart público o requerir que los mantenedores de charts especifiquen hasta la última opción de configuración para una pieza de software. También hay casos de uso para inyectar herramientas comunes y side cars en entornos empresariales o análisis de los manifiestos antes del despliegue. + +### Prerrequisitos +- Helm 3.1+ + +### Uso +Un post-renderizador puede ser cualquier ejecutable que acepte manifiestos Kubernetes renderizados en STDIN y devuelva manifiestos Kubernetes válidos en STDOUT. Debe devolver un código de salida distinto de 0 en caso de fallo. Esta es la única "API" entre los dos componentes. Permite una gran flexibilidad en lo que puede hacer con su proceso de post renderizado. + +Un post renderizador puede ser usado con `install`, `upgrade`, y `template`. Para utilizar un post renderizador, utilice la flag `--post-renderer` con una ruta al ejecutable del renderizador que desea utilizar: + +```shell +$ helm install mychart stable/wordpress --post-renderer ./path/to/executable +``` + +Si la ruta no contiene ningún separador, buscará en $PATH, de lo contrario resolverá cualquier ruta relativa a una ruta absoluta. + +Si desea utilizar varios post-renderizadores, llámelos a todos desde un script o juntos en cualquier herramienta en binario. En bash, sería tan simple como `renderer1 | renderer2 | renderer3`. + +[Aquí](https://github.com/thomastaylor312/advanced-helm-demos/tree/master/post-render) tienes un ejemplo de uso de `kustomize` como post renderer. + +### Advertencias +Cuando se usan post renderers, hay varias cosas importantes a tener en cuenta. La más importante de ellas es que cuando se utiliza un post renderizador, todas las personas que modifican esa release **DEBEN** utilizar el mismo renderizador con el fin de tener construcciones repetibles. Esta característica está construida a propósito para permitir a cualquier usuario cambiar el renderizador utilizado o dejar de usarlo, pero esto debe hacerse deliberadamente para evitar la modificación accidental o pérdida de datos. + +Otra nota importante se refiere a la seguridad. Si estás utilizando un post-renderizador, debe asegurarse de que proviene de una fuente fiable. El uso de renderizadores no fiables o no verificados NO es recomendable, ya que tienen acceso completo a las plantillas renderizadas, que a menudo contienen secretos. + +### Renderizadores personalizados de entradas +El paso de post renderizado ofrece aún más flexibilidad cuando se utiliza en el Go SDK. Cualquier post renderizador sólo necesita implementar la siguiente interfaz Go: + +```go +type PostRenderer interface { + // Run expects a single buffer filled with Helm rendered manifests. It + // expects the modified results to be returned on a separate buffer or an + // error if there was an issue or failure while running the post render step + Run(renderedManifests *bytes.Buffer) (modifiedManifests *bytes.Buffer, err error) +} +``` + +Para más información sobre el uso del Go SDK, puede seguir en la siguiente [sección Go SDK](#go-sdk) + +## Go SDK +Helm 3 debutó con un Go SDK completamente reestructurado para una mejor experiencia cuando se construye software y herramientas que aprovechan Helm. La documentación completa se puede encontrar en [https://pkg.go.dev/helm.sh/helm/v3](https://pkg.go.dev/helm.sh/helm/v3), pero a continuación tienes una breve descripción de algunos de los paquetes más comunes y un ejemplo sencillo. + +### Resumen de paquetes +Esta es una lista de los paquetes más utilizados con una explicación sencilla sobre cada uno de ellos: + +- `pkg/action`: Contiene el "cliente" principal para realizar acciones de Helm. Este es el mismo paquete que usa el CLI. Si sólo necesitas ejecutar comandos básicos de Helm desde otro programa Go, este paquete es para ti. +- `pkg/{chart,chartutil}`: Métodos y ayudantes usados para cargar y manipular charts. +- `pkg/cli` y sus subpaquetes: Contiene todos los manejadores para las variables de entorno estándar de Helm y sus subpaquetes contienen el manejo de ficheros de salida y valores. +- `pkg/release`: Define el objeto `Release` y sus estados. + +Obviamente hay muchos más paquetes además de estos, ¡así que revise la documentación para más información! + +### Ejemplo simple +Este es un ejemplo simple para hacer un `helm list` usando el Go SDK: + +```go +package main + +import ( + "log" + "os" + + "helm.sh/helm/v3/pkg/action" + "helm.sh/helm/v3/pkg/cli" +) + +func main() { + settings := cli.New() + + actionConfig := new(action.Configuration) + // You can pass an empty string instead of settings.Namespace() to list + // all namespaces + if err := actionConfig.Init(settings.RESTClientGetter(), settings.Namespace(), os.Getenv("HELM_DRIVER"), log.Printf); err != nil { + log.Printf("%+v", err) + os.Exit(1) + } + + client := action.NewList(actionConfig) + // Only list deployed + client.Deployed = true + results, err := client.Run() + if err != nil { + log.Printf("%+v", err) + os.Exit(1) + } + + for _, rel := range results { + log.Printf("%+v", rel) + } +} +``` + +## Backends de almacenamiento +Helm 3 cambió el almacenamiento por defecto de la información de la release a Secrets en el namespace de la release. Helm 2 por defecto almacena la información de la release como ConfigMaps en el namespace de la instancia de Tiller. Las subsecciones siguientes muestran cómo configurar diferentes backends. Esta configuración se basa en la variable de entorno `HELM_DRIVER`. Se puede establecer a uno de los valores: +`[configmap, secret, sql]`. + +### Backend de almacenamiento ConfigMap +Para habilitar el backend ConfigMap, necesitarás establecer la variable de entorno `HELM_DRIVER` a `configmap`. + +Puedes establecerla en un shell de la siguiente manera: + +```shell +export HELM_DRIVER=configmap +``` + +Si quieres cambiar del backend por defecto al backend ConfigMap, tendrás que hacer la migración por tu cuenta. Puedes recuperar la información de la release con el siguiente comando: + +```shell +kubectl get secret --all-namespaces -l "owner=helm" +``` + +**NOTAS DE PRODUCCIÓN**: La información de lanzamiento incluye el contenido de charts y archivos de valores y, por lo tanto, podría contener datos confidenciales (como contraseñas, claves privadas y otras credenciales) que deben protegerse del acceso no autorizado. Al gestionar la autorización de Kubernetes, por ejemplo con [RBAC](https://kubernetes.io/docs/reference/access-authn-authz/rbac/), es posible conceder un acceso más amplio a los recursos ConfigMap, al tiempo que se restringe el acceso a los recursos Secret. Por ejemplo, el rol predeterminado [user-facing +role](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#user-facing-roles) +"view" otorga acceso a la mayoría de los recursos, pero no a los Secrets. Además, los secretos pueden configurarse para [almacenamiento cifrado](https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/). Por favor, tenlo en cuenta si decides cambiar al backend ConfigMap, ya que podría exponer los datos sensibles de tu aplicación. + +### backend de almacenamiento SQL +Existe un backend de almacenamiento SQL ***beta*** que almacena la información de liberación en una base de datos SQL. + +El uso de este tipo de almacenamiento es especialmente útil si la información de publicación pesa más de 1 MB (en cuyo caso, no puede almacenarse en ConfigMaps/Secrets debido a los límites internos del almacenamiento de valores clave etcd subyacente de Kubernetes). + +Para habilitar el backend SQL, tendrás que desplegar una base de datos SQL y establecer la variable de entorno `HELM_DRIVER` en `sql`. Los detalles de la base de datos se establecen con la variable de entorno `HELM_DRIVER_SQL_CONNECTION_STRING`. + +Puedes configurarlo en un shell de la siguiente manera: + +```shell +export HELM_DRIVER=sql +export HELM_DRIVER_SQL_CONNECTION_STRING=postgresql://helm-postgres:5432/helm?user=helm&password=changeme +``` + +> Nota: En este momento sólo soporta PostgreSQL. + +**NOTAS DE PRODUCCIÓN**: Se recomienda: +- Preparar la base de datos para la producción. Para PostgreSQL, consulta la documentación [Administración del servidor](https://www.postgresql.org/docs/12/admin.html) para más detalles +- Habilitar [gestión de permisos](/docs/permissions_sql_storage_backend/) para reflejar Kubernetes RBAC y obtener información sobre la versión + +Si desea cambiar del backend por defecto al backend SQL, tendrá que hacer la migración por su cuenta. Puede recuperar la información de lanzamiento con el siguiente comando: + +```shell +kubectl get secret --all-namespaces -l "owner=helm" +``` diff --git a/content/es/docs/topics/architecture.md b/content/es/docs/topics/architecture.md new file mode 100644 index 0000000000..1c44bb36ce --- /dev/null +++ b/content/es/docs/topics/architecture.md @@ -0,0 +1,55 @@ +--- +title: "Arquitectura Helm" +description: "Describe la arquitectura de Helm a alto nivel." +aliases: ["/docs/architecture/"] +weight: 8 +--- + +# Arquitectura de Helm + +Este documento describe la arquitectura de Helm a alto nivel. + +## El propósito de Helm + +Helm es una herramienta para gestionar paquetes Kubernetes llamados _charts_. Helm puede hacer lo siguiente: + +- Crear nuevos charts desde cero. +- Empaquetar charts en archivos de charts (tgz). +- Interactuar con repositorios de charts donde se almacenan charts. +- Instalar y desinstalar charts en un clúster Kubernetes existente. +- Gestionar el ciclo de lanzamiento de los charts instalados con Helm. + +Para Helm, hay tres conceptos importantes: + +1. El _chart_ es un conjunto de información necesaria para crear una instancia de una aplicación de aplicación Kubernetes. +2. El _config_ contiene información de configuración que puede fusionarse en un chart empaquetado para crear un objeto releaseable. +3. Un _release_ es una instancia en ejecución de un _chart_, combinado con un _config_ específico. + +## Componentes + +Helm es un ejecutable que se implementa en dos partes distintas: + +**El cliente Helm** es un cliente de línea de comandos para usuarios finales. El cliente es responsable de lo siguiente + +- Desarrollo de charts locales +- Gestión de repositorios +- Gestión de release +- Interfaz con la librería Helm + - Envío de charts para su instalación + - Solicitud de actualización o desinstalación de releases existentes + +**La biblioteca Helm** proporciona la lógica para ejecutar todas las operaciones de Helm. Interactúa con el servidor API de Kubernetes y proporciona la siguiente capacidad: + +- Combinación de una chart y una configuración para construir una release. +- Instalar charts en Kubernetes y proporcionar el objeto de release subsiguiente. +- Actualizar y desinstalar charts interactuando con Kubernetes. + +La biblioteca standalone de Helm encapsula la lógica de Helm para que pueda ser aprovechada por diferentes clientes. + +## Implementación + +El cliente y la biblioteca Helm están escritos en el lenguaje de programación Go. + +La librería utiliza la librería cliente de Kubernetes para comunicarse con Kubernetes. Actualmente, esa librería utiliza REST+JSON. Almacena información en Secrets ubicados dentro de Kubernetes. No necesita su propia base de datos. + +Los archivos de configuración se escriben, cuando es posible, en YAML. diff --git a/content/es/docs/topics/chart_tests.md b/content/es/docs/topics/chart_tests.md new file mode 100644 index 0000000000..676fff9eed --- /dev/null +++ b/content/es/docs/topics/chart_tests.md @@ -0,0 +1,143 @@ +--- +title: "Pruebas de Chart" +description: "Describe cómo ejecutar y probar sus charts." +weight: 3 +--- + +Un chart contiene varios recursos y componentes de Kubernetes que funcionan +juntos. Como autor de charts, es posible que desee escribir algunas pruebas +que validen que su chart funciona como se esperaba cuando se instala. Estas +pruebas también ayudan al consumidor de charts a comprender lo que se supone +que debe hacer su chart. + +Una **prueba** en un chart de helm vive en el directorio `templates/` y es una +definición de trabajo que especifica un contenedor con un comando dado para ejecutar. +El contenedor debe salir correctamente (salida 0) para que una prueba se considere +un éxito. La definición del trabajo debe contener la anotación del gancho de +prueba del timón: `helm.sh/hook: test`. + +Tenga en cuenta que hasta Helm v3, la definición de trabajo debía contener una +de estas anotaciones de gancho de prueba de helm: `helm.sh/hook: test-success` o +`helm.sh/hook: test-failure`. `helm.sh/hook: test-success` todavía se acepta como +una alternativa compatible con versiones anteriores de `helm.sh/hook: test`. + +Ejemplo de pruebas: + +- Valide que su configuración del archivo values.yaml se haya inyectado correctamente. + - Asegúrese de que su nombre de usuario y contraseña funcionen correctamente + - Asegúrese de que un nombre de usuario y una contraseña incorrectos no funcionen +- Afirmar que sus servicios están activos y con el balanceo de carga correcto +- etc. + +Puede ejecutar las pruebas predefinidas en Helm en un release usando el comando +`helm test `. Para un consumidor de charts, esta es una excelente +manera de verificar que su release de un chart (o aplicación) funcione como se esperaba. + +## Ejemplo de Prueba + +A continuación se muestra un ejemplo de la definición de un módulo de prueba Helm +en el [chart de bitnami wordpress](https://hub.helm.sh/charts/bitnami/wordpress). +Si descarga una copia del chart, puede ver los archivos localmente: + +```console +$ helm repo add bitnami https://charts.bitnami.com/bitnami +$ helm pull bitnami/wordpress --untar +``` + +``` +wordpress/ + Chart.yaml + README.md + values.yaml + charts/ + templates/ + templates/tests/test-mariadb-connection.yaml +``` + +En el archivo `wordpress/templates/tests/test-mariadb-connection.yaml`, verás +una prueba que puedes probar: + +```yaml +{{- if .Values.mariadb.enabled }} +apiVersion: v1 +kind: Pod +metadata: + name: "{{ .Release.Name }}-credentials-test" + annotations: + "helm.sh/hook": test +spec: + containers: + - name: {{ .Release.Name }}-credentials-test + image: {{ template "wordpress.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy | quote }} + {{- if .Values.securityContext.enabled }} + securityContext: + runAsUser: {{ .Values.securityContext.runAsUser }} + {{- end }} + env: + - name: MARIADB_HOST + value: {{ template "mariadb.fullname" . }} + - name: MARIADB_PORT + value: "3306" + - name: WORDPRESS_DATABASE_NAME + value: {{ default "" .Values.mariadb.db.name | quote }} + - name: WORDPRESS_DATABASE_USER + value: {{ default "" .Values.mariadb.db.user | quote }} + - name: WORDPRESS_DATABASE_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "mariadb.fullname" . }} + key: mariadb-password + command: + - /bin/bash + - -ec + - | + mysql --host=$MARIADB_HOST --port=$MARIADB_PORT --user=$WORDPRESS_DATABASE_USER --password=$WORDPRESS_DATABASE_PASSWORD + restartPolicy: Never +{{- end }} +``` + +## Pasos Para Ejecutar un Conjunto de Pruebas sobre un Release + +Primero, instale el chart en su clúster para crear un release. Puede que tenga +que esperar a que todos los Pods se activen; si prueba inmediatamente después de +esta instalación, es probable que muestre una falla transitiva y querrá volver +a probar. + +```console +$ helm install quirky-walrus wordpress --namespace default +$ helm test quirky-walrus +Pod quirky-walrus-credentials-test pending +Pod quirky-walrus-credentials-test pending +Pod quirky-walrus-credentials-test pending +Pod quirky-walrus-credentials-test succeeded +Pod quirky-walrus-mariadb-test-dqas5 pending +Pod quirky-walrus-mariadb-test-dqas5 pending +Pod quirky-walrus-mariadb-test-dqas5 pending +Pod quirky-walrus-mariadb-test-dqas5 pending +Pod quirky-walrus-mariadb-test-dqas5 succeeded +NAME: quirky-walrus +LAST DEPLOYED: Mon Jun 22 17:24:31 2020 +NAMESPACE: default +STATUS: deployed +REVISION: 1 +TEST SUITE: quirky-walrus-mariadb-test-dqas5 +Last Started: Mon Jun 22 17:27:19 2020 +Last Completed: Mon Jun 22 17:27:21 2020 +Phase: Succeeded +TEST SUITE: quirky-walrus-credentials-test +Last Started: Mon Jun 22 17:27:17 2020 +Last Completed: Mon Jun 22 17:27:19 2020 +Phase: Succeeded +[...] +``` + +## Notas + +- Puede definir tantas pruebas como desee en un solo archivo yaml o distribuirlas + en varios archivos yaml en el directorio `templates/`. +- Le invitamos a anidar su suite de pruebas en un directorio `tests/` como + `/templates/tests/` para mayor aislamiento. +- Una prueba es un [gancho de Helm](/docs/charts_hooks/), por lo que anotaciones + como `helm.sh/hook-weight` y `helm.sh/hook-delete-policy` pueden usarse con + recursos de prueba. diff --git a/content/es/docs/topics/charts.md b/content/es/docs/topics/charts.md new file mode 100644 index 0000000000..e5d678e7a0 --- /dev/null +++ b/content/es/docs/topics/charts.md @@ -0,0 +1,1152 @@ +--- +title: "Charts" +description: "Explica el formato del chart y proporciona una guía básica para crear charts con Helm." +weight: 1 +--- + +Helm usa un formato de empaquetado llamado _charts_. Un chart es una colección +de archivos que describen un conjunto relacionado de recursos de Kubernetes. Se +puede usar un solo chart para implementar algo simple, como un pod de Memcached, +o algo complejo, como una pila de aplicaciones web completa con servidores HTTP, +bases de datos, cachés, etc. + +Los charts se crean como archivos dispuestos en un árbol de directorios en +particular. Se pueden empaquetar en archivos versionados para ser desplegados. + +Si desea descargar y ver los archivos de un chart publicado, sin instalarlo, +puede hacerlo con `helm pull chartrepo/chartname`. + +Este documento explica el formato del chart y proporciona una guía básica para +crear charts con Helm. + +## La Estructura de Archivos del Chart + +Un chart se organiza como una colección de archivos dentro de un directorio. El +nombre del directorio es el nombre del chart (sin información de versiones). Por +lo tanto, un chart que describa WordPress se almacenaría en un directorio `wordpress/`. + +Dentro de este directorio, Helm esperará una estructura que coincida con esto: + +```text +wordpress/ + Chart.yaml # Un archivo YAML que contiene información sobre el chart. + LICENSE # OPCIONAL: Un archivo de texto sin formato que contiene la licencia del chart. + README.md # OPCIONAL: Un archivo README legible por humanos + values.yaml # Los valores de configuración predeterminados para este chart + values.schema.json # OPCIONAL: Un esquema JSON para imponer una estructura en el archivo values.yaml + charts/ # Un directorio que contiene los charts de los que depende este chart. + crds/ # Custom Resource Definitions + templates/ # Un directorio de plantillas que, cuando se combinan con valores, + # generarán archivos de manifiesto de Kubernetes válidos. + templates/NOTES.txt # OPCIONAL: Un archivo de texto sin formato que contiene breves notas de uso. +``` + +Helm se reserva el uso de los directorios `charts/`, `crds/` y `templates/`, y +de los nombres de archivo listados. Los demás archivos se dejarán como están. + +## El Archivo Chart.yaml + +El archivo `Chart.yaml` es requerido para un chart. Contiene los siguientes campos: + +```yaml +apiVersion: La versión de la API de chart (requerido) +name: El nombre del chart (requerido) +version: An versión SemVer 2 (requerido) +kubeVersion: Un rango SemVer de versiones compatibles de Kubernetes (opcional) +description: Una descripción de una sola frase de este proyecto (opcional) +type: El tipo de chart (opcional) +keywords: + - Una lista de palabras clave sobre este proyecto (opcional) +home: La URL de la página de inicio de este proyecto (opcional) +sources: + - Una lista de URL al código fuente de este proyecto (opcional) +dependencies: # Una lista de los requisitos del chart. (opcional) + - name: El nombre del chart (nginx) + version: La versión del chart ("1.2.3") + repository: (opcional) La URL del repositorio ("https://example.com/charts") o el alias ("@repo-name") + condition: (opcional) Una ruta yaml que se resuelve en un booleano, que se usa para habilitar/deshabilitar charts (e.g. subchart1.enabled) + tags: # (opcional) + - Las etiquetas se pueden usar para agrupar charts para habilitar/deshabilitar en for conjunta + import-values: # (opcional) + - ImportValues contiene la asignación de valores de origen a la clave principal que se va a importar. Cada elemento puede ser una cadena o un par de elementos hijo/padre de la sublista. + alias: (opcional) Alias que se utilizará para el chart. Útil cuando tiene que agregar el mismo chart varias veces +maintainers: # (opcional) + - name: El nombre de los mantenedores (requerido para cada mantenedor) + email: El correo electrónico de los mantenedores (opcional para cada mantenedor) + url: Una URL para el mantenedor (opcional para cada mantenedor) +icon: Una URL a una imagen SVG o PNG que se utilizará como icono (opcional). +appVersion: La versión de la aplicación que contiene. (opcional). No es necesario que sea SemVer. Se recomienda encerrar en comillas. +deprecated: Si este chart está obsoleto (optional, boolean) +annotations: + example: Una lista de anotaciones codificadas por nombre (opcional). +``` + +Otros campos se ignorarán silenciosamente. + +### Charts y Versionado + +Cada chart debe tener un número de versión. Una versión debe seguir el estándar +[SemVer 2](https://semver.org/spec/v2.0.0.html). A diferencia de Helm Classic, +Helm v2 y versiones posteriores utilizan números de versión como marcadores de +versión. Los paquetes en repositorios son identificado por el nombre más la versión. + +Por ejemplo, un chart `nginx` cuyo campo de versión se establece en +`versión: 1.2.3` se denominará: + +```text +nginx-1.2.3.tgz +``` + +También se admiten nombres SemVer 2 más complejos, como `versión: 1.2.3-alpha.1+ef365`. +Pero el sistema rechaza explícitamente los nombres que no son SemVer. + +**NOTA:** Mientras que Helm Classic y Deployment Manager estaban muy orientados +a GitHub cuando se trataba de charts, Helm v2 y versiones posteriores no dependen +ni requieren GitHub o incluso Git. En consecuencia, no utiliza Git SHA para el +control de versiones. + +El campo `version` dentro de `Chart.yaml` es utilizado por muchas de las +herramientas de Helm, incluida el CLI. Al generar un paquete, el comando +`helm package` usará la versión que encuentre en el archivo `Chart.yaml` +como un token en el nombre del paquete. El sistema asume que el número de versión +en el nombre del paquete del chart coincide con el número de versión en +`Chart.yaml`. El incumplimiento de esta suposición provocará un error. + +### El Campo `apiVersion` + +El campo `apiVersion` debe ser `v2` para los charts de Helm que requieren al menos +Helm 3. Los charts que admiten versiones anteriores de Helm tienen el campo `apiVersion` +establecido en `v1` y aún se pueden instalar en Helm 3. + +Cambios de `v1` a `v2`: + +- Un campo `dependencies` que define las dependencias del chart, que se encontraba + en el archivo `requirements.yaml` para los charts `v1` (consulte [Dependencias + del chart](#dependencias-del-chart)). +- El campo `type`, discriminando charts de aplicaciones y bibliotecas (consulte + [Tipos de Charts](#tipos-de-chart)). + +### El Campo `appVersion` + +Tenga en cuenta que el campo `appVersion` no está relacionado con el campo `version`. +Es una forma de especificar la versión de la aplicación. Por ejemplo, el chart +`drupal` puede tener una `appVersion: "8.2.1"`, lo que indica que la versión de +Drupal incluida en el chart (por defecto) es `8.2.1`. Este campo es informativo +y no tiene ningún impacto en los cálculos de la versión del chart. Se recomienda +encarecidamente envolver la versión entre comillas. Esto obliga al analizador YAML +a tratar el número de versión como una cadena. Dejarlo sin comillas puede provocar +problemas de análisis en algunos casos. Por ejemplo, YAML interpreta `1.0` como un +valor de punto flotante y un SHA de confirmación de git como `1234e10` como +notación científica. + +A partir de Helm v3.5.0, `helm create` envuelve el campo predeterminado +`appVersion` entre comillas. + +### El Campo `kubeVersion` + +El campo opcional `kubeVersion` puede definir restricciones de SemVer en las +versiones compatibles de Kubernetes. Helm validará las restricciones de versión +al instalar el chart y fallará si el clúster ejecuta una versión de Kubernetes +no compatible. + +Las restricciones de versión pueden comprender comparaciones AND separadas por +espacios, como + +```text +>= 1.13.0 < 1.15.0 +``` + +que pueden combinarse con el operador OR `||` como en el siguiente ejemplo + +```text +>= 1.13.0 < 1.14.0 || >= 1.14.1 < 1.15.0 +``` + +En este ejemplo, se excluye la versión `1.14.0`, lo que puede tener sentido si +se sabe que un error en ciertas versiones impide que el chart se ejecute correctamente. + +Aparte de las restricciones de versión que emplean operadores `=` `! =` `>` `<` +`> =` `<=`, se admiten las siguientes notaciones abreviadas + + * rangos de guiones para intervalos cerrados, donde `1.1 - 2.3.4` es equivalente + a `>= 1.1 <= 2.3.4`. + * comodines `x`, `X` y `*`, donde `1.2.x` es equivalente a `> = 1.2.0 <1.3.0`. + * rangos de tilde (se permiten cambios en la versión del parche), donde `~1.2.3` + es equivalente a `>= 1.2.3 < 1.3.0`. + * intervalos de intercalación (se permiten cambios menores en la versión), donde + `^1.2.3` es equivalente a `>= 1.2.3 < 2.0.0`. + +Para obtener una explicación detallada de las restricciones semver admitidas, consulte +[Masterminds/semver](https://github.com/Masterminds/semver). + +### Deprecando Charts + +Al administrar charts en un repositorio de charts, a veces es necesario deprecar +un chart. El campo opcional `deprecated` en `Chart.yaml` se puede utilizar para +marcar un chart como deprecado. Si la **última** versión de un chart en el +repositorio está marcada como deprecado, entonces el chart en su conjunto se +considera deprecado. El nombre del chart se puede reutilizar más tarde publicando +una versión más reciente que no esté marcada como deprecado. El flujo de trabajo +para charts obsoletos es: + +1. Actualizar el archivo `Chart.yaml` del chart para marcar el chart como deprecado, + subiendo la versión +2. Publicar la nueva versión del chart en el repositorio de charts. +3. Eliminar el chart del repositorio de origen (p. Ej., git) + +### Tipos de Chart + +El campo `type` define el tipo de chart. Hay dos tipos: `application` (aplicación) +y `library` (biblioteca). Aplicación es el tipo predeterminado y es el chart estándar +con el que se puede operar completamente. El [chart de biblioteca]({{< ref +"/docs/topics/library_charts.md" >}}) +proporciona utilidades o funciones para el generador de charts. Un chart de biblioteca +se diferencia de un chart de aplicación porque no se puede instalar y, por lo +general, no contiene ningún objeto de recurso. + +**Nota:** Se puede utilizar un chart de aplicación como chart de biblioteca. Esto +se habilita estableciendo el tipo en `library`. Luego, el chart se renderizará +como un chart de biblioteca en el que se pueden aprovechar todas las utilidades +y funciones. Todos los objetos de recursos del chart no se renderizarán. + +## Archivos LICENSE, README y NOTES del Chart + +Los Charts también pueden contener archivos que describen la instalación, +configuración, uso y licencia de un chart. + +Un archivo LICENSE es un archivo de texto sin formato que contiene la +[licencia](https://en.wikipedia.org/wiki/Software_license) para el chart. El +chart puede contener una licencia, ya que puede tener lógica de programación en +las plantillas y, por lo tanto, no sería solo configuración. También puede haber +licencias separadas para la aplicación instalada por el chart, si es necesario. + +Un archivo README para un chart debe tener el formato Markdown (README.md) y +generalmente debe contener: + +- Una descripción de la aplicación o servicio que proporciona el chart. +- Cualquier requisito previo o requisito para ejecutar el chart. +- Descripciones de opciones en `values.yaml` y valores predeterminados +- Cualquier otra información que pueda ser relevante para la instalación o + configuración del chart + +Cuando los concentradores y otras interfaces de usuario muestran detalles sobre +un chart, ese detalle se extrae del contenido del archivo `README.md`. + +El chart también puede contener un archivo corto de texto sin formato `templates/NOTES.txt` +que se imprimirá después de la instalación y al ver el estado de un release. Este +archivo se evalúa como una [plantilla](#plantillas-y-valores) y se puede utilizar +para mostrar notas de uso, próximos pasos o cualquier otra información relevante +para una publicación del chart. Por ejemplo, se pueden proporcionar instrucciones +para conectarse a una base de datos o acceder a una interfaz de usuario web. Dado +que este archivo se imprime en STDOUT cuando se ejecuta `helm install` o `helm status`, +se recomienda mantener breve el contenido y señalar el archivo README para obtener +más detalles. + +## Dependencias del Chart + +En Helm, un chart puede depender de cualquier número de otros charts. Estas +dependencias se pueden vincular dinámicamente usando el campo `dependencies` en +`Chart.yaml` o se pueden traer al directorio `charts/` y administrar manualmente. + +### Administrar Dependencias con el Campo `dependencies` + +Los chart requeridos por el chart actual se definen como una lista en el campo +`dependencias`. + +```yaml +dependencies: + - name: apache + version: 1.2.3 + repository: https://example.com/charts + - name: mysql + version: 3.2.1 + repository: https://another.example.com/charts +``` + +- El campo `name` es el nombre del chart que desea. +- El campo `version` es la versión del chart que desea. +- El campo `repository` es la URL completa del repositorio de charts. Tenga en + cuenta que usted también debe usar `helm repo add` para agregar ese repositorio + localmente. +- Puede usar el nombre del repositorio en lugar de la URL + +```console +$ helm repo add fantastic-charts https://fantastic-charts.storage.googleapis.com +``` + +```yaml +dependencies: + - name: awesomeness + version: 1.0.0 + repository: "@fantastic-charts" +``` + +Una vez que haya definido las dependencias, puede ejecutar `helm dependency update` +y usará su archivo de dependencia para descargar todos los chart especificados +en su directorio `charts/` por usted. + +```console +$ helm dep up foochart +Hang tight while we grab the latest from your chart repositories... +...Successfully got an update from the "local" chart repository +...Successfully got an update from the "stable" chart repository +...Successfully got an update from the "example" chart repository +...Successfully got an update from the "another" chart repository +Update Complete. Happy Helming! +Saving 2 charts +Downloading apache from repo https://example.com/charts +Downloading mysql from repo https://another.example.com/charts +``` + +Cuando `helm dependency update` recupera charts, los almacenará como archivos +de chart en el directorio `charts/`. Entonces, para el ejemplo anterior, uno +esperaría ver los siguientes archivos en el directorio de charts: + +```text +charts/ + apache-1.2.3.tgz + mysql-3.2.1.tgz +``` + +#### El Campo Alias en dependencies + +Además de los otros campos anteriores, cada entrada de requisitos puede contener +el campo opcional `alias`. + +Agregar un alias para un chart de dependencia colocaría un chart en dependencias +usando alias como nombre de la nueva dependencia. + +Se puede usar un `alias` en los casos en que necesiten acceder a un chart con otro +nombre(s). + +```yaml +# parentchart/Chart.yaml + +dependencies: + - name: subchart + repository: http://localhost:10191 + version: 0.1.0 + alias: new-subchart-1 + - name: subchart + repository: http://localhost:10191 + version: 0.1.0 + alias: new-subchart-2 + - name: subchart + repository: http://localhost:10191 + version: 0.1.0 +``` + +En el ejemplo anterior obtendremos 3 dependencias en total para `parentchart`: + +```text +subchart +new-subchart-1 +new-subchart-2 +``` + +La forma manual de lograr esto es copiando y pegando el mismo chart en el directorio +`charts/` varias veces con diferentes nombres. + +#### Campos de Tags and Condition en dependencies + +Además de los otros campos anteriores, cada entrada de requisitos puede contener +los campos opcionales `tags` y `condition`. + +Todos los charts se cargan de forma predeterminada. Si los campos `tags` o `condition` +están presentes, se evaluarán y usarán para controlar la carga de los charts a +los que se aplican. + +Condition: el campo condition contiene una o más rutas YAML (delimitadas por +comas). Si esta ruta existe en los valores del padre superior y se resuelve en +un valor booleano, el chart se habilitará o deshabilitará en función de ese +valor booleano. Solo se evalúa la primera ruta válida que se encuentra en la +lista y, si no existen rutas, la condición no tiene ningún efecto. + +Tags: el campo tag es una lista YAML de etiquetas para asociar con este chart. En +los valores padres superiores, todos los charts con etiquetas se pueden habilitar +o deshabilitar especificando la etiqueta y un valor booleano. + +```yaml +# parentchart/Chart.yaml + +dependencies: + - name: subchart1 + repository: http://localhost:10191 + version: 0.1.0 + condition: subchart1.enabled, global.subchart1.enabled + tags: + - front-end + - subchart1 + - name: subchart2 + repository: http://localhost:10191 + version: 0.1.0 + condition: subchart2.enabled,global.subchart2.enabled + tags: + - back-end + - subchart2 +``` + +```yaml +# parentchart/values.yaml + +subchart1: + enabled: true +tags: + front-end: false + back-end: true +``` + +En el ejemplo anterior, todos los chart con la etiqueta `front-end` estarían deshabilitados, +pero dado que la ruta `subchart1.enabled` se evalúa como 'true' en los valores del +padre, la condición anulará la etiqueta `front-end` y `subchart1` estará habilitado. + +Dado que `subchart2` está etiquetado con `back-end` y esa etiqueta se evalúa como +`true`, se habilitará `subchart2`. También tenga en cuenta que aunque `subchart2` +tiene una condición especificada, no hay una ruta y un valor correspondientes en +los valores de los padres, por lo que la condición no tiene ningún efecto. + +##### Utilizar el CLI con Etiquetas y Condiciones + +El parámetro `--set` se puede utilizar como de costumbre para alterar los valores +de tags (etiquetas) y conditions (condiciones). + +```console +helm install --set tags.front-end=true --set subchart2.enabled=false +``` + +##### Resolución de Etiquetas y Condiciones + +- **Las condiciones (cuando se establecen en values) siempre sobreescriben a + las etiquetas.** La primera ruta de condición que existe gana y las siguientes + para ese chart se ignoran. +- Las etiquetas se evalúan como 'si alguna de las etiquetas del chart es + verdadera, habilite el chart'. +- Los valores de etiquetas y condiciones deben establecerse en los values + del chart padre superior. +- The `tags:` key in values must be a top level key. Globals and nested `tags:` + tables are not currently supported. +- La clave `tags:` en values debe ser una clave de nivel superior. Los `tags:` + globales y anidados no son soportados actualmente. + +#### Importar values hijos via dependencias + +En algunos casos, es deseable permitir que los valores de un chart secundario +se propaguen al chart principal y se compartan como valores predeterminados +comunes. Un beneficio adicional de usar el formato de `exports` es que permitirá +que las herramientas futuras introspecten los valores configurables por el usuario. + +Las claves que contienen los valores que se van a importar se pueden especificar +en la sección `dependencies` del chart principal en el campo `import-values` +mediante una lista YAML. Cada elemento de la lista es una clave que se importa +del campo `exports` del chart secundario. + +Para importar valores que no están contenidos en la clave `exports`, use el +formato [hijo-padre](#usando-el-formato-padre-hijo). A continuación se describen +ejemplos de ambos formatos. + +##### Usando el formato de exportación + +If a child chart's `values.yaml` file contains an `exports` field at the root, +its contents may be imported directly into the parent's values by specifying the +keys to import as in the example below: + +Si el archivo `values.yaml` de un chart secundario contiene un campo de `exports` +en la raíz, su contenido se puede importar directamente a los values del padre +especificando las claves para importar como en el siguiente ejemplo: + +```yaml +# archivo Chart.yaml del padre + +dependencies: + - name: subchart + repository: http://localhost:10191 + version: 0.1.0 + import-values: + - data +``` + +```yaml +# archivo value.yaml del hijo + +exports: + data: + myint: 99 +``` + +Dado que estamos especificando la clave `data` en nuestra lista de importación, +Helm busca en el campo `exports` del chart secundario la clave `data` e importa +su contenido. + +El values final del padres contendrían nuestro campo exportado: + +```yaml +# values del padre + +myint: 99 +``` + +Tenga en cuenta que la clave principal `data` no está contenida en el values +final del padre. Si necesita especificar la clave principal, utilice el formato 'hijo-padre'. + +##### Usando el formato padre-hijo + +Para acceder a los valores que no están contenidos en la clave `exports` del values +del chart hijo, deberá especificar la clave de origen del values que se +importarán (`child`) y la ruta de destino en el values del chart padre (`parent`). + +The `import-values` in the example below instructs Helm to take any values found +at `child:` path and copy them to the parent's values at the path specified in +`parent:` + +Los `import-values` en el siguiente ejemplo le indican a Helm que tome los valores +encontrados en la ruta `child:` y los copie a los valores del padre en la ruta +especificada en `parent:` + +```yaml +# archivo Chart.yaml del padre + +dependencies: + - name: subchart1 + repository: http://localhost:10191 + version: 0.1.0 + ... + import-values: + - child: default.data + parent: myimports +``` + +En el ejemplo anterior, los valores que se encuentran en `default.data` en los +valores del subchart1 se importarán a la clave `myimports` en los values del chart +padre como se detalla a continuación: + +```yaml +# archivo values.yaml del padre + +myimports: + myint: 0 + mybool: false + mystring: "helm rocks!" +``` + +```yaml +# archivo values.yaml subchart1 + +default: + data: + myint: 999 + mybool: true +``` + +El values del chart padre resultantes sería: + +```yaml +# vales final del padre + +myimports: + myint: 999 + mybool: true + mystring: "helm rocks!" +``` + +El values final del padre ahora contienen los campos `myint` y `mybool` +importados de subchart1. + +### Administrar Dependencias manualmente a través del directorio `charts/` + +Si se desea más control sobre las dependencias, estas dependencias se pueden +expresar explícitamente copiando los charts de dependencias en el directorio +`charts/`. + +Una dependencia puede ser un archivo de chart (`foo-1.2.3.tgz`) o un directorio +de chart descomprimido. Pero su nombre no puede comenzar con `_` o `.`. El cargador +de chart ignora estos archivos. + +Por ejemplo, si el chart de WordPress depende del chart de Apache, el chart de Apache +(de la versión correcta) se proporciona en el directorio `charts/` del chart de WordPress: + +```yaml +wordpress: + Chart.yaml + # ... + charts/ + apache/ + Chart.yaml + # ... + mysql/ + Chart.yaml + # ... +``` + +El ejemplo anterior muestra cómo el chart de WordPress expresa su dependencia +de Apache y MySQL al incluir esos charts dentro de su directorio `charts /`. + +**CONSEJO:** _Para colocar una dependencia en su directorio `charts/`, use el +comando `helm pull`_ + +### Aspectos operativos del uso de dependencias + +Las secciones anteriores explican cómo especificar las dependencias del chart, +pero ¿cómo afecta esto a la instalación del chart usando `helm install` y +`helm upgrade`? + +Supongamos que un chart llamado "A" crea los siguientes objetos de Kubernetes + +- namespace "A-Namespace" +- statefulset "A-StatefulSet" +- service "A-Service" + +Además, A depende del chart B que crea los objetos + +- namespace "B-Namespace" +- replicaset "B-ReplicaSet" +- service "B-Service" + +Después de la instalación/actualización del chart A, se crea/modifica un único +release de Helm. El release creará/actualizará todos los objetos de Kubernetes +anteriores en el siguiente orden: + +- A-Namespace +- B-Namespace +- A-Service +- B-Service +- B-ReplicaSet +- A-StatefulSet + +Esto se debe a que cuando Helm instala/actualiza charts, los objetos de Kubernetes +de los charts y todas sus dependencias son + +- agregado en un solo conjunto; luego +- ordenados por tipo seguido de nombre; y entonces +- creado/actualizado en ese orden. + +Por lo tanto, se crea un único release con todos los objetos del charts y sus dependencias. + +El orden de instalación de los tipos de Kubernetes viene dado por la enumeración +InstallOrder en kind_sorter.go (ver [el archivo fuente de Helm](https://github.com/helm/helm/blob/484d43913f97292648c867b56768775a55e4bba6/pkg/releaseutil/kind_sorter.go)). + +## Plantillas y Valores + +Las plantillas de Charts de Helm están escritas en el [lenguaje Go +template](https://golang.org/pkg/text/template/), con la adición de unas 50 +funciones de plantilla complementarias [de la biblioteca Sprig](https://github.com/Masterminds/sprig) +y algunas otras [funciones especializadas]({{< ref "/docs/howto/charts_tips_and_tricks.md" >}}). + +Todos los archivos de plantilla se almacenan en la carpeta `templates/` de un chart. +Cuando Helm renderiza los charts, pasará todos los archivos de ese directorio a +través del motor de plantillas. + +Los valores de las plantillas se proporcionan de dos formas: + +- Los desarrolladores de charts pueden proporcionar un archivo llamado `values.yaml` + dentro de un chart. Este archivo puede contener valores predeterminados. +- Los usuarios de charts pueden proporcionar un archivo YAML que contenga valores. + Esto se puede proporcionar en la línea de comandos con `helm install`. + +Cuando un usuario proporciona valores personalizados, estos valores sobreescribirán +los valores del archivo `values.yaml` del chart. + +### Archivos de Plantillas + +Los archivos de plantilla siguen las convenciones estándar para escribir plantillas +de Go (consulte [la documentación del paquete de text/template de Go](https://golang.org/pkg/text/template/) +para obtener más detalles). Un archivo de plantilla de ejemplo podría verse así: + +```yaml +apiVersion: v1 +kind: ReplicationController +metadata: + name: deis-database + namespace: deis + labels: + app.kubernetes.io/managed-by: deis +spec: + replicas: 1 + selector: + app.kubernetes.io/name: deis-database + template: + metadata: + labels: + app.kubernetes.io/name: deis-database + spec: + serviceAccount: deis-database + containers: + - name: deis-database + image: {{ .Values.imageRegistry }}/postgres:{{ .Values.dockerTag }} + imagePullPolicy: {{ .Values.pullPolicy }} + ports: + - containerPort: 5432 + env: + - name: DATABASE_STORAGE + value: {{ default "minio" .Values.storage }} +``` + +El ejemplo anterior, basado ligeramente en +[https://github.com/deis/charts](https://github.com/deis/charts), es una plantilla +para un controlador de replicación de Kubernetes. Puede utilizar los siguientes +cuatro valores de plantilla (normalmente definidos en un archivo `values.yaml`): + +- `imageRegistry`: El registro de origen de la imagen de Docker. +- `dockerTag`: La etiqueta para image de Docker. +- `pullPolicy`: La política de pull de The Kubernetes. +- `storage`: El backend de almacenamiento, cuyo valor predeterminado es `"minio"` + +Todos estos valores los define el autor de la plantilla. Helm no requiere ni +dicta parámetros. + +Para ver muchos charts operativos, consulte [Artifact +Hub](https://artifacthub.io/packages/search?kind=0) de la CNCF. + +### Valores Predefinidos + +Los valores que se proporcionan a través de un archivo `values.yaml` (o mediante +la bandera `--set`) son accesibles desde el objeto `.Values` en una plantilla. +Pero hay otros datos predefinidos a los que puede acceder en tus plantillas. + +Los siguientes valores están predefinidos, están disponibles para todas las +plantillas y no se pueden sobreescribir. Como ocurre con todos los valores, +los nombres son _sensibles a mayúsculas y minúsculas_. + +- `Release.Name`: El nombre del release (no del chart) +- `Release.Namespace`: El namespace donde el chart fue deplegado. +- `Release.Service`: El servicio que realizó el lanzamiento. +- `Release.IsUpgrade`: Se establece en true (verdadero) si la operación actual + es una actualización o una reversión. +- `Release.IsInstall`: Se establece en true (verdadero) si la operación actual + es una instalación. +- `Chart`: El contenido de `Chart.yaml`. Por lo tanto, la versión del chart se + puede obtener como `Chart.Version` y los mantenedores están en `Chart.Maintainers`. +- `Files`: Un objeto similar a un mapa que contiene todos los archivos no especiales + del chart. Esto no le dará acceso a las plantillas, pero le dará acceso a archivos + adicionales que están presentes (a menos que estén excluidos usando `.helmignore`). + Se puede acceder al archivo usando `{{ index .Files "file.name" }}` o usando la + función `{{ .Files.Get name }}`. También puede acceder al contenido del archivo + como `[]byte` usando `{{ .Files.GetBytes }}` +- `Capabilities`: Un objeto similar a un mapa que contiene información sobre las + versiones de Kubernetes (`{{ .Capabilities.KubeVersion }}`) y las versiones + compatibles de la API de Kubernetes (`{{ .Capabilities.APIVersions.Has "batch/v1" }}`) + +**NOTA:** Se eliminarán todos los campos desconocidos de `Chart.yaml`. No serán +accesibles dentro del objeto `Chart`. Por lo tanto, `Chart.yaml` no se puede usar +para pasar datos estructurados arbitrariamente a la plantilla. Sin embargo, el +archivo de values se puede usar para eso. + +### Archivos values + +Teniendo en cuenta la plantilla de la sección anterior, un archivo `values.yaml` +que proporciona los valores necesarios se vería así: + +```yaml +imageRegistry: "quay.io/deis" +dockerTag: "latest" +pullPolicy: "Always" +storage: "s3" +``` + +Un archivo values tiene el formato YAML. Un chart puede incluir un archivo +`values.yaml` predeterminado. El comando de instalación de Helm permite al usuario +sobreescribir valores al proporcionar valores YAML adicionales: + +```console +$ helm install --generate-name --values=myvals.yaml wordpress +``` + +Cuando los valores se pasan de esta manera, se fusionarán en el archivo de values +predeterminado. Por ejemplo, considere un archivo `myvals.yaml` que se ve así: + +```yaml +storage: "gcs" +``` + +Cuando se fusiona con `values.yaml` del chart, el contenido generado resultante será: + +```yaml +imageRegistry: "quay.io/deis" +dockerTag: "latest" +pullPolicy: "Always" +storage: "gcs" +``` + +Tenga en cuenta que solo se sobreescribó el último campo. + +**NOTA:** El archivo de valores predeterminados incluido dentro de un chart +_debe_ llamarse `values.yaml`. Pero los archivos especificados en la línea de +comandos pueden tener cualquier nombre. + +**NOTA:** Si la marca `--set` se usa en `helm install` o `helm upgrade`, esos valores +simplemente se convierten a YAML en el lado del cliente. + +**NOTA:** Si existen entradas obligatorias en el archivo values, se pueden declarar +según sea necesario en la plantilla del chart mediante la [función +'required']({{< ref "/docs/howto/charts_tips_and_tricks.md" >}}) + +Cualquiera de estos valores es accesible dentro de las plantillas usando el objeto +`.Values`: + +```yaml +apiVersion: v1 +kind: ReplicationController +metadata: + name: deis-database + namespace: deis + labels: + app.kubernetes.io/managed-by: deis +spec: + replicas: 1 + selector: + app.kubernetes.io/name: deis-database + template: + metadata: + labels: + app.kubernetes.io/name: deis-database + spec: + serviceAccount: deis-database + containers: + - name: deis-database + image: {{ .Values.imageRegistry }}/postgres:{{ .Values.dockerTag }} + imagePullPolicy: {{ .Values.pullPolicy }} + ports: + - containerPort: 5432 + env: + - name: DATABASE_STORAGE + value: {{ default "minio" .Values.storage }} +``` + +### Alcance, Dependencias y Valores + +Los archivos de valores pueden declarar valores para el chart de nivel superior, +así como para cualquiera de los charts que se incluyen en el directorio `charts/` +de ese chart. O, para expresarlo de otra manera, un archivo de valores puede +proporcionar valores al chart, así como a cualquiera de sus dependencias. Por ejemplo, +el chart de demostración de WordPress anterior tiene tanto `mysql` como `apache` +como dependencias. El archivo de valores podría proporcionar valores a todos estos +componentes: + +```yaml +title: "My WordPress Site" # Enviado a la plantilla de WordPress + +mysql: + max_connections: 100 # Enviado a MySQL + password: "secret" + +apache: + port: 8080 # Enviado a Apache +``` + +Los charts de un nivel superior tienen acceso a todas las variables definidas a +nivel inferior. Entonces, el chart de WordPress puede acceder a la contraseña de +MySQL como `.Values.mysql.password`. Pero los charts de nivel inferior no pueden +acceder a elementos de los charts padres, por lo que MySQL no podrá acceder a la +propiedad `title`. Tampoco, en ese caso, puede acceder a `apache.port`. + +Los valores son dependientes del espacio de nombres, pero los espacios de nombres +se podan. Entonces, para el chart de WordPress, puede acceder al campo de contraseña +de MySQL como `.Values.mysql.password`. Pero para el chart MySQL, el alcance de +los valores se ha reducido y el prefijo del espacio de nombres eliminado, por lo +que verá el campo de contraseña simplemente como `.Values.password`. + +#### Valores Globales + +A partir de 2.0.0-Alpha.2, Helm admite un valor "global" especial. Considere esta +versión modificada del ejemplo anterior: + +```yaml +title: "My WordPress Site" # Enviado a la plantilla de WordPress + +global: + app: MyWordPress + +mysql: + max_connections: 100 # Enviado a MySQL + password: "secret" + +apache: + port: 8080 # Enviado a Apache +``` + +Lo anterior agrega una sección `global` con el valor `app: MyWordPress`. Este +valor está disponible para _todos_ los charts como `.Values.global.app`. + +Por ejemplo, las plantillas `mysql` pueden acceder a `app` como +`{{ .Values.global.app }}`, y también el chart `apache`. Efectivamente, el +archivo de valores anterior se regenera así: + +```yaml +title: "My WordPress Site" # Enviado a la plantilla de WordPress + +global: + app: MyWordPress + +mysql: + global: + app: MyWordPress + max_connections: 100 # Enviado a MySQL + password: "secret" + +apache: + global: + app: MyWordPress + port: 8080 # Enviado a Apache +``` + +Esto proporciona una forma de compartir una variable de nivel superior con todos +los sub-charts, lo cual es útil para cosas como establecer propiedades de `metadatos` +como etiquetas. + +Si un sub-chart declara una variable global, ese global se pasará _hacia abajo_ +(a los sub-charts del sub-chart), pero no _hacia arriba_ al chart padre. No hay +forma de que un sub-chart influya en los valores del chart padre. + +Además, las variables globales de los charts padres tienen prioridad sobre las +variables globales de los subcharts. + +### Archivos de Esquema + +A veces, un mantenedor de charts puede querer definir una estructura sobre sus +valores. Esto se puede hacer definiendo un esquema en el archivo +`values.schema.json`. Un esquema se representa como un +[JSON Schema](https://json-schema.org/). Podría verse algo como esto: + +```json +{ + "$schema": "https://json-schema.org/draft-07/schema#", + "properties": { + "image": { + "description": "Container Image", + "properties": { + "repo": { + "type": "string" + }, + "tag": { + "type": "string" + } + }, + "type": "object" + }, + "name": { + "description": "Service name", + "type": "string" + }, + "port": { + "description": "Port", + "minimum": 0, + "type": "integer" + }, + "protocol": { + "type": "string" + } + }, + "required": [ + "protocol", + "port" + ], + "title": "Values", + "type": "object" +} +``` + +Este esquema se aplicará a los valores para validarlo. La validación se produce +cuando se invoca cualquiera de los siguientes comandos: + +- `helm install` +- `helm upgrade` +- `helm lint` +- `helm template` + +Un ejemplo de un archivo `values.yaml` que cumpla con los requisitos de este +esquema podría verse así: + +```yaml +name: frontend +protocol: https +port: 443 +``` + +Tenga en cuenta que el esquema se aplica al objeto final `.Values`, y no solo al +archivo `values.yaml`. Esto significa que el siguiente archivo `yaml` es válido, +dado que el chart se instala con la opción `--set` apropiada que se muestra a continuación. + +```yaml +name: frontend +protocol: https +``` + +```console +helm install --set port=443 +``` + +Además, el objeto `.Values` final se verifica con *todos* los esquemas de los sub-charts. +Esto significa que un chart padre no puede eludir las restricciones de un sub-chart. +Esto también funciona al revés: si un subchart tiene un requisito que no se cumple +en el archivo `values.yaml` del subchart, el chart padre *debe* satisfacer esas +restricciones para ser válido. + +### Referencias + +Cuando se trata de escribir plantillas, valores y archivos de esquema, existen +varias referencias estándar que le ayudarán. + +- [Plantillas de Go](https://godoc.org/text/template) +- [Funciones extras de plantillas](https://godoc.org/github.com/Masterminds/sprig) +- [El formato YAML](https://yaml.org/spec/) +- [JSON Schema](https://json-schema.org/) + +## Custom Resource Definitions (CRDs) + +Kubernetes proporciona un mecanismo para declarar nuevos tipos de objetos de Kubernetes. +Con CustomResourceDefinitions (CRD), los desarrolladores de Kubernetes pueden declarar +tipos de recursos personalizados. + +En Helm 3, los CRD se tratan como un tipo especial de objeto. Se instalan antes +que el resto de la tabla y están sujetos a algunas limitaciones. + +Los archivos CRD YAML deben colocarse en el directorio `crds/` dentro de un chart. +Se pueden colocar varios CRD (separados por marcadores de inicio y finalización YAML) +en el mismo archivo. Helm intentará cargar _todos_ los archivos del directorio +CRD en Kubernetes. + +Los archivos CRD _no pueden tener plantilla_. Deben ser documentos YAML simples. + +Cuando Helm instala un nuevo chart, cargará los CRD, se detendrá hasta que el +servidor de API los ponga a disposición, y luego iniciará el motor de plantillas, +renderizará el resto del chart y lo cargará en Kubernetes. Debido a este orden, +la información de CRD está disponible en el objeto `.Capabilities` en las +plantillas de Helm, y las plantillas de Helm pueden crear nuevas instancias de +objetos que fueron declarados en los CRD. + +For example, if your chart had a CRD for `CronTab` in the `crds/` directory, you +may create instances of the `CronTab` kind in the `templates/` directory: + +Por ejemplo, si su chart tenía un CRD para `CronTab` en el directorio `crds/`, +puede crear instancias del tipo `CronTab` en el directorio `templates/`: + +```text +crontabs/ + Chart.yaml + crds/ + crontab.yaml + templates/ + mycrontab.yaml +``` + +El archivo `crontab.yaml` debe contener el CRD sin directivas de plantilla: + +```yaml +kind: CustomResourceDefinition +metadata: + name: crontabs.stable.example.com +spec: + group: stable.example.com + versions: + - name: v1 + served: true + storage: true + scope: Namespaced + names: + plural: crontabs + singular: crontab + kind: CronTab +``` + +Luego, la plantilla `mycrontab.yaml` puede crear un nuevo `CronTab` (usando +plantillas como de costumbre): + +```yaml +apiVersion: stable.example.com +kind: CronTab +metadata: + name: {{ .Values.name }} +spec: + # ... +``` + +Helm se asegurará de que el tipo `CronTab` se haya instalado y esté disponible +en el servidor API de Kubernetes antes de continuar con la instalación de las cosas +en `templates/`. + +### Limitaciones de los CRDs + +A diferencia de la mayoría de los objetos de Kubernetes, los CRD se instalan +globalmente. Por esa razón, Helm adopta un enfoque muy cauteloso en la gestión +de CRD. Los CRD están sujetos a las siguientes limitaciones: + +- Los CRD nunca se reinstalan. Si Helm determina que los CRD en el directorio `crds/` + ya están presentes (independientemente de la versión), Helm no intentará + instalarlos ni actualizarlos. +- Los CRD nunca se instalan en la actualización o reversión. Helm solo creará + CRD en las operaciones de instalación. +- Los CRD nunca se eliminan. La eliminación de un CRD elimina automáticamente + todo el contenido del CRD en todos los espacios de nombres del clúster. + En consecuencia, Helm no eliminará los CRD. + +Se recomienda a los operadores que deseen actualizar o eliminar CRD que lo hagan +manualmente y con mucho cuidado. + +## Uso de Helm para Administrar Charts + +La herramienta `helm` tiene varios comandos para trabajar con charts. + +Puede crear un nuevo chart para usted: + +```console +$ helm create mychart +Created mychart/ +``` + +Una vez que haya editado un chart, `helm` puede empaquetarlo en un archivo de +charts para usted: + +```console +$ helm package mychart +Archived mychart-0.1.-.tgz +``` + +También puede usar `helm` para ayudarlo a encontrar problemas con el formato o +la información de su chart: + +```console +$ helm lint mychart +No issues found +``` + +## Repositorios de Chart + +Un _repositorio de charts_ es un servidor HTTP que alberga uno o más charts +empaquetados. Si bien `helm` se puede usar para administrar directorios de +charts locales, cuando se trata de compartir charts, el mecanismo preferido es +un repositorio de charts. + +Cualquier servidor HTTP que pueda servir archivos YAML y tar y que pueda responder +solicitudes GET se puede utilizar como servidor de repositorio. El equipo de Helm +ha probado algunos servidores, incluido Google Cloud Storage con el modo de sitio +web habilitado y S3 con el modo de sitio web habilitado. + +Un repositorio se caracteriza principalmente por la presencia de un archivo +especial llamado `index.yaml` que tiene una lista de todos los paquetes +proporcionados por el repositorio, junto con metadatos que permiten recuperar y +verificar esos paquetes. + +En el lado del cliente, los repositorios se administran con los comandos `helm repo`. +Sin embargo, Helm no proporciona herramientas para cargar charts en servidores +de repositorios remotos. Esto se debe a que hacerlo agregaría requisitos +sustanciales a un servidor de implementación y, por lo tanto, elevaría la barrera +para configurar un repositorio. + +## Paquetes de Inicio de Charts + +El comando `helm create` toma una opción opcional `--starter` que le permite +especificar un "chart de inicio". + +Los paquetes de inicio son charts regulares, pero se encuentran en +`$XDG_DATA_HOME/helm/starters`. Como desarrollador de charts, puede crear charts +que estén diseñados específicamente para usarse como iniciadores. Dichos charts +deben diseñarse teniendo en cuenta las siguientes consideraciones: + +- El generador sobrescribirá el archivo `Chart.yaml`. +- Los usuarios esperarán modificar el contenido de dicho chart, por lo que la + documentación debe indicar cómo pueden hacerlo los usuarios. +- Todas las apariciones de `` serán reemplazadas con el nombre de chart + especificado para que los charts de inicio se puedan usar como plantillas. + +Actualmente, la única forma de agregar un chart a `$XDG_DATA_HOME/helm/starters` +es copiarlo manualmente allí. En la documentación de su chart, es posible que +desee explicar ese proceso. diff --git a/content/es/docs/topics/charts_hooks.md b/content/es/docs/topics/charts_hooks.md new file mode 100644 index 0000000000..e33720e670 --- /dev/null +++ b/content/es/docs/topics/charts_hooks.md @@ -0,0 +1,208 @@ +--- +title: "Ganchos de Chart" +description: "Describe como trabajar con ganchos de chart." +weight: 2 +--- + +Helm proporciona un mecanismo de _gancho_ (hook) que permite a los desarrolladores +de charts intervenir en determinados puntos del ciclo de vida de un release. Por +ejemplo, puede utilizar ganchos para: + +- Cargue un ConfigMap o un Secret durante la instalación antes de que se carguen + otros charts. +- Ejecute un trabajo para hacer una copia de seguridad de una base de datos antes + de instalar un nuevo chart y luego ejecute un segundo trabajo después de la + actualización para restaurar los datos. +- Ejecute un trabajo antes de eliminar un release para retirar un servicio de + rotación antes de eliminarlo. + +Los ganchos funcionan como plantillas normales, pero tienen anotaciones especiales +que hacen que Helm los utilice de manera diferente. En esta sección, cubrimos el +patrón de uso básico de los ganchos. + +## Los Ganchos Disponibles + +Se definen los siguientes ganchos: + +| Valor de Anotación | Descripción | +| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------ | +| `pre-install` | Se ejecuta después de que se procesan las plantillas, pero antes de que se creen recursos en Kubernetes | +| `post-install` | Se ejecuta después de que todos los recursos se cargan en Kubernetes | +| `pre-delete` | Ejecuta en una solicitud de eliminación antes de que se eliminen los recursos de Kubernetes | +| `post-delete` | Se ejecuta en una solicitud de eliminación después de que se hayan eliminado todos los recursos del release | +| `pre-upgrade` | Se ejecuta en una solicitud de actualización después de que se procesan las plantillas, pero antes de que se actualicen los recursos | +| `post-upgrade` | Se ejecuta en una solicitud de actualización después de que se hayan actualizado todos los recursos. | +| `pre-rollback` | Se ejecuta en una solicitud de reversión después de renderizar las plantillas, pero antes de revertir los recursos | +| `post-rollback` | Se ejecuta en una solicitud de reversión después de que se hayan modificado todos los recursos. | +| `test` | Se ejecuta cuando se invoca el subcomando Helm test ([ver documentos de prueba](/docs/chart_tests/)) | + +_Note que el gancho `crd-install` se ha eliminado a favor del directorio `crds/` +en Helm 3._ + +## Ganchos y el Ciclo de Vida del Release + +Los ganchos le brindan a usted, el desarrollador de charts, la oportunidad de +realizar operaciones en puntos estratégicos del ciclo de vida de un release. Por +ejemplo, considere el ciclo de vida de un `helm install`. De forma predeterminada, +el ciclo de vida se ve así: + +1. El usuario ejecuta `helm install foo` +2. La API de instalación de la biblioteca Helm se llama +3. Después de cierta verificación, la biblioteca renderiza las plantillas de `foo` +4. La biblioteca carga los recursos resultantes en Kubernetes. +5. La biblioteca devuelve el objeto de release (y otros datos) al cliente. +6. El cliente sale + +Helm define dos ganchos para el ciclo de vida de `install`: `pre-install` y +`post-install`. Si el desarrollador del chart `foo` implementa ambos ganchos, el +ciclo de vida se modifica así: + +1. El usuario ejecuta `helm install foo` +2. La API de instalación de la biblioteca Helm se llama +3. Se instalan los CRD del directorio `crds/` +4. Después de cierta verificación, la biblioteca renderiza las plantillas de `foo` +5. La biblioteca se prepara para ejecutar los ganchos de `pre-install` (cargando + los recursos del gancho en Kubernetes) +6. La biblioteca ordena los ganchos por peso (asignando un peso de 0 de forma predeterminada), + por tipo de recurso y finalmente por nombre en orden ascendente. +7. Luego, la biblioteca carga primero el gancho con el peso más bajo (negativo a + positivo) +8. La biblioteca espera hasta que el enlace esté "Listo" (excepto para los CRD). +9. La biblioteca carga los recursos resultantes en Kubernetes. Tenga en cuenta + que si la bandera `--wait` está configurada, la biblioteca esperará hasta que + todos los recursos estén en un estado "Listo" y no ejecutará el gancho `post-install` + hasta que estén listos. +10. La biblioteca ejecuta el gancho `post-install` (cargando recursos del gancho) +11. La biblioteca espera hasta que el gancho esté "Listo". +12. La biblioteca devuelve el objeto de release (y otros datos) al cliente. +13. El cliente sale + +¿Qué significa esperar hasta que un gancho esté listo? Esto depende del recurso +declarado en el gancho. Si el recurso es del tipo `Job` o `Pod`, Helm esperará +hasta que se complete correctamente. Y si el gancho falla, el release fallará. +Esta es una _operación de bloqueo_, por lo que el cliente de Helm se detendrá +mientras se ejecuta el Job. + +Para todos los demás tipos, tan pronto como Kubernetes marca el recurso como +cargado (agregado o actualizado), el recurso se considera "Listo". Cuando se +declaran muchos recursos en un gancho, los recursos se ejecutan en serie. Si +tienen pesos de gancho (ver más abajo), se ejecutan en orden ponderado. A partir +de Helm 3.2.0, los recursos de ganchos con el mismo peso se instalan en el mismo +orden que los recursos normales que no son de gancho. De lo contrario, el ordenamiento +no está garantizado. (En Helm 2.3.0 y posteriores, se ordenan alfabéticamente. +Sin embargo, ese comportamiento no se considera vinculante y podría cambiar en +el futuro). Se considera una buena práctica agregar un peso de gancho y establecerlo +en `0` si el peso no es importante. + +### Los recursos del gancho no se administran con los releases correspondientes + +Los recursos que crea un gancho no se rastrean ni administran actualmente como parte +del release. Una vez que Helm verifica que el gancho ha alcanzado su estado listo, +dejará solo el recurso de gancho. La recolección de basura de los recursos del +gancho cuando se elimina el release correspondiente se puede agregar a Helm 3 en +el futuro, por lo que cualquier recurso del gancho que nunca deba eliminarse debe +anotarse con `helm.sh/resource-policy: keep`. + +En términos prácticos, esto significa que si crea recursos en un gancho, no puede +confiar en `helm uninstall` para eliminar los recursos. Para destruir dichos +recursos, debe [agregar una anotación personalizada `helm.sh/hook-delete-policy`](#políticas-de-eliminación-de-ganchos) +al archivo de plantilla de gancho, o [establecer el campo de tiempo de vida (TTL) +de un recurso Job](https://kubernetes.io/docs/concepts/workloads/controllers/ttlafterfinished/). + +## Escribir un Gancho + +Los enganches son solo archivos de manifiesto de Kubernetes con anotaciones +especiales en la sección `metadata`. Debido a que son archivos de plantilla, +puede utilizar todas las funciones normales de la plantilla, incluida la lectura +de `.Values`, `.Release` y `.Template`. + +Por ejemplo, esta plantilla, almacenada en `templates/post-install-job.yaml`, +declara que un Job se ejecutará en `post-install`: + +```yaml +apiVersion: batch/v1 +kind: Job +metadata: + name: "{{ .Release.Name }}" + labels: + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + annotations: + # Esto es lo que define este recurso como un gancho. Sin esta línea, + # el trabajo se considera parte del release. + "helm.sh/hook": post-install + "helm.sh/hook-weight": "-5" + "helm.sh/hook-delete-policy": hook-succeeded +spec: + template: + metadata: + name: "{{ .Release.Name }}" + labels: + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + spec: + restartPolicy: Never + containers: + - name: post-install-job + image: "alpine:3.3" + command: ["/bin/sleep","{{ default "10" .Values.sleepyTime }}"] + +``` + +Lo que hace que esta plantilla sea un gancho es la anotación: + +```yaml +annotations: + "helm.sh/hook": post-install +``` + +Un recurso puede implementar varios ganchos: + +```yaml +annotations: + "helm.sh/hook": post-install,post-upgrade +``` + +De manera similar, no hay límite para la cantidad de recursos diferentes que +pueden implementar un gancho determinado. Por ejemplo, uno podría declarar tanto +un ConfigMap y un Secret como un gancho de pre-install. + +Cuando los sub-charts declaran ganchos, también se evalúan. No hay forma de que +un chart de nivel superior deshabilite los ganchos declarados por los sub-charts. + +Es posible definir un peso para un gancho que ayudará a construir un orden de +ejecución determinista. Los pesos se definen mediante la siguiente anotación: + +```yaml +annotations: + "helm.sh/hook-weight": "5" +``` + +Los pesos de los ganchos pueden ser números positivos o negativos, pero deben +representarse como cadenas. Cuando Helm inicia el ciclo de ejecución de ganchos +de un tipo particular, los ordenará en orden ascendente. + +### Políticas de eliminación de ganchos + +Es posible definir políticas que determinen cuándo eliminar los recursos de +gancho correspondientes. Las políticas de eliminación de ganchos se definen +mediante la siguiente anotación: + +```yaml +annotations: + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +``` + +Puede elegir uno o más valores de anotación definidos: + +| Valor de Anotación | Descripción | +| ---------------------- | ---------------------------------------------------------------------------------- | +| `before-hook-creation` | Elimina el recurso anterior antes de que se lance un nuevo gancho (predeterminado) | +| `hook-succeeded` | Eliminar el recurso después de que el gancho se ejecute correctamente | +| `hook-failed` | Eliminar el recurso si el gancho falló durante la ejecución | + +Si no se especifica ninguna anotación de política de eliminación de ganchos, el +comportamiento `before-hook-creation` se aplica de forma predeterminada. diff --git a/content/es/docs/topics/library_charts.md b/content/es/docs/topics/library_charts.md new file mode 100644 index 0000000000..05c05d4b23 --- /dev/null +++ b/content/es/docs/topics/library_charts.md @@ -0,0 +1,388 @@ +--- +title: "Charts de Bibliotecas" +description: "Explica los Charts de biblioteca y ejemplos de uso." +weight: 4 +--- + +Un chart de biblioteca es un tipo de [chart de Helm]({{< ref "/docs/topics/charts.md" >}}) +que define las primitivas o definiciones del chart que pueden ser compartidas por +las plantillas de Helm en otros charts. Esto permite a los usuarios compartir +fragmentos de código que se pueden reutilizar en los charts, evitando la repetición +y manteniendo los charts [DRY](https://es.wikipedia.org/wiki/No_te_repitas). + +El chart de biblioteca se introdujo en Helm 3 para reconocer formalmente +los charts comunes o auxiliares que han sido utilizados por los mantenedores +de charts desde Helm 2. Al incluirlo como un tipo de chart, proporciona: + +- Un medio para distinguir explícitamente entre charts comunes y de aplicación. +- Lógica para evitar la instalación de un chart común +- No se renderizan las plantillas en un chart común que puede contener un + artefacto de un release + +Un mantenedor de charts puede definir un chart común como un chart de biblioteca +y ahora estar seguro de que Helm manejará el chart de una manera estándar +consistente. También significa que las definiciones en un chart deaplicación +se pueden compartir cambiando el tipo de chart. + +## Crear un Chart de Biblioteca Simple + +Como se mencionó anteriormente, un chart de biblioteca es un tipo de [chart de +Helm]({{< ref "/docs/topics/charts.md" >}}). Esto significa que puede comenzar +creando un chart de estantería: + +```console +$ helm create mylibchart +Creating mylibchart +``` + +Primero eliminará todos los archivos en el directorio `templates` ya que crearemos +nuestras propias definiciones de plantillas en este ejemplo. + +```console +$ rm -rf mylibchart/templates/* +``` + +El archivo values tampoco será necesario. + +```console +$ rm -f mylibchart/values.yaml +``` + +Antes de pasar a la creación de código común, hagamos una revisión rápida de algunos +conceptos relevantes de Helm. Una [plantilla con nombre]({{< relref path="/docs/chart_template_guide/named_templates.md" lang="en" >}}) +(a veces llamada parcial o subplantilla) es simplemente una plantilla definida +dentro de un archivo, y se le dio un nombre. En el directorio `templates/`, no se +espera que ningún archivo que comience con un guión bajo (_) genere un archivo de +manifiesto de Kubernetes. Entonces, por convención, las plantillas auxiliares y +los parciales se colocan en archivos `_*.tpl` o `_*.yaml`. + +En este ejemplo, codificaremos un ConfigMap común que crea un recurso ConfigMap +vacío. Definiremos el ConfigMap común en el archivo `mylibchart/templates/_configmap.yaml` +de la siguiente manera: + +```yaml +{{- define "mylibchart.configmap.tpl" -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name | printf "%s-%s" .Chart.Name }} +data: {} +{{- end -}} +{{- define "mylibchart.configmap" -}} +{{- include "mylibchart.util.merge" (append . "mylibchart.configmap.tpl") -}} +{{- end -}} +``` + +La construcción ConfigMap se define en la plantilla denominada `mylibchart.configmap.tpl`. +Es un ConfigMap simple con un recurso vacío, `data`. Dentro de este archivo hay +otra plantilla con nombre llamada `mylibchart.configmap`. Esta plantilla con +nombre incluye otra plantilla con nombre `mylibchart.util.merge` que tomará 2 +plantillas con nombre como argumentos, la plantilla que llama a `mylibchart.configmap` +y `mylibchart.configmap.tpl`. + +La función auxiliar `mylibchart.util.merge` es una plantilla con nombre en +`mylibchart/templates/_util.yaml`. Es una utilidad útil de [El Chart de Utilidad +Común de Helm](#el-chart-de-utilidad-común-de-helm) porque combina las 2 plantillas +y sobreescribe cualquier parte común en ambas: + +```yaml +{{- /* +mylibchart.util.merge convinará dos plantillas YAML y generará el resultado. +Esto toma un arreglo de tres valores: +- el contexto superior +- el nombre de la plantilla de las anulaciones (destino) +- el nombre de la plantilla de la base (fuente) +*/}} +{{- define "mylibchart.util.merge" -}} +{{- $top := first . -}} +{{- $overrides := fromYaml (include (index . 1) $top) | default (dict ) -}} +{{- $tpl := fromYaml (include (index . 2) $top) | default (dict ) -}} +{{- toYaml (merge $overrides $tpl) -}} +{{- end -}} +``` + +Esto es importante cuando un chart desea utilizar un código común que necesita +personalizar con su configuración. + +Finalmente, cambiemos el tipo de chart a "biblioteca". Esto requiere editar +`mylibchart/Chart.yaml` de la siguiente manera: + +```yaml +apiVersion: v2 +name: mylibchart +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +# type: application +type: library + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application and it is recommended to use it with quotes. +appVersion: "1.16.0" +``` + +El chart de biblioteca ahora está listo para ser compartido y su definición de +ConfigMap para ser reutilizada. + +Antes de continuar, vale la pena verificar si Helm reconoce el chart como un chart +de biblioteca: + +```console +$ helm install mylibchart mylibchart/ +Error: library charts are not installable +``` + +## Utilice el Chart de Biblioteca Simple + +Es hora de usar el chart de biblioteca. Esto significa volver a crear un chart +de estantería: + +```console +$ helm create mychart +Creating mychart +``` + +Limpiemos los archivos de plantilla nuevamente, ya que solo queremos crear un ConfigMap: + +```console +$ rm -rf mychart/templates/* +``` + +Cuando queremos crear un ConfigMap simple en una plantilla de Helm, podría tener +un aspecto similar al siguiente: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name | printf "%s-%s" .Chart.Name }} +data: + myvalue: "Hello World" +``` + +Sin embargo, vamos a reutilizar el código común ya creado en `mylibchart`. El +ConfigMap se puede crear en el archivo `mychart/templates/configmap.yaml` de +la siguiente manera: + +```yaml +{{- include "mylibchart.configmap" (list . "mychart.configmap") -}} +{{- define "mychart.configmap" -}} +data: + myvalue: "Hello World" +{{- end -}} +``` + +Puede ver que simplifica el trabajo que tenemos que hacer al heredar la definición +común de ConfigMap que agrega propiedades estándar para ConfigMap. En nuestra +plantilla agregamos la configuración, en este caso la clave de datos `myvalue` +y su valor. La configuración sobreescribe el recurso vacío del ConfigMap común. +Esto es factible debido a la función auxiliar `mylibchart.util.merge` que +mencionamos en la sección anterior. + +Para poder usar el código común, necesitamos agregar `mylibchart` como dependencia. +Agregue lo siguiente al final del archivo `mychart/Chart.yaml`: + +```yaml +# Mi código común en el chart de mi biblioteca +dependencies: +- name: mylibchart + version: 0.1.0 + repository: file://../mylibchart +``` + +Esto incluye el chart de biblioteca como una dependencia dinámica del +sistema de archivos que se encuentra en la misma ruta principal que nuestro +chart de la aplicación. Como estamos incluyendo el chart de biblioteca como +una dependencia dinámica, necesitamos ejecutar la actualización de la dependencia +de helm. Helm copiará el chart de biblioteca en su directorio `charts/`. + +```console +$ helm dependency update mychart/ +Hang tight while we grab the latest from your chart repositories... +...Successfully got an update from the "stable" chart repository +Update Complete. ⎈Happy Helming!⎈ +Saving 1 charts +Deleting outdated charts +``` + +Ahora estamos listos para implementar nuestro chart. Antes de instalar, vale la +pena verificar primero la plantilla renderizada. + +```console +$ helm install mydemo mychart/ --debug --dry-run +install.go:159: [debug] Original chart version: "" +install.go:176: [debug] CHART PATH: /root/test/helm-charts/mychart + +NAME: mydemo +LAST DEPLOYED: Tue Mar 3 17:48:47 2020 +NAMESPACE: default +STATUS: pending-install +REVISION: 1 +TEST SUITE: None +USER-SUPPLIED VALUES: +{} + +COMPUTED VALUES: +affinity: {} +fullnameOverride: "" +image: + pullPolicy: IfNotPresent + repository: nginx +imagePullSecrets: [] +ingress: + annotations: {} + enabled: false + hosts: + - host: chart-example.local + paths: [] + tls: [] +mylibchart: + global: {} +nameOverride: "" +nodeSelector: {} +podSecurityContext: {} +replicaCount: 1 +resources: {} +securityContext: {} +service: + port: 80 + type: ClusterIP +serviceAccount: + annotations: {} + create: true + name: null +tolerations: [] + +HOOKS: +MANIFEST: +--- +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +data: + myvalue: Hello World +kind: ConfigMap +metadata: + labels: + app: mychart + chart: mychart-0.1.0 + release: mydemo + name: mychart-mydemo +``` + +Esto se parece al ConfigMap que queremos con la sobre escritura de datos de +`myvalue: Hello World`. Vamos a instalarlo: + +```console +$ helm install mydemo mychart/ +NAME: mydemo +LAST DEPLOYED: Tue Mar 3 17:52:40 2020 +NAMESPACE: default +STATUS: deployed +REVISION: 1 +TEST SUITE: None +``` + +Podemos recuperar el release y ver que se cargó la plantilla real. + +```console +$ helm get manifest mydemo +--- +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +data: + myvalue: Hello World +kind: ConfigMap +metadata: + labels: + app: mychart + chart: mychart-0.1.0 + release: mydemo + name: mychart-mydemo + ``` + +## El Chart de Utilidad Común de Helm + +Este [chart](https://github.com/helm/charts/tree/master/incubator/common) fue +el patrón original para los charts comunes. Proporciona utilidades que reflejan +las mejores prácticas del desarrollo de charts de Kubernetes. Lo mejor de todo +es que puede usarlo de inmediato cuando desarrolle sus charts para brindarle un +código compartido útil. + +Aquí hay una forma rápida de usarlo. Para más detalles, eche un vistazo al +[README](https://github.com/helm/charts/blob/master/incubator/common/README.md). + +Vuelva a crear un chart de estantería: + +```console +$ helm create demo +Creating demo +``` + +Usemos el código común del chart de ayuda. Primero, edite el deployment +`demo/templates/deployment.yaml` de la siguiente manera: + +```yaml +{{- template "common.deployment" (list . "demo.deployment") -}} +{{- define "demo.deployment" -}} +## Defina anulaciones para su deployment aquí, p. Ej. +spec: + replicas: {{ .Values.replicaCount }} +{{- end -}} +``` + +Y ahora el archivo de servicio, `demo/templates/service.yaml` como sigue: + +```yaml +{{- template "common.service" (list . "demo.service") -}} +{{- define "demo.service" -}} +## Defina aquí anulaciones para su Service, p. Ej. +# metadata: +# labels: +# custom: label +# spec: +# ports: +# - port: 8080 +{{- end -}} +``` + +Estas plantillas muestran cómo heredar el código común del chart auxiliar +simplifica su codificación hasta su configuración o personalización de los recursos. + +Para poder usar el código común, necesitamos agregar `common` como dependencia. +Agregue lo siguiente al final del archivo `demo/Chart.yaml`: + +```yaml +dependencies: +- name: common + version: "^0.0.5" + repository: "https://charts.helm.sh/incubator/" +``` + +Nota: Deberá agregar el repositorio `incubator` a la lista de repositorios +de Helm (`helm repo add`). + +Como estamos incluyendo el chart como una dependencia dinámica, necesitamos +ejecutar `helm dependency update`. Helm copiará el chart auxiliar en su directorio +`charts/`. + +Como el chart auxiliar está usando algunas construcciones de Helm 2, deberá agregar +lo siguiente a `demo/values.yaml` para permitir que se cargue la imagen `nginx` +ya que se actualizó en el chart de estantería de Helm 3: + +```yaml +image: + tag: 1.16.0 +``` + +Ahora está listo, ¡así que a desplegarlo! diff --git a/content/es/docs/topics/provenance.md b/content/es/docs/topics/provenance.md new file mode 100644 index 0000000000..1404723196 --- /dev/null +++ b/content/es/docs/topics/provenance.md @@ -0,0 +1,288 @@ +--- +title: "Procedencia e Integridad de Helm" +description: "Describe cómo verificar la integridad y el origen de un Chart." +weight: 5 +--- + +Helm tiene herramientas de procedencia que ayudan a los usuarios de charts a +verificar la integridad y el origen de un paquete. Utilizando herramientas estándar +de la industria basadas en PKI, GnuPG y administradores de paquetes muy respetados, +Helm puede generar y verificar archivos de firmas. + +## Descripción General + +La integridad se establece comparando un chart con un registro de procedencia. +Los registros de procedencia se almacenan en _archivos de procedencia_, que se +almacenan junto con un chart empaquetado. Por ejemplo, si un chart se llama +`myapp-1.2.3.tgz`, su archivo de procedencia será `myapp-1.2.3.tgz.prov`. + +Los archivos de procedencia se generan en el momento del empaquetado +(`helm package --sign ...`) y se pueden verificar mediante varios comandos, +en particular `helm install --verify`. + +## El Flujo de Trabajo + +Esta sección describe un flujo de trabajo potencial para utilizar los datos de +procedencia de manera eficaz. + +Requisitos previos: + +- Un par de claves PGP válido en formato binario (no blindado ASCII) +- La herramienta de línea de comandos `helm` +- Herramientas de línea de comandos de GnuPG (opcional) +- Herramientas de línea de comando de base de claves (opcional) + +**NOTA:** Si su clave privada PGP tiene una frase de contraseña, se le pedirá que +ingrese esa frase de contraseña para cualquier comando que admita la opción `--sign`. + +Crear un nuevo chart es el mismo que antes: + +```console +$ helm create mychart +Creating mychart +``` + +Una vez que esté listo para empaquetar, agregue la marca `--sign` a `helm package`. +Además, especifique el nombre con el que se conoce la clave de firma y el anillo +de claves que contiene la clave privada correspondiente: + +```console +$ helm package --sign --key 'John Smith' --keyring path/to/keyring.secret mychart +``` + +**Nota:** El valor del argumento `--key` debe ser una subcadena del `uid` de la +clave deseada (en la salida de `gpg --list-keys`), por ejemplo, el nombre o el +correo electrónico. **La huella _no_ se puede utilizar.** + +**SUGERENCIA:** para los usuarios de GnuPG, su anillo de claves secreto está en +`~ /.gnupg /secring.gpg`. Puede usar `gpg --list-secret-keys` para enumerar las +claves que tiene. + +**Advertencia:** GnuPG v2 almacena su llavero secreto usando un nuevo formato +`kbx` en la ubicación predeterminada `~/.gnupg/pubring.kbx`. Utilice el siguiente +comando para convertir su llavero al formato gpg heredado: + +```console +$ gpg --export-secret-keys >~/.gnupg/secring.gpg +``` + +En este punto, debería ver tanto `mychart-0.1.0.tgz` como `mychart-0.1.0.tgz.prov`. +Finalmente, ambos archivos deberían cargarse en el repositorio de charts que desee. + +Puede verificar un chart usando `helm verify`: + +```console +$ helm verify mychart-0.1.0.tgz +``` + +Una verificación fallida se ve así: + +```console +$ helm verify topchart-0.1.0.tgz +Error: sha256 sum does not match for topchart-0.1.0.tgz: "sha256:1939fbf7c1023d2f6b865d137bbb600e0c42061c3235528b1e8c82f4450c12a7" != "sha256:5a391a90de56778dd3274e47d789a2c84e0e106e1a37ef8cfa51fd60ac9e623a" +``` + +Para verificar durante una instalación, use la bandera `--verify`. + +```console +$ helm install --generate-name --verify mychart-0.1.0.tgz +``` + +Si el llavero que contiene la clave pública asociada con el chart firmado no se +encuentra en la ubicación predeterminada, es posible que deba señalar el llavero +con `--keyring PATH` como en el ejemplo de `helm package`. + +Si la verificación falla, la instalación se cancelará antes de que el chart sea renderizado. + +### Usando las credenciales de Keybase.io + +El servicio [Keybase.io](https://keybase.io) facilita el establecimiento de una +cadena de confianza para una identidad criptográfica. Las credenciales de la base +de claves se pueden utilizar para firmar charts. + +Requisitos previos: + +- Una cuenta Keybase.io configurada +- GnuPG instalado localmente +- La CLI `keybase` instalada localmente + +#### Firma de paquetes + +El primer paso es importar las claves de la base de claves a su anillo de +claves GnuPG local: + +```console +$ keybase pgp export -s | gpg --import +``` + +Esto convertirá su clave de Keybase al formato OpenPGP, y luego la importará +localmente en su archivo `~/.gnupg/secring.gpg`. + +Puede comprobarlo ejecutando `gpg --list-secret-keys`. + +```console +$ gpg --list-secret-keys +/Users/mattbutcher/.gnupg/secring.gpg +------------------------------------- +sec 2048R/1FC18762 2016-07-25 +uid technosophos (keybase.io/technosophos) +ssb 2048R/D125E546 2016-07-25 +``` + +Tenga en cuenta que su clave secreta tendrá una cadena de identificación: + +``` +technosophos (keybase.io/technosophos) +``` + +Ese es el nombre completo de su clave. + +A continuación, puede empaquetar y firmar un chart con `helm package`. Asegúrese +de utilizar al menos parte de esa cadena de nombre en `--key`. + +```console +$ helm package --sign --key technosophos --keyring ~/.gnupg/secring.gpg mychart +``` + +Como resultado, el comando `package` debería producir tanto un archivo +`.tgz` como un archivo `.tgz.prov`. + +#### Verificación de paquetes + +También puede utilizar una técnica similar para verificar un chart firmado por +la clave de Keybase de otra persona. Supongamos que desea verificar un paquete +firmado por `keybase.io/technosophos`. Para hacer esto, use la herramienta `keybase`: + +```console +$ keybase follow technosophos +$ keybase pgp pull +``` + +El primer comando de arriba rastrea al usuario `technosophos`. A continuación, +`keybase pgp pull` descarga las claves OpenPGP de todas las cuentas que sigue, +colocándolas en su anillo de claves GnuPG (`~/.gnupg/pubring.gpg`). + +En este punto, ahora puede usar `helm verify` o cualquiera de los comandos con +una marca `--verify`: + +```console +$ helm verify somechart-1.2.3.tgz +``` + +### Razones por las que un chart no puede verificar + +Éstas son razones comunes de falla. + +- Falta el archivo `.prov` o está dañado. Esto indica que algo está mal configurado + o que el responsable de mantenimiento original no creó un archivo de procedencia. +- La clave utilizada para firmar el archivo no está en su llavero. Esto indica que + la entidad que firmó el chart no es alguien a quien ya haya señalado que confía. +- Falló la verificación del archivo `.prov`. Esto indica que algo anda mal con + el chart o con los datos de procedencia. +- Los hash de archivo en el archivo de procedencia no coinciden con el hash del + archivo de almacenamiento. Esto indica que el archivo ha sido manipulado. + +Si una verificación falla, hay motivos para desconfiar del paquete. + +## El Archivo de Procedencia + +El archivo de procedencia contiene un archivo YAML de un chart más varios datos +de verificación. Los archivos de procedencia están diseñados para generarse automáticamente. + +Se agregan los siguientes datos de procedencia: + +- El archivo de chart (`Chart.yaml`) se incluye para que tanto los humanos como + las herramientas puedan ver fácilmente el contenido del chart. +- La firma (SHA256, al igual que Docker) del paquete de charts (el archivo `.tgz`) + está incluida y puede usarse para verificar la integridad del paquete de charts. +- Todo el cuerpo está firmado utilizando el algoritmo utilizado por OpenPGP + (consulte [Keybase.io](https://keybase.io) para conocer una forma emergente de + facilitar la firma y verificación de cifrado). + +La combinación de esto brinda a los usuarios las siguientes garantías: + +- El paquete en sí no ha sido manipulado (suma de comprobación del paquete `.tgz`). +- Se conoce la entidad que liberó este paquete (a través de la firma GnuPG/PGP). + +El formato del archivo se parece a esto: + +``` +Hash: SHA512 + +apiVersion: v2 +appVersion: "1.16.0" +description: Sample chart +name: mychart +type: application +version: 0.1.0 + +... +files: + mychart-0.1.0.tgz: sha256:d31d2f08b885ec696c37c7f7ef106709aaf5e8575b6d3dc5d52112ed29a9cb92 +-----BEGIN PGP SIGNATURE----- + +wsBcBAEBCgAQBQJdy0ReCRCEO7+YH8GHYgAAfhUIADx3pHHLLINv0MFkiEYpX/Kd +nvHFBNps7hXqSocsg0a9Fi1LRAc3OpVh3knjPfHNGOy8+xOdhbqpdnB+5ty8YopI +mYMWp6cP/Mwpkt7/gP1ecWFMevicbaFH5AmJCBihBaKJE4R1IX49/wTIaLKiWkv2 +cR64bmZruQPSW83UTNULtdD7kuTZXeAdTMjAK0NECsCz9/eK5AFggP4CDf7r2zNi +hZsNrzloIlBZlGGns6mUOTO42J/+JojnOLIhI3Psd0HBD2bTlsm/rSfty4yZUs7D +qtgooNdohoyGSzR5oapd7fEvauRQswJxOA0m0V+u9/eyLR0+JcYB8Udi1prnWf8= +=aHfz +-----END PGP SIGNATURE----- +``` + +Tenga en cuenta que la sección YAML contiene dos documentos (separados por `...\n`). +El primer archivo es el contenido de `Chart.yaml`. El segundo son las sumas de +comprobación, un mapa de nombres de archivo a resúmenes SHA-256 del contenido de +ese archivo en el momento del empaquetado. + +El bloque de firma es una firma PGP estándar, que proporciona [resistencia a la +manipulación(https://www.rossde.com/PGP/pgp_signatures.html). + +## Repositorios de Charts + +Los repositorios de charts sirven como una colección centralizada de charts de Helm. + +Los repositorios de charts deben permitir la entrega de archivos de procedencia +a través de HTTP a través de una solicitud específica, y deben hacerlos disponibles +en la misma ruta de URI que el chart. + +Por ejemplo, si la URL base de un paquete es +`https://example.com/charts/mychart-1.2.3.tgz`, el archivo de procedencia, +si existe, DEBE ser accesible en `https://example.com/charts/mychart-1.2.3.tgz.prov`. + +Desde la perspectiva del usuario final, `helm install --verify myrepo/mychart-1.2.3` +debería resultar en la descarga tanto del chart como del archivo de procedencia +sin configuración o acción adicional del usuario. + +## Establecimiento de Autoridad y Autenticidad + +Cuando se trata de sistemas de cadena de confianza, es importante poder establecer +la autoridad de un firmante. O, para decirlo claramente, el sistema anterior depende +del hecho de que usted confía en la persona que firmó el chart. Eso, a su vez, +significa que debe confiar en la clave pública del firmante. + +Una de las decisiones de diseño de Helm ha sido que el proyecto Helm no se +insertará en la cadena de confianza como parte necesaria. No queremos ser +"la autoridad de certificación" para todos los firmantes de charts. En cambio, +estamos a favor de un modelo descentralizado, que es parte de la razón por la +que elegimos OpenPGP como nuestra tecnología fundamental. Entonces, cuando se +trata de establecer la autoridad, hemos dejado este paso más o menos indefinido +en Helm 2 (una decisión llevada a cabo en Helm 3). + +Sin embargo, tenemos algunos consejos y recomendaciones para aquellos interesados +en utilizar el sistema de procedencia: + +- La plataforma [Keybase](https://keybase.io) proporciona un repositorio público + centralizado para información de confianza. + - Puede utilizar Keybase para almacenar sus claves o para obtener las claves + públicas de otros. + - Keybase también tiene documentación fabulosa disponible + - Si bien no lo hemos probado, la función de "sitio web seguro" de Keybase + podría usarse para servir charts de Helm. + - La idea básica es que un "revisor de charts" oficial firme los charts con + su clave, y el archivo de procedencia resultante se carga en el repositorio + de charts. + - Se ha trabajado en la idea de que se pueda incluir una lista de claves de + firmas válidas en el archivo `index.yaml` de un repositorio. + diff --git a/content/fr/docs/_index.md b/content/fr/docs/_index.md new file mode 100644 index 0000000000..31a099e1bb --- /dev/null +++ b/content/fr/docs/_index.md @@ -0,0 +1,18 @@ +--- +title: "Accueil Documentations" +description: "Tout ce que vous devez savoir sur l'organisation de la documentation." +--- + +# Bienvenue + +Bienvenue dans la documentation de [Helm](https://helm.sh/). Helm est le manageur de paquet pour Kubernetes. Les informations générales détaillées sont disponnibles ici : [CNCF Helm Project Journey report](https://www.cncf.io/cncf-helm-project-journey/). + +# Comment la documentation est organisée + +Helm a beaucoup de documentation. Voici un aperçu de son organisation +pour vous aider à chercher: + +- [Les Tutoriels](intro) vous guide à travers une série d'étapes pour créer votre premier tableau Helm. Commencez ici si vous êtes nouveau dans Helm. +- [Les Guides thématiques](topics) abordent des sujets et concepts clés à un niveau assez élevé et fournissent des informations de base et des explications utiles. +- [Le Guide de la communauté](community) aborde des sujets centrés sur la communauté de Helm. Rendez-vous dessus si vous souhaitez en savoir plus sur le processus de développement de Helm en lui-même et comment vous pouvez y contribuer. +- [Les Guides pratiques](howto) sont des recettes. Ils vous guident à travers les étapes qui permettent de résoudre les problèmes clés et les cas d’utilisations. Ils sont plus avancés que les tutoriels et nécessitent une certaine connaissance du fonctionnement de Helm. \ No newline at end of file diff --git a/content/fr/docs/community/_index.md b/content/fr/docs/community/_index.md new file mode 100644 index 0000000000..e78fb770a8 --- /dev/null +++ b/content/fr/docs/community/_index.md @@ -0,0 +1,9 @@ +--- +title: "Communauté" +weight: 7 +--- + +# Guide communautaire + +Apprenez ici l'ensemble des processus de développement du projet Helm et comment +vous pouvez y contribuer. diff --git a/content/fr/docs/helm/_index.md b/content/fr/docs/helm/_index.md new file mode 100644 index 0000000000..def77c6e5f --- /dev/null +++ b/content/fr/docs/helm/_index.md @@ -0,0 +1,10 @@ +--- +title: "Commandes Helm" +description: "Documentation de toute la liste des commandes CLI helm." +weight: 6 +slug: helm +--- + +# Commandes Helm + +Vous trouverez ici la liste des commandes CLI helm, avec l'aide sur leur utilisation diff --git a/content/fr/docs/helm/helm.md b/content/fr/docs/helm/helm.md new file mode 100644 index 0000000000..0a6d5e65a4 --- /dev/null +++ b/content/fr/docs/helm/helm.md @@ -0,0 +1,84 @@ +--- +title: "Helm" +--- + +## helm + +Helm, Le gestionnaire de paquets pour Kubernetes + +### Synopsis + +Le gestionnaire de paquets pour Kubernetes + +Actions courrantes de Helm: + +- helm search: cherche des charts installées dans Kubernetes +- helm pull: télécharge l'archive chart dans le répertoire courant +- helm install: installe le chart dans le namespace du cluster Kubernetes +- helm list: liste les versions de charts installées dans le namespace du cluster Kubernetes + +Variables d'environnement: + +| Nom | Description | +|------------------------------------|---------------------------------------------------------------------------------------------------| +| $HELM_CACHE_HOME | définit un répertoire alternatif pour stocker les fichiers du cache. | +| $HELM_CONFIG_HOME | définit un répertoire alternatif pour stocker les fichiers de configuration. | +| $HELM_DATA_HOME | définit un répertoire alternatif pour stocker les fichiers de données. | +| $HELM_DEBUG | indique si Helm tourne en mode Debug | +| $HELM_DRIVER | définit le driver du stockage du backend. Il peut être: configmap, secret, memory, sql. | +| $HELM_DRIVER_SQL_CONNECTION_STRING | définit la chaine de caractères que le driver de stockage SQL doit utiliser. | +| $HELM_MAX_HISTORY | définit le nombre maximum de versions helm conservées. | +| $HELM_NAMESPACE | définit le namespace des operations helm. | +| $HELM_NO_PLUGINS | désactive les plugins. Positionne HELM_NO_PLUGINS=1 pour désactiver les plugins. | +| $HELM_PLUGINS | définit le chemin du répertoire de plugins. | +| $HELM_REGISTRY_CONFIG | définit le chemin du registre de configuration. | +| $HELM_REPOSITORY_CACHE | définit le chemin du repertoire cache. | +| $HELM_REPOSITORY_CONFIG | définit le chemin du registre de configuration. | +| $KUBECONFIG | définit un chemin alternatif de configuration de kubernetes (default "~/.kube/config") | +| $HELM_KUBEAPISERVER | définit le point d'entrée API du serveur Kubernetes pour authentification | +| $HELM_KUBECAFILE | définit le fichier de certificat d'autorité de Kubernetes. | +| $HELM_KUBEASGROUPS | définit le groupe à utiliser pour anonymisation en utilisant une liste csv. | +| $HELM_KUBEASUSER | définit le nom à utiliser pour anonymiser l'operation. | +| $HELM_KUBECONTEXT | définit le nom du contexte kubeconfig. | +| $HELM_KUBETOKEN | définit le canal KubeToken utilisé pour authentification. | +| $HELM_KUBEINSECURE_SKIP_TLS_VERIFY | indique si la vérification du certificat de l'API serveur ne doit pas être faite. (peu sûr) | +| $HELM_KUBETLS_SERVER_NAME | définit le nom du serveur utilisé pour valider le certificat de l'API Kubernetes. | +| $HELM_BURST_LIMIT | définit la limite burst au cas où le serveur contient plusieurs CRDs (défaut 100,-1 désactive) | + +Helm range le cache, configuration, et données suivant les configurations serveur suivantes: + +- Si la variable d'environnement HELM_*_HOME est positionnée, elle sera utilisée +- Sinon, sur les systèmes supportant les spécifications XDG base directory, les variables XDG seront utilisées +- Lorsqu'aucun autre chemin n'est positionné, le chemin par défaut sera celui ddéfinit par le système d'exploitation OS + +Par défaut, les répertoires par défaut dépendent du système d'exploitation OS: + +| OS | Chemin Cache | Chemin Configuration | Chemin Données | +|------------------|---------------------------|--------------------------------|-------------------------| +| Linux | $HOME/.cache/helm | $HOME/.config/helm | $HOME/.local/share/helm | +| macOS | $HOME/Library/Caches/helm | $HOME/Library/Preferences/helm | $HOME/Library/helm | +| Windows | %TEMP%\helm | %APPDATA%\helm | %APPDATA%\helm | + + +### Options + +``` + --burst-limit int coté client limite bande passante (defaut 100) + --debug active la verbosité + -h, --help aide pour helm + --kube-apiserver string l'addresse et le port API du serveur Kubernetes + --kube-as-group stringArray group pour anonymiser l'opération, ce flag peut être répété pour spécifier plusieurs groupes. + --kube-as-user string nom utilisateur à anonymiser pour l'operation + --kube-ca-file string le fichier de l'autorité certifiante pour la connection à l'API serveur Kubernetes + --kube-context string nom du contexte kubeconfig à utiliser + --kube-insecure-skip-tls-verify Si true, la validité du certificat du serveur API Kubernetes ne sera pas vérifiée. Cela fera les connections HTTPS non sûres + --kube-tls-server-name string Nom du serveur utilisé pour la validation du certificat du serveur API Kubernetes. S'il n'est pas fourni, le nom de la machine cliente utilisée pour contacter le serveur sera utilisée + --kube-token string token du canal utilisé pour l'authentification + --kubeconfig string chemin du fichier de configuration kubeconfig + -n, --namespace string namespace utilisée pour la requête + --registry-config string chemin de configuration du registre (par defaut "~/.config/helm/registry/config.json") + --repository-cache string chemin contenant les indexes des repository en cache (default "~/.cache/helm/repository") + --repository-config string chemin contenant les noms et URLs des répertoires (default "~/.config/helm/repositories.yaml") +``` + +###### Auto generated by spf13/cobra on 8-Feb-2023 diff --git a/content/fr/docs/howto/_index.md b/content/fr/docs/howto/_index.md new file mode 100644 index 0000000000..0117e39a13 --- /dev/null +++ b/content/fr/docs/howto/_index.md @@ -0,0 +1,11 @@ +--- +title: "Comment faire" +weight: 2 +--- + +# Comment faire + +Dans cette section vous trouverez un ensemble de courtes réponses aux questions +"**Comment faire ...?**". Ces guides ne vont pas traiter de sujets en profondeur +*(La documentation dans les guides par [Thèmes](../topics))*, cependant ils vous +aideront à réussir rapidement des tâches simples. diff --git a/content/fr/docs/intro/_index.md b/content/fr/docs/intro/_index.md new file mode 100644 index 0000000000..546d7168d8 --- /dev/null +++ b/content/fr/docs/intro/_index.md @@ -0,0 +1,8 @@ +--- +title: "Introduction" +weight: 1 +--- + +# Introduction à Helm + +Vous êtes nouveau sur Helm ? C'est ici que ça commence ! diff --git a/content/fr/docs/intro/install.md b/content/fr/docs/intro/install.md new file mode 100755 index 0000000000..fbedef7394 --- /dev/null +++ b/content/fr/docs/intro/install.md @@ -0,0 +1,123 @@ +--- +title: "Installation de Helm" +description: "Learn how to install and get running with Helm." +weight: 2 +--- + +Ce guide vous explique comment installer la CLI (Interface de Ligne de Commande) Helm. Helm peut être installé soit à partir des sources, ou à partir des releases binaires pré-construites. + +## Depuis le projet Helm + +Nous vous proposons deux méthodes pour récupérer et installer Helm. Voici les méthodes officielles pour obtenir les releases de l'application. En plus de cela, la communauté Helm +fournit des méthodes pour installer Helm via différents gestionnaires de packages. L'installation via ces méthodes peut être trouvée ci-dessous. + +### À partir des releases binaires + +Chaque [releases] (https://github.com/helm/helm/releases) de Helm fournit des binaires pour une variété de systèmes d'exploitation. Ces binaires peuvent être téléchargées manuellement +et installé. + +1. Téléchargez la [version adéquate](https://github.com/helm/helm/releases) +2. Décompressez l'archive (`tar -zxvf helm-v3.0.0-linux-amd64.tar.gz`) +3. Trouvez le binaire `helm` dans le répertoire décompréssé, et déplacez le dans la destination voulue (`mv linux-amd64/helm /usr/local/bin/helm`) + +A ce stade, vous devriez être cappable de lancer le client et [d'ajouter le dépot stable](https://helm.sh/docs/intro/quickstart/#initialize-a-helm-chart-repository): `helm help`. + +**Remarque:** Les tests automatisés de Helm sont effectués pour Linux AMD64 uniquement pendant les build et release CircleCi. Les tests d'autres systèmes d'exploitation sont sous la responsabilité de la communauté qui demande Helm pour le système d'exploitation en question. + +### À partir du script + +Helm a maintenant un script d'installation qui récupérera automatiquement la dernière version de Helm et [l'installera localement](https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3). + +Vous pouvez récupérer ce script, puis l'exécuter localement. Il est bien documenté donc que vous pouvez le lire et comprendre ce qu'il fait avant de l'exécuter. + +```console +$ curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 +$ chmod 700 get_helm.sh +$ ./get_helm.sh +``` + +Oui, vous pouvez également `curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash` si vous aimez vivre dangereusement. + +## Via les gestionnaires de packages + +La communauté Helm offre la possibilité d'installer Helm via le gestionnaire de packages de votre système d'exploitation. Ceux-ci ne sont pas pris en charge par le projet Helm et ne sont pas considérés comme des tiers de confiance. + +### Depuis Homebrew (macOS) + +Les membres de la communauté Helm ont contribué à la création d'une formule Helm pour Homebrew. Ce package est généralement à jour. + +```console +brew install helm +``` + +(Note: il existe un projet différent possédant une formule pour emacs-helm.) + +### Depuis Chocolatey (Windows) + +Les membres de la communauté Helm ont contribué à la création d'un [package Helm](https://chocolatey.org/packages/kubernetes-helm) build pour [Chocolatey](https://chocolatey.org/). Ce package est généralement à jour. + +```console +choco install kubernetes-helm +``` + +### Depuis Apt (Debian/Ubuntu) + +Les membres de la communauté Helm ont contribué à la création d'un [package Helm](https://helm.baltorepo.com/stable/debian/) for Apt. Ce package est généralement à jour. + +```console +curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null +sudo apt-get install apt-transport-https --yes +echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list +sudo apt-get update +sudo apt-get install helm +``` + +### Depuis Snap + +La communauté des [Snapcrafters](https://github.com/snapcrafters) maintiennent la version Snap du [package Helm](https://snapcraft.io/helm) à jour : + +```console +sudo snap install helm --classic +``` + +### Depuis pkg (FreeBSD) + +Les membres de la communauté FreeBSD ont contribué à la création d'un [package Helm](https://www.freshports.org/sysutils/helm) build pour la [Collection de Ports FreeBSD](https://man.freebsd.org/ports). Ce package est généralement à jour. + +```console +pkg install helm +``` + +### Builds de developpement + +En plus des releases vous pouvez également télécharger et installer les snpashots de developpement de Helm + +### Depuis les builds Canary + +Les builds "Canary" sont des versions de logiciel Helm qui ont été construits à partir de la dernière version de la branche `main`. Ce ne sont pas des releases offcielles et peuvent ne pas être stable. Ceci étant, elles vous proposent l'opportunité de tester les features les plus récentes. + +Les binaires des builds Canary sont disponibles ici : [get.helm.sh](https://get.helm.sh). Voici les liens vers les builds les plus communs : + +- [Linux AMD64](https://get.helm.sh/helm-canary-linux-amd64.tar.gz) +- [macOS AMD64](https://get.helm.sh/helm-canary-darwin-amd64.tar.gz) +- [Experimental Windows AMD64](https://get.helm.sh/helm-canary-windows-amd64.zip) + +### Depuis les Sources (Linux, macOS) + +Construire Helm à partir des sources est un peu plus éprouvant, mais c'est le meilleur moyen de tester la dernière version (pré-release) de Helm. + +Vous devez disposer d'un environnement fonctionnelle de [Go](https://golang.org/doc/install). + +```console +$ git clone https://github.com/helm/helm.git +$ cd helm +$ make +``` + +Si nécessaire, Helm récupérera les dépendances et les mettra en cache, il poourra ensuite valider la configuration. `helm` sera compilé et le placé dans` bin/helm`. + +## Conclusion + +Dans la plupart des cas, l'installation est aussi simple que de télécharger un binaire `helm` pré-compilé. Ce document couvre des cas supplémentaires pour ceux qui veulent utiliser Helm dans des cas plus sophistiqués. + +Une fois que le client Helm est installé avec succès, vous pouvez passer à l'utilisation de Helm pour gérer des Charts [ajouter le dépot stable](https://helm.sh/docs/intro/quickstart/#initialize-a-helm-chart-repository). diff --git a/content/fr/docs/intro/quickstart.md b/content/fr/docs/intro/quickstart.md new file mode 100644 index 0000000000..6f4a8224a9 --- /dev/null +++ b/content/fr/docs/intro/quickstart.md @@ -0,0 +1,107 @@ +--- +title: "Guide de démarrage rapide" +description: "Comment installer et débuter sur Helm, comprends les instructions pour les distros, FAQs, et plugins." +weight: 1 +--- + +Ce guide explique comment commencer rapidement à utiliser Helm. + +## Conditions préalables + +Les conditions préalables suivantes sont requises pour une utilisation correcte et sécurisé de Helm : + +1. Posséder un cluster Kubernetes. +2. Décider des configurations de sécurité à appliquer à votre installation, si vous en avez. +3. Installation et configuration de Helm. + +### Installer Kubernetes ou avoir accès à un cluster + +- Vous devez avoir installé Kubernetes. Pour la dernière release de Helm, nous recommandons la dernière version stable de Kubernetes, qui est dans la plupart des cas la deuxième release mineure la plus récente. +- Vous devriez également avoir une copie locale configurée de `kubectl`. + +Lisez la [Politique de prise en charge de la version Helm](https://helm.sh/docs/topics/version_skew/) pour connaitre la différence de version maximal pris en charge entre Helm et Kubernetes. + +## Installer Helm + +Télécharger le binaire de la dernière release de Helm. Vous pouvez également utiliser un gestionnaire de package tel que `homebrew`, ou regarder sur [la page des releases officielles](https://github.com/helm/helm/releases). + +Pour plus de détails, ou d'autre options d'installation rendez vous sur [le guide d'installation]({{< ref "install.md" >}}). + +## Initialiser un dépot de charts Helm + +Une fois que votre Helm est prêt, vous avez la possibilité d'ajouter un dépot de charts. Regardez le [Artifact Hub](https://artifacthub.io/packages/search?kind=0) pour voir les dépots publiques de charts Helm disponibles. + +```console +$ helm repo add stable https://charts.helm.sh/stable +``` + +Une fois que le dépot est configuré, vous aurez la possibilité de lister les charts que vous pouvez installer : + +```console +$ helm search repo stable +NAME chart VERSION APP VERSION DESCRIPTION +stable/acs-engine-autoscaler 2.2.2 2.1.1 DEPRECATED Scales worker nodes within agent pools +stable/aerospike 0.2.8 v4.5.0.5 A Helm chart for Aerospike in Kubernetes +stable/airflow 4.1.0 1.10.4 Airflow is a platform to programmatically autho... +stable/ambassador 4.1.0 0.81.0 A Helm chart for Datawire Ambassador +# ... and many more +``` + +## Installer un chart d'exemple + +Pour installer un chart, vous pouvez exécuter la commande `helm install`. Helm a plusieurs moyens de trouver et d'installer un chart, mais le plus simple reste d'utiliser le dépot officiel de charts «stable». + +```console +$ helm repo update # Make sure we get the latest list of charts +$ helm install stable/mysql --generate-name +Released smiling-penguin +``` + +Dans l'exemple ci-dessus, le chart `stable / mysql` a été déployé, et le nom de notre nouvelle release est «smiling-penguin». + +Vous pouvez obtenir les informations simples des fonctionnalités de ce chart MySQL en exécutant `helm show chart stable/mysql`. Ou vous pouvez lancer `helm show all stable/mysql` pour obtenir toute les informations disponibles. + +Chaque fois que vous installez un chart, une nouvelle release est créée. Un chart peut donc être installé plusieurs fois sur le même cluster. Et chaque release peut être indépendamment gérée et mise à jour. + +La commande `helm install` est très puissante et possède beaucoup de fonctionnalités. Pour en apprendre plus sur cette commande lisez le [Guide d'utilisation de Helm]({{< ref "using_helm.md">}}) + +## Apprenez en plus sur le système de release + +Il est facile de voir ce qui à été deployé avec Helm : + +```console +$ helm ls +NAME VERSION UPDATED                   STATUS   chart +smiling-penguin 1 Wed Sep 28 12:59:46 2016 DEPLOYED mysql-0.1.0 +``` + +La fonction `helm list` vous montrera une liste de toutes les release déployées. + +## Désinstaller une release + +Pour désinstaller une release utiliser la commande `helm uninstall` : + +```console +$ helm uninstall smiling-penguin +Removed smiling-penguin +``` + +Cela désinstallera la release `smiling-penguin` de Kubernetes, toutes les ressources associées à cette release seront supprimés ainsi que l'historique lié. + +Si l'indicateur `--keep-history` est fourni, l'historique des releases sera conservé. Vous serez même en mesure de demander des informations sur cette release : + +```console +$ helm status smiling-penguin +Status: UNINSTALLED +... +``` + +Étant donné que Helm suit vos releases même après les avoir désinstallées, vous pouvez auditer l'historique d'un cluster, et même annuler la suppression d'une release (avec `helm rollback`). + +## Lecture du l'aide + +Pour en savoir plus sur les commandes Helm disponibles, utilisez `helm help` ou tapez une commande suivie de l'indicateur `-h`: + +```console +$ helm get -h +``` diff --git a/content/fr/docs/intro/using_helm.md b/content/fr/docs/intro/using_helm.md new file mode 100755 index 0000000000..55682de769 --- /dev/null +++ b/content/fr/docs/intro/using_helm.md @@ -0,0 +1,406 @@ +--- +title: "Utilisation de Helm" +description: "Explique la base de Helm." +weight: 3 +--- + +Ce guide explique les bases de l'utilisation de Helm pour gérer les packages sur votre cluster Kubernetes. Nous partons du principe que vous avez déjà [installé]({{< ref "install.md" >}}) le client Helm. + +Si vous souhaitez simplement exécuter quelques commandes rapides, vous pouvez commencer par le [Guide de démarrage rapide]({{< ref "quickstart.md" >}}). Ce chapitre couvre les différentes commandes Helm et explique comment les utiliser. + +## Trois grands concepts + +Un *Chart* est un package Helm. Il contient toutes les définitions des ressources nécessaires pour exécuter une application, un outil ou un service à l'intérieur d'un cluster Kubernetes. Voyez cela comme l'équivalent Kubernetes d'une formule pour Homebrew, d'un dpkg pour Apt , ou d'un fichier RPM pour Yum. + +Un *Dépot* est le lieu où les charts peuvent être collectés et partagés. C'est comme les [archives CPAN de Perl](https://www.cpan.org) ou la [base de données de packages Fedora](https://src.fedoraproject.org/), mais pour les packages de Kubernetes. + +Une *Release* est une instance d'un chart s'exécutant dans un cluster Kubernetes. Un chart peut être installé plusieurs fois dans le même cluster. Et à chaque fois qu'il est à nouveau installé, une nouvelle _release_ est créé. Prenons un chart MySQL, si vous voulez deux bases de données s'exécutant dans votre cluster, vous pouvez installer ce chart deux fois. Chacune aura sa propre _release_, qui à son tour aura son propre _release name_. + +Maintenant que vous maîtrisez ces concepts, nous pouvons aborder Helm de la manière suivante : + +Helm installe des _charts_ dans Kubernetes, créant une nouvelle _release_ pour chaque installation. Et pour trouver de nouveaux charts, vous pouvez rechercher des _repositories_ (dépots) de charts Helm. + +## 'helm search': La recherche de charts + +Helm est livré avec une puissante commande de recherche. Elle peut être utilisée pour rechercher deux différents types de ressources : + +- `helm search hub` recherche sur le [Artifact Hub](https://artifacthub.io), qui liste les charts Helm depuis une douzaines de dépôts. +- `helm search repo` recherche sur les dépots que vous avez ajouté a votre config (via `helm repo add`). Cette recherche est faite sur le réseau privé et ne nécessite pas de connexion à internet. + +Vous pouvez trouver un chart sur les dépôts publique avec la commande `helm search hub`: + +```console +$ helm search hub wordpress +URL CHART VERSION APP VERSION DESCRIPTION +https://hub.helm.sh/charts/bitnami/wordpress 7.6.7 5.2.4 Web publishing platform for building blogs and ... +https://hub.helm.sh/charts/presslabs/wordpress-... v0.6.3 v0.6.3 Presslabs WordPress Operator Helm Chart +https://hub.helm.sh/charts/presslabs/wordpress-... v0.7.1 v0.7.1 A Helm chart for deploying a WordPress site on ... +``` + +La commande ci-dessus recherche toutes les charts `wordpress` sur Artifact Hub. + +En utilisant `helm search repo`, vous pouvez trouver les noms des charts dans les dépots que vous avez ajouté manuellement : + +```console +$ helm repo add brigade https://brigadecore.github.io/charts +"brigade" has been added to your repositories +$ helm search repo brigade +NAME CHART VERSION APP VERSION DESCRIPTION +brigade/brigade 1.3.2 v1.2.1 Brigade provides event-driven scripting of Kube... +brigade/brigade-github-app 0.4.1 v0.2.1 The Brigade GitHub App, an advanced gateway for... +brigade/brigade-github-oauth 0.2.0 v0.20.0 The legacy OAuth GitHub Gateway for Brigade +brigade/brigade-k8s-gateway 0.1.0 A Helm chart for Kubernetes +brigade/brigade-project 1.0.0 v1.0.0 Create a Brigade project +brigade/kashti 0.4.0 v0.4.0 A Helm chart for Kubernetes +``` + +La commande de recherche de Helm utilise un algorithme de correspondance de chaîne de charactères, vous pouvez donc saisir des mots ou une partie de phrase : + +```console +$ helm search repo kash +NAME CHART VERSION APP VERSION DESCRIPTION +brigade/kashti 0.4.0 v0.4.0 A Helm chart for Kubernetes +``` + +La recherche est un bon moyen de trouver les packages disponibles. Une fois que vous avez trouvé une application que vous souhaitez installer, vous pouvez utiliser `helm install` pour l'installer. + +## 'helm install': Installation d'un package + +Pour installer un nouveau package, utilisez la commande `helm install`. Dans sa forme la plus simple, elle prend deux arguments: le nom de la version voulue et le nom du chart que vous +voulez installer. + +```console +$ helm install happy-panda bitnami/wordpress +NAME: happy-panda +LAST DEPLOYED: Tue Jan 26 10:27:17 2021 +NAMESPACE: default +STATUS: deployed +REVISION: 1 +NOTES: +** Please be patient while the chart is being deployed ** + +Your WordPress site can be accessed through the following DNS name from within your cluster: + + happy-panda-wordpress.default.svc.cluster.local (port 80) + +To access your WordPress site from outside the cluster follow the steps below: + +1. Get the WordPress URL by running these commands: + + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + Watch the status with: 'kubectl get svc --namespace default -w happy-panda-wordpress' + + export SERVICE_IP=$(kubectl get svc --namespace default happy-panda-wordpress --template "{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}") + echo "WordPress URL: http://$SERVICE_IP/" + echo "WordPress Admin URL: http://$SERVICE_IP/admin" + +2. Open a browser and access WordPress using the obtained URL. + +3. Login with the following credentials below to see your blog: + + echo Username: user + echo Password: $(kubectl get secret --namespace default happy-panda-wordpress -o jsonpath="{.data.wordpress-password}" | base64 --decode) +``` + +Le chart `wordpress` est maintenant installé. Notez que l'installation d'un chart crée un nouvel objet _release_. La version ci-dessus est nommée «happy-panda». (Si vous voulez que Helm génère un nom pour vous, oubliez le nom de la version et utilisez `--generate-name`.) + +Lors de l'installation, le client `helm` affichera des informations utiles sur les ressources qui ont été créées, l'état de la version et si il y a des étapes de configurations supplémentaires que vous pouvez ou devez suivre. + +Helm n'attend pas que toutes les ressources soient en cours d'exécution avant de quitter. De nombreuses charts nécessitent des images Docker de plus de 600 Mo et peuvent prendre du temps à s'installer dans le cluster. + +Pour suivre l'état d'une release ou pour relire les informations de configuration, vous pouvez utiliser `helm status`: + +```console +$ helm status happy-panda +NAME: happy-panda +LAST DEPLOYED: Tue Jan 26 10:27:17 2021 +NAMESPACE: default +STATUS: deployed +REVISION: 1 +NOTES: +** Please be patient while the chart is being deployed ** + +Your WordPress site can be accessed through the following DNS name from within your cluster: + + happy-panda-wordpress.default.svc.cluster.local (port 80) + +To access your WordPress site from outside the cluster follow the steps below: + +1. Get the WordPress URL by running these commands: + + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + Watch the status with: 'kubectl get svc --namespace default -w happy-panda-wordpress' + + export SERVICE_IP=$(kubectl get svc --namespace default happy-panda-wordpress --template "{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}") + echo "WordPress URL: http://$SERVICE_IP/" + echo "WordPress Admin URL: http://$SERVICE_IP/admin" + +2. Open a browser and access WordPress using the obtained URL. + +3. Login with the following credentials below to see your blog: + + echo Username: user + echo Password: $(kubectl get secret --namespace default happy-panda-wordpress -o jsonpath="{.data.wordpress-password}" | base64 --decode) +``` + +La commande ci-dessus montre l'état actuel de votre release. + +### Personnalisation d'un chart avant son installation + +L'installation comme nous l'avons fait ici n'utilisera que les options de configuration par défaut. Il peut arriver que vous souhaitiez personnaliser le chart pour utiliser une +configuration personalisée. + +Pour voir quelles options sont configurables sur un chart, utilisez `helm show values`: +```console +$ helm show values bitnami/wordpress +## Global Docker image parameters +## Please, note that this will override the image parameters, including dependencies, configured to use the global value +## Current available global Docker image parameters: imageRegistry and imagePullSecrets +## +# global: +# imageRegistry: myRegistryName +# imagePullSecrets: +# - myRegistryKeySecretName +# storageClass: myStorageClass + +## Bitnami WordPress image version +## ref: https://hub.docker.com/r/bitnami/wordpress/tags/ +## +image: + registry: docker.io + repository: bitnami/wordpress + tag: 5.6.0-debian-10-r35 + [..] +``` + +Vous pouvez ensuite ecraser la configuration par défaut grâce à un fichier YAML que vous passerez en paramètre lors de l'installation. + +```console +$ echo '{mariadb.auth.database: user0db, mariadb.auth.username: user0}' > values.yaml +$ helm install -f values.yaml bitnami/wordpress --generate-name +``` + +La commande ci-dessus créera un utilisateur MariaDB par défaut avec le nom `user0`, et accordera à cet utilisateur l'accès à la base de données `user0db` nouvellement créée, mais prendra le reste des valeurs par défaut pour l'installation du chart. + +Il existe deux façons de transmettre les données de configuration lors de l'installation: + +- `--values` (ou `-f`): Spécifie un fichier YAML personnalisé. Vous pouvez spécifier plusieurs fichiers, celui le plus à droite prévaudra. +- `--set`: Spécifie une valeur personnalisée en ligne de commande. + +Si les deux paramètes sont utilisés, les valeurs de `--set` sont fusionnés dans ` --values` avec une priorité plus élevée. Les remplacements spécifiés avec `--set` sont conservés dans un fichier ConfigMap. +Les valeurs qui ont été `--set` peuvent être visualisées pour une release donnée avec ` helm get values `. +Les valeurs qui ont été `--set` peuvent être effacées en exécutant `helm upgrade` avec ` --reset-values` spécifié. + +#### Le format et les limites de `--set` + +L'option `--set` prend zéro ou plusieurs paires de nom/valeur. La manière la plus simple d'utilisation est : +`--set name = value`. L'équivalent YAML serait : + +```yaml +name: value +``` + +Vous pouvez entrer plusieurs valeurs en les séparant par une virgule `,` . Ainsi `--set a=b,c=d` devient l'équivalent YAML de : + +```yaml +a: b +c: d +``` + +Des expressions plus complexes sont acceptés. Par exemple l'équivalent de `--set outer.inner=value` en YAML est : + +```yaml +outer: + inner: value +``` + +Vous pouvez définir des listes grâce à des accolades `{` et `}`. Exemple: `--set name={a, b, c}` devient : + +```yaml +name: + - a + - b + - c +``` + +Depuis Helm 2.5.0, il est possible d'accéder aux éléments d'une liste en utilisant l'index du tableau. +Exemple : `--set servers[0].port=80` correspond à : + +```yaml +servers: + - port: 80 +``` + +Plusieurs valeurs peuvent être définit de cette manière. +La ligne suivante `--set servers[0].port=80,servers[0].host=example` devient: + +```yaml +servers: + - port: 80 + host: example +``` + +Il peut arriver que vous ayez besoin d'utiliser un charactère spécial avec `--set`. Pour ce faire vous pouvez utiliser un backslash `\`. +Exemple : `--set name=value1\,value2` devient : + +```yaml +name: "value1,value2" +``` + +De la même manière, vous pouvez l'utiliser pour une séquence commençant par un point, ce qui peut être utile lorsque les charts utilisent la fonction `toYaml` pour analyser les annotations, les étiquettes et les nœuds sélecteurs. +La syntaxe de `--set nodeSelector." Kubernetes \ .io / role "= master` devient: + +```yaml +nodeSelector: + kubernetes.io/role: master +``` + +Les structures de données profondément imbriquées peuvent être difficiles à exprimer en utilisant `--set`. Les concepteurs de charts sont encouragés à utiliser un fichier de valeurs au format YAML : ` values.yaml` lorsqu'il y a beaucoup de valeurs à configurer (en savoir plus sur [les fichiers de valeurs]({{< relref path="/docs/chart_template_guide/values_files/_index.md" lang="en" >}})). + +### Autres methodes d'installations + +La commande `helm install` peut installer un package depuis différentes sources: + +- Un dépot de charts (Comme vu précédemment) +- Une archive local d'un chart (`helm install foo foo-0.1.1.tgz`) +- Un dossier contenant un chart décompressé (`helm install foo path/to/foo`) +- Une URL pointant vers un chart (`helm install foo https://example.com/charts/foo-1.2.3.tgz`) + +## 'helm upgrade' et 'helm rollback': Mettre à jour une Release, et récupération d'un Echec + +Lorsqu'une nouvelle release d'un chart est publiée, ou lorsque vous souhaitez modifier la configuration de votre release, vous pouvez utiliser la commande `helm upgrade`. + +Une mise à niveau prend une release existante et la met à niveau en fonction des informations que vous fournissez. Étant donné que les charts Kubernetes peuvent être volumineuses et complexes, Helm essaie d'effectuer la mise à niveau la moins invasive. Ainsi il essaiera de mettre à jour uniquement les éléments qui ont changé depuis la dernière version. + +```console +$ helm upgrade -f panda.yaml happy-panda bitnami/wordpress +``` + +Dans le cas ci-dessus la release `happy-panda` est mis à jour depuis la même chart mais avec un fichier de config YAML différent : + +```yaml +mariadb.auth.username: user1 +``` + +Vous pouvez utiliser `helm get values` si votre nouvelle configuration à pris effet ou non : + +```console +$ helm get values happy-panda +mariadb: + auth: + username: user1 +``` + +La commande `helm get` est un outil utile pour voir les informations d'une release dans le cluster. Et comme nous venons de le voir ci-dessus, la commande peut également être utilisé pour voir si les nouvelles valeurs de `panda.yaml` sont bien déployés sur le cluster. + +Maintenant admettons que quelque chose ne se passe pas comme prévu lors d'une release, il est facile de revenir à une version précédente en utilisant `helm rollback [RELEASE_NAME] [VERSION]`. + +```console +$ helm rollback happy-panda 1 +``` + +la commande précédente ramène notre happy-panda à sa toute première version. Une version de release est une révision incrémentielle. Chaque fois qu'une installation, qu'une mise à jour ou qu'une restauration est faite, le numéro de révision est incrémenté de 1. La première release est toujours la version numéro 1. Et vous pouvez utiliser `helm history [RELEASE]` voir les versions d'une release. + +## Options utiles pour l'installation / la mise à jour / la restauration + +Il existe d'autres options utiles que vous pouvez spécifier pour personnaliser le comportement de Helm lors d'une installation / d'une mise à jour / d'une restauration. Veuillez noter que la liste qui suit n'est pas exhaustive. Pour voir une description de tous les flags, exécutez simplement `helm --help`. + +- `--timeout`: Une [durée Go](https://golang.org/pkg/time/#ParseDuration) maximale avant de terminer la commande Kubernetes. La valeur par défaut est `5m0s`. +- `--wait`: Attend que tous les pods soient dans un état prêt, les PVCs sont liés, les déploiements ont un minimum (`Desired` moins ` maxUnavailable`) de pods prêts et les services ont une adresse IP (et une entrée si il y a un `LoadBalancer`) avant de marquer la release comme réussie. Il attendra au maximum la valeur de `--timeout`. Si le délai d'expiration est atteint, la release sera marquée comme «FAILED». Remarque: dans les scénarios où le déploiement a `réplicas` défini sur 1 et ` maxUnavailable` n'est pas défini à 0 dans le cadre de la stratégie de mise à jour progressive, `--wait` sera marqué comme prêt dès qu'il aura satisfait son nombre minimum de Pods en état prêt. +- `--no-hooks`: Permet d'ignorer l'exécution des hooks pour la commande +- `--recreate-pods` (seulement disponible pour les `upgrade` et les `rollback`): Ce flag permet de recréer tous les pods (à l'exception des pods de deploiements). (DEPRECIE depuis Helm 3) + +## 'helm uninstall': Désinstallation d'une Release + +Quand sera venu le jour ou vous devrez désinstaller une release de votre cluster, utilisez la commande `helm uninstall` : + +```console +$ helm uninstall happy-panda +``` + +Cela supprimera la release du cluster. Vous pouvez voir toutes vos releases actuellement déployées avec la commande `helm list`: + +```console +$ helm list +NAME VERSION UPDATED STATUS CHART +inky-cat 1 Wed Sep 28 12:59:46 2016 DEPLOYED alpine-0.1.0 +``` + +À partir du résultat ci-dessus, nous pouvons voir que la version `happy-panda` a bien été désinstallé. + +Dans les versions précédentes de Helm, lorsqu'une release était supprimée, l'historique entier restait disponible. Depuis Helm 3, la désinstallation supprime également l'historique de la release. +Si vous souhaitez tout de même conserver un enregistrement de l'historique, utilisez `helm uninstall --keep-history`. +L'utilisation de `helm list --uninstalled` affichera uniquement les release qui ont été désinstallés avec l'indicateur `--keep-history`. + +L'indicateur `helm list --all` vous montrera tous les historique de release que Helm a conservés, y compris les historiques des éléments ayant échoué ou ayant été supprimé (si `--keep-history` était spécifié): + +```console +$ helm list --all +NAME VERSION UPDATED STATUS CHART +happy-panda 2 Wed Sep 28 12:47:54 2016 UNINSTALLED wordpress-10.4.5.6.0 +inky-cat 1 Wed Sep 28 12:59:46 2016 DEPLOYED alpine-0.1.0 +kindred-angelf 2 Tue Sep 27 16:16:10 2016 UNINSTALLED alpine-0.1.0 +``` + +Notez que les historiques de release étant désormais supprimées par défaut, il n'est plus possible de restaurer une ressource désinstallée. + +## 'helm repo': Travailler avec des Dépôts + +Helm 3 n'est plus livré avec un dépôt de charts par défaut. La commande `helm repo` vous permet entre autre d'ajouter, de répertorier et de supprimer des dépôts. + +Vous pouvez voir quels dépôts sont configurés en utilisant `helm repo list`: + +```console +$ helm repo list +NAME URL +stable https://charts.helm.sh/stable +mumoshu https://mumoshu.github.io/charts +``` + +Vous pouvez bien entendu ajouter de nouveaux dépôts avec `helm repo add`: + +```console +$ helm repo add dev https://example.com/dev-charts +``` + +Étant donné que les dépôts de charts changent fréquemment, vous pouvez à tout moment vous assurer que dépot Helm est à jour en exécutant `helm repo update`. + +Les dépôts peuvent être supprimés avec `helm repo remove`. + +## Création de vos propres charts + +Le [Guide de développement de charts]({{< relref path="/docs/topics/charts.md" lang="en" >}}) explique comment développer vos propres charts. Mais vous pouvez vous lancer rapidement dans la création de charts avec la commande `helm create`: + +```console +$ helm create deis-workflow +Creating deis-workflow +``` + +Il y a maintenant un chart dans `./deis-workflow`. Vous pouvez le modifier et créer vôtre modèles personalisé. + +Lorsque vous modifiez votre chart, vous pouvez vérifier la syntaxe en exécutant `helm lint`. + +Quand vous aurez besoin de packager le chart pour la distribution, vous pourrez exécuter `helm package`: + +```console +$ helm package deis-workflow +deis-workflow-0.1.0.tgz +``` + +Le chart est maintenant prêt à l'installation `helm install`: + +```console +$ helm install deis-workflow ./deis-workflow-0.1.0.tgz +... +``` + +Les charts packagés peuvent être uploadés dans des dépôts. Jetez un oeil à la +[documentation des dépôts]({{< ref path="/docs/topics/chart_repository.md" lang="en" >}}) de charts Helm pour plus de détails. + +## Conclusion + +Ce chapitre a couvert les utilisations de base du client `helm`, y compris la recherche, l'installation, la mise à jour et la désinstallation. Nous avons également vu les commandes utilitaires telles que `helm status`,` helm get` ou encore `helm repo`. + +Pour plus d'informations sur ces commandes, consultez l'aide intégrée de Helm: `helm help`. + +Dans le [chapitre suivant]({{< relref path="/docs/howto/charts_tips_and_tricks/_index.md" lang="en" >}}), nous verrons le processus de développement des charts. diff --git a/content/fr/docs/topics/_index.md b/content/fr/docs/topics/_index.md new file mode 100644 index 0000000000..3c0f3265f9 --- /dev/null +++ b/content/fr/docs/topics/_index.md @@ -0,0 +1,9 @@ +--- +title: "Thèmes" +weight: 3 +--- + +# Guides par thème + +Dans cette section vous trouverez une introduction pour chacune des parties clés +de Helm dont vous pourrez avoir besoin. diff --git a/content/gr/docs/_index.md b/content/gr/docs/_index.md new file mode 100644 index 0000000000..fb5522a165 --- /dev/null +++ b/content/gr/docs/_index.md @@ -0,0 +1,27 @@ +--- +title: "Αρχική Εγγράφων" +description: "Όλα όσα χρειάζεσαι να μάθεις για το πως είναι οργανωμένη η τεκμηρίωση." +--- + +# Καλωσήρθες + +Καλωσήρθες στην τεκμηρίωση του [Helm](https://helm.sh/). Το Helm είναι ο package manager +του Kubernetes, και μπορείς να διαβάσεις τις λεπτομερείς πληροφορίες για το πλαίσιο στο +[CNCF Helm Project Journey +report](https://www.cncf.io/cncf-helm-project-journey/). + +# Πως οργανώνεται η τεκμηρίωση + +Το Helm έχει πολύ καλή τεκμηρίωση. Μια γενική ματιά στο πως είναι οργανωμένη +θα σε βοηθήσει να ξέρεις που να ψάξεις για συγκεκριμένα πράγματα: + +- Τα Tutorials σε παίρνουν από το χέρι και σε καθοδηγούν σε μια σειρά από βήματα + ώστε να δημιουργήσεις το πρώτο σου Helm chart. Ξεκίνα από εδώ αν είσαι νέος/νέα στο Helm. +- Οι Θεματικοί Οδηγοί συζητούν για θέματα κλειδιά και έννοιες σε ένα αρκετά γενικό επίπεδο + και παρέχουν χρήσιμες πληροφορίες για το πλαίσιο και επεξηγήσεις. +- Οι Οδηγοί της Κοινότητας συζητούν για θέματα που έχουν κέντρο την κοινότητα του Helm. + Ξεκίνα από εδώ αν θες να μάθεις περισσότερα για την διαδικασία ανάπτυξης του ίδιου του Helm + και πως μπορείς να συνεισφέρεις. +- Οι Οδηγοί How-to είναι συνταγές. Σε καθοδηγούν μέσα από τα βήματα που απαιτούνται + ώστε να διευθετήσεις προβλήματα κλειδιά και περιπτώσεις χρήσης. Είναι πιο προχωρημένοι από τα tutorials + και έχουν ως προϋπόθεση βασικές γνώσεις για το Helm. diff --git a/content/gr/docs/chart_best_practices/_index.md b/content/gr/docs/chart_best_practices/_index.md new file mode 100644 index 0000000000..366628e647 --- /dev/null +++ b/content/gr/docs/chart_best_practices/_index.md @@ -0,0 +1,13 @@ +--- +title: "Βέλτιστες Πρακτικές" +sidebar: true +weight: 4 +--- + +# Ο Οδηγός Βέλτιστων Πρακτικών για τα Charts + +Αυτός ο οδηγός καλύπτει αυτά που η Ομάδα του Helm θεωρεί ως βέλτιστες πρακτικές για την δημιουργία charts. +Επικεντρώνεται στο πως θα έπρεπε να δομούνται τα charts. + +Κυρίως επικεντρωνόμαστε στις βέλτιστες πρακτικές για τα charts τα οποία θα μπορούσαν να γίνουν deploy από ευρύτερο κοινό. +Ξέρουμε ότι πολλά charts προορίζονται μόνο για εσωτερική χρήση, και οι συγγραφείς τέτοιων charts ότι τα εσωτερικά συμφέροντα παρακάμπτουν τις προτάσεις μας εδώ. diff --git a/content/gr/docs/chart_best_practices/conventions.md b/content/gr/docs/chart_best_practices/conventions.md new file mode 100644 index 0000000000..a3d01dabc1 --- /dev/null +++ b/content/gr/docs/chart_best_practices/conventions.md @@ -0,0 +1,42 @@ +--- +title: "Γενικές Συμβάσεις" +description: "Γενικές Συμβάσεις για τα charts." +weight: 1 +--- + +Αυτό το μέρος του Οδηγού Βέλτιστων Πρακτικών εξηγεί τις γενικές συμβάσεις. + +## Ονόματα των Charts + +Τα ονόματα των Charts πρέπει να είναι γραμμένα με μικρά λατινικά γράμματα και αριθμούς. Οι λέξεις _μπορούν_ να διαχωρίζονται με παύλες (-): + +Παραδείγματα: + +``` +drupal +nginx-lego +aws-cluster-autoscaler +``` + +Ούτε κεφαλαία γράμματα ούτε κάτω παύλες μπορούν να χρησιμοποιούνται στα ονόματα των charts. Οι τελείες δεν θα έπρεπε να χρησιμοποιούνται στα ονόματα των charts. + +## Αριθμοί Εκδόσεων + +Όπου είναι δυνατό, το Helm χρησιμοποιεί το [SemVer 2](https://semver.org) για να αναπαραστήσει ττους αριθμούς των εκδόσεων ( versions ). (Σημειώστε ότι τα tags ενός Docker image δεν ακολουθούν απαραίτητα το SemVer, και ως εκ τούτου θεωρούνται μια ατυχής εξαίρεση στον κανόνα.) + +Όταν οι εκδόσεις τύπου SemVer αποθηκεύονται στα labels του Kubernetes, εμείς ως σύμβαση αλλάζουμε τον χαρακτήρα `+` με τον χαρακτήρα `_` , μιας και τα labels δεν επιτρέπουν το σήμα `+` ως τιμή. + +## Μορφοποίηση του YAML + +Τα αρχεία YAML δεν θα έπρεπε να στοιχίζονται χρησιμοποιώντας _δύο κενά_ (και ποτέ tabs). + +## Χρήση των λέξεων Helm και Chart + +Υπάρχουν μερικές συμβάσεις για την χρήση των λέξεων _Helm_ και _helm_. + +- Το _Helm_ αναφέρεται σε ολόκληρο το εγχείρημα +- Το `helm` αναφέρεται στην εντολή την οποία εκτελεί ένας χρήστης +- Ο όρος `chart` δεν χρειάζεται να γραφτεί με κεφαλαίο, αφού δεν αποτελεί κανονικό όνομα +- Παρ' ολ' αυτά, το `Chart.yaml` χρειάζεται να γραφτεί με κεφαλαίο γιατί τα ονόματα αρχείων κάνουν διάκριση κεφαλαίων και μικρών ( case sensitive ). + +Όταν δεν είστε σίγουροι/ες, χρησιμοποιήστε το _Helm_ (με κεφαλαίο 'H'). diff --git a/content/gr/docs/chart_best_practices/dependencies.md b/content/gr/docs/chart_best_practices/dependencies.md new file mode 100644 index 0000000000..4b5ca8155d --- /dev/null +++ b/content/gr/docs/chart_best_practices/dependencies.md @@ -0,0 +1,52 @@ +--- +title: "Αλυσίδες Charts" +description: "Καλύπτει τις βέλτιστες πρακτικές για τις αλυσίδες chart εντός ενός Chart." +weight: 4 +--- + +Αυτός ο τομέας του οδηγού καλύπτει τις βέλτιστες πρακτικές για τις `αλυσίδες charts` οι οποίες δηλώνονται στο `Chart.yaml`. + +## Εκδόσεις + +Όπου είναι δυνατό, χρησιμοποιήστε ένα φάσμα εκδόσεων (versions) αντί να καρφώνετε σε κάποια συγκεκριμένη έκδοση. Το συνιστώμενο default είναι να χρησιμοποιείτε μια έκδοση η οποία να κάνει το ταίριασμα στο επίπεδο του patch: + +```yaml +version: ~1.2.3 +``` + +Αυτό θα ταιριάξει με την έκδοση `1.2.3` και όλα τα patches αυτού του release. Με άλλα λόγια, το `~1.2.3` είναι εφάμιλο με την έκφραση `>= 1.2.3, < 1.3.0` + +Για την πλήρη σύνταξη του πως γίνεται το ταίριασμα των εκδόσεων, παρακαλούμε δείτε το [semver +documentation](https://github.com/Masterminds/semver#checking-version-constraints). + +### URLs των Repositories + +Όπου είναι δυνατό, χρησιμοποιήστε `https://` για τα URLs ενός repository, και ακολούθως `http://` URLs. + +Αν το repository έχει προστεθεί στο αρχείο index για repository ( κατάλογος για repositories ) , το όνομα του repository μπορεί να χρησιμοποιηθεί ως alias του URL. Χρησιμοποιήστε το `alias:` ή `@` ακολουθούμενο από το όνομα του repository. + +Τα file URLs (`file://...`) θεωρούνται ως "ειδική περίπτωση" για charts τα οποία συντάσσονται από το pipeline ενός φιξαρισμένου deployment. Τα Charts τα οποία χρησιμοποιούν `file://` δεν επιτρέπονται στο επίσημο Helm repository. + +## Συνθήκες και Tags + +Οι συνθήκες ή τα tags θα έπρεπε να προστίθενται σε εξαρτώμενα οι οποίες είναι _προαιρετικές_. + +Η προτιμώμενη μορφή μίας συνθήκης (condition) είναι η ακόλουθη: + +```yaml +condition: somechart.enabled +``` + +Όπου το `somechart` είναι το όνομα του chart της αλυσίδας. + +Όταν πολλαπλά υποcharts (αλυσίδες - dependencies) παρέχουν ένα προαιρετικό ή ανταλλάξιμο +feature μαζί, αυτά τα charts θα έπρεπε να περιέχουν τα ίδια tags. + +Για παράδειγμα , αν κα το `nginx` και το `memcached` παρέχουν και τα δύο βελτιστοποιήσεις για την απόδοση για το κύριο app του chart, και είναι απαραίτητο και τα δύο να είναι παρόντα όταν αυτό το feature είναι ενεργοποιημένο, τότε θα πρέπει να έχουν και τα δύο έναν τομέα με tags κάπως έτσι: + +```yaml +tags: + - webaccelerator +``` + +Αυτό επιτρέπει στον χρήστη να ανοίγει και να κλείνει αυτό το feature με ένα tag. diff --git a/content/ja/docs/_index.md b/content/ja/docs/_index.md new file mode 100644 index 0000000000..4f5c63ffe0 --- /dev/null +++ b/content/ja/docs/_index.md @@ -0,0 +1,26 @@ +--- +title: "ドキュメントホーム" +description: "ドキュメントの構成について知っておく必要のあるすべて。" +--- + +# ようこそ + +[Helm](https://helm.sh/) ドキュメントへようこそ。Helm は Kubernetes の +パッケージマネージャーであり、[CNCF Helm プロジェクトジャーニーレポート](https://www.cncf.io/cncf-helm-project-journey/)で +詳細な背景情報を読むことができます。 + +# ドキュメントの構成 + +Helm には多くのドキュメントがあります。それがどのように編成されているかについての +ハイレベルの概要は、特定のものを探す場所を知るのに役立ちます。 + +- [チュートリアル](intro) では、最初の Helm チャートを作成するための一連の手順を1つずつ説明します。 + Helm を初めて使用する場合は、ここから始めてください。 +- [トピックガイド](topics) では、主要なトピックと概念についてかなり高いレベルで説明し、 + 役立つ背景情報と説明を提供します。 +- [コミュニティガイド](community) は、Helm のコミュニティを中心としたトピックについて話し合っています。 + Helm 自体の開発プロセスと貢献方法について詳しく知りたい場合は、 + ここから始めてください。 +- [How-to ガイド](howto) はレシピです。 + これらは、主要な問題とユースケースへの対処に関連する手順を案内します。 + これらはチュートリアルよりも高度で、Helm の動作に関するある程度の知識があることを前提としています。 diff --git a/content/ja/docs/chart_best_practices/_index.md b/content/ja/docs/chart_best_practices/_index.md new file mode 100644 index 0000000000..853765c83c --- /dev/null +++ b/content/ja/docs/chart_best_practices/_index.md @@ -0,0 +1,14 @@ +--- +title: "ベストプラクティス" +sidebar: true +weight: 4 +--- + +# チャートのベストプラクティスガイド + +このガイドでは、チャートを作成するために Helm チームが検討したベストプラクティスについて説明します。 +チャートの構造に焦点を当てています。 + +主に、公に展開される可能性のあるチャートのベストプラクティスに焦点を当てています。 +多くのチャートは内部使用のみであることを認識しており、 +そのようなチャートの作成者は、内部の関心がここでの提案をオーバーライドすることに気付く場合があります。 diff --git a/content/ja/docs/chart_best_practices/conventions.md b/content/ja/docs/chart_best_practices/conventions.md new file mode 100644 index 0000000000..105b78e7db --- /dev/null +++ b/content/ja/docs/chart_best_practices/conventions.md @@ -0,0 +1,42 @@ +--- +title: "一般的な慣習" +description: "チャートについての一般的な慣習です。" +weight: 1 +--- + +ベストプラクティスガイドのこの部分では一般的な慣習について説明します。 + +## チャート名 + +チャート名は英小文字と数字である必要があります。単語はダッシュ(-)で区切ることも _できます_ 。 + +例: + +``` +drupal +nginx-lego +aws-cluster-autoscaler +``` + +英大文字とアンダースコアは両方ともチャート名に用いることはできません。ドットもチャート名には使わないべきです。 + +## バージョン数 + +可能ならばどこであっても、Helm はバージョン数を表現するために [SemVer 2](https://semver.org) を使います。(Docker イメージタグは SemVer に従う必要がないことに注意してください。またこれは残念ながら規約の例外とみなされています。) + +SemVer バージョンが Kubernetes ラベルに保存されるとき、私たちは慣習的に文字 `+` を文字 `_` に置き換えます。これはラベルで `+` が値を表さないようにするためです。 + +## YAML のフォーマット + +YAML ファイルは _2 つのスペース_ でインデントされるべきです(そしてタブは使いません)。 + +## 単語 Helm と Chart の使い方 + +単語 _Helm_ および _helm_ の使い方についていくつかの慣習があります。 + +- _Helm_ はプロジェクト全体を表します。 +- `helm` はクライアントサイドのコマンドを表します。 +- 用語 `chart` を大文字化する必要はありません。なぜならそれは固有名詞ではないためです。 +- しかし、ファイル名はケース・センシティブであるため `Chart.yaml` は大文字化する必要があります。 + +迷ったときは、 _Helm_ (大文字の 'H' を含む)を使いましょう。 \ No newline at end of file diff --git a/content/ja/docs/chart_best_practices/dependencies.md b/content/ja/docs/chart_best_practices/dependencies.md new file mode 100644 index 0000000000..78f0199e21 --- /dev/null +++ b/content/ja/docs/chart_best_practices/dependencies.md @@ -0,0 +1,79 @@ +--- +title: "依存関係" +description: "チャートの依存関係についての解説です。" +weight: 4 +--- + +このセクションでは、`Chart.yaml`に宣言された`依存関係`のベストプラクティスについて +解説します。 + +## バージョン + +可能であれば、正確なバージョンを固定するよりバージョンの範囲を使用してください。デフォルト +では、パッチレベルのバージョンマッチを使用することが推奨されています: + +```yaml +version: ~1.2.3 +``` + +これはバージョン`1.2.3`とそのバッチバージョンにマッチします。つまり、 +`~1.2.3`は`>= 1.2.3, < 1.3.0`と同等になります。 + +完全なバージョンマッチのシンタックスについては、[semver +documentation](https://github.com/Masterminds/semver#checking-version-constraints) +を参照してください。 + +### プレリリースバージョン + +上記のバージョンの制約は、プレリリースバージョンにはマッチしません。 +例えば、`version: ~1.2.3`は`version: ~1.2.4`にマッチしますが、`version: ~1.2.3-1` +にはマッチしません。 +以下はパッチレベルのマッチングだけでなく、プレリリースにも対応します: + +```yaml +version: ~1.2.3-0 +``` + +### リポジトリURL + +可能であれば、`https://`のリポジトリURLを使用し、その後、`http://`のURLを使用してください。 + +リポジトリが、そのインデックスファイルに追加されている場合、リポジトリの名前がURLの別名 +として使われます。`alias:`もしくは`@`の後に、リポジトリ名を付けて利用してください。 + +ファイルのURL(`file://...`)は固定されたデプロイパイプラインによって組み立てられた +チャートのための"特殊なケース"と考えられます。 + +[downloader plugins]({{< ref path="/docs/topics/plugins.md#downloader-plugins" lang="en" >}})を使用する場合、 +URLのスキームはプラグインに固有になります。注意としては、チャートの利用者はその依存関係を +ビルドもしくは更新するために、スキームをサポートするプラグインをインストールする必要があります。 + +`repository`フィールドが空白の場合、Helmは依存関係の管理操作を行うことができません。 +その場合、Helmはその依存関係が`name`で指定した名前と同じ名前の、 +`charts`フォルダーのサブディレクトリにあると推測します。 + +## コンディションとタグ + +_任意の_ 依存関係には、コンディションもしくはタグを追加するべきです。 + +コンディションの好ましい書き方: + +```yaml +condition: somechart.enabled +``` + +ここでは`somechart`が依存関係のあるチャートの名前です。 + +複数のサブチャート(依存関係)が共に任意もしくは取り替え可能な機能 +を提供する場合、これらのチャートは同じタグを共有するべきです。 + +例えば、`nginx`と`memcached`の両方がチャート内で、メインアプリケーション用に +パフォーマンスの最適化を提供している場合、そして、その機能を使用する際、その両方が +必要になる場合、このようなタグのセクションを含めるべきでしょう: + +```yaml +tags: + - webaccelerator +``` + +これにより、利用者はその機能のオンとオフを一つのタグで切り替えることができます。 diff --git a/content/ja/docs/chart_best_practices/labels.md b/content/ja/docs/chart_best_practices/labels.md new file mode 100644 index 0000000000..ddb5cf920a --- /dev/null +++ b/content/ja/docs/chart_best_practices/labels.md @@ -0,0 +1,46 @@ +--- +title: "ラベルとアノテーション" +description: "チャートの中でラベルとアノテーションを使用するためのベストプラクティスを解説します。" +weight: 5 +aliases: ["/docs/topics/chart_best_practices/labels/"] +--- + +ベストプラクティスのこの部分では、チャートの中でラベルとアノテーションを使用する際の +ベストプラクティスについて議論します。 + +## ラベルかアノテーションか? + +メタデータの項目は以下の条件でラベルにすべきです: + +- リソースを特定するためにKubernetesによって使用される場合 +- システムに問い合わせをする目的でオペレータに公開すると便利な場合 + +例えば、オペレータが特定のチャートの全てのインスタンスを便利に見つけられるように、 +ラベルとして`helm.sh/chart: NAME-VERSION`を使うことを推奨します。 + +メタデータの項目が問い合わせの目的で使用されない場合、代わりにアノテーションを +使うべきでしょう。 + +Helmフックは常にアノテーションです。 + +## 標準的なラベル + +次のテーブルはHelmチャートが使う、共通のラベルを定義しています。Helmそれ自体は +特定のラベルが存在することを必要としません。RECとマークされたラベルは使用を推奨され、 +グローバルな一貫性のためにチャートに記述される _べき_ です。 +OPTとマークされた項目は任意です。これらは慣用句として、あるいは一般的に使用されているもの +ではありますが、業務上頻繁に使用されるものではありません。 + +名前|ステータス|説明 +-----|------|---------- +`app.kubernetes.io/name` | REC | これはアプリ全体を反映した名前であるべきです。一般的には`{{ template "name" . }}`がこのために使われるでしょう。これは多くのKubernetesマニフェストで使用されるものであり、Helm特有のものではありません。 +`helm.sh/chart` | REC | これはチャート名とバージョンにすべきです: `{{ .Chart.Name }}-{{ .Chart.Version \| replace "+" "_" }}`. +`app.kubernetes.io/managed-by` | REC | これは常に`{{ .Release.Service }}`に設定するべきです。Helmで管理されているものを全て見つけるために使用されます。 +`app.kubernetes.io/instance` | REC | これは`{{ .Release.Name }}`にすべきです。 これは、同じアプリケーションの異なるインスタンスを区別するのに役立ちます。 +`app.kubernetes.io/version` | OPT | アプリのバージョンで、`{{ .Chart.AppVersion }}`に設定できます。 +`app.kubernetes.io/component` | OPT | これはアプリケーション内の違った役割示す共通のラベルです。例、 `app.kubernetes.io/component: frontend` +`app.kubernetes.io/part-of` | OPT | 複数のチャートとソフトウェアが一体となって一つのアプリケーションを構成している場合のラベル。例えば、ウェブサイトを生成するデータベースとアプリケーションソフトウェアなど。これは、対応するトップレベルのアプリケーションにも設定することができます。 + +Kubernetesの`app.kubernetes.io`プレフィックスが付いたラベルについて、 +[Kubernetes +documentation](https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/)でより詳細な情報を見つけることができます。 diff --git a/content/ja/docs/chart_best_practices/pods.md b/content/ja/docs/chart_best_practices/pods.md new file mode 100644 index 0000000000..9b7e71b0a1 --- /dev/null +++ b/content/ja/docs/chart_best_practices/pods.md @@ -0,0 +1,76 @@ +--- +title: "PodとPodテンプレート" +description: "チャートマニフェストの、PodとPodテンプレート部分のフォーマットについて説明します。" +weight: 6 +aliases: ["/docs/topics/chart_best_practices/pods/"] +--- + +ベストプラクティスのこの部分では、チャートマニフェストの、PodとPodテンプレート部分の +フォーマットについて説明します。 + +以下のリソースのリスト(非網羅的)がPodテンプレートを使用します: + +- Deployment +- ReplicationController +- ReplicaSet +- DaemonSet +- StatefulSet + +## イメージ + +コンテナイメージは固定されたタグ、もしくはイメージのSHAを使用するべきです。イメージは`latest`, +`head`,`canary`タグや、その他"浮いている"タグは使用するべきではありません。 + + +イメージは、簡単に入れ替えられるように、`values.yaml`に定義しても _良い_ +でしょう。 + +```yaml +image: {{ .Values.redisImage | quote }} +``` + +イメージとタグは、それぞれ別のフィールドとして`values.yaml`に定義しても _良い_ でしょう: + +```yaml +image: "{{ .Values.redisImage }}:{{ .Values.redisTag }}" +``` + +## ImagePullPolicy + +`helm create`はデフォルトで以下のようにして、`deployment.yaml`の +`imagePullPolicy`を`IfNotPresent`に設定します: + +```yaml +imagePullPolicy: {{ .Values.image.pullPolicy }} +``` + +そして、`values.yaml`: + +```yaml +image: + pullPolicy: IfNotPresent +``` + +同様に、Kubernetesは`imagePullPolicy`が定義されていない場合、デフォルトで`IfNotPresent`に +設定します。`IfNotPresent`以外の値が必要な場合、単純に`values.yaml`の値を必要な値に更新 +してください。 + +## Podテンプレートはselectorを宣言するべき + +全てのPodテンプレートセクションはselectorを指定するべきです。例えば: + +```yaml +selector: + matchLabels: + app.kubernetes.io/name: MyName +template: + metadata: + labels: + app.kubernetes.io/name: MyName +``` + +これはセットとPodの関係を作るため、良い慣習です。 + +しかし、Deploymentのようなセットでは、これはさらに重要になります。これがないと、 +_全ての_ ラベルのセットが一致するPodを選択するために使用され、もし、バージョンやリリース日のように、 +変化するラベルを使用していた場合、これが壊れることになります。 diff --git a/content/ja/docs/chart_best_practices/templates.md b/content/ja/docs/chart_best_practices/templates.md new file mode 100644 index 0000000000..dbcb1393c6 --- /dev/null +++ b/content/ja/docs/chart_best_practices/templates.md @@ -0,0 +1,205 @@ +--- +title: "テンプレート" +description: "テンプレートについての一般的な慣習です。" +weight: 3 +--- + +ベストプラクティスガイドのこの部分では、テンプレートについて焦点を合わせます。 + +## `templates/`の構造 + +`templates/`ディレクトリは次のように構造化されるべきです: + +- テンプレートファイルは、YAMLを出力するのであれば、`.yaml`の拡張子をつけるべきです。 + `.tpl`拡張子はフォーマットされない内容を出力するテンプレートファイルに使用することができます。 +- テンプレートファイルの名前はキャメルケースではなく、ハイフン区切り(`my-example-configmap.yaml`) + で命名すべきです。 +- それぞれのリソース定義は、テンプレートファイル毎に独立したものにすべきです。 +- テンプレートファイルの名前は、そのリソースの種類を名前に含めるべきです。e.g. + `foo-pod.yaml`, `bar-svc.yaml` + +## 定義されたテンプレートの名前 + +定義されたテンプレート(`{{ define }} `ディレクティブの中に作られたテンプレート)は +グローバルにアクセス可能です。つまり、チャートとそのサブチャート全てが、`{{ define }}` +で作成されたテンプレートにアクセスすることができます。 + +そのため、_定義されたテンプレート名は全て、名前空間を含んでいるべきです。_ + +正しい書き方: + +```yaml +{{- define "nginx.fullname" }} +{{/* ... */}} +{{ end -}} +``` + +正しくない書き方: + +```yaml +{{- define "fullname" -}} +{{/* ... */}} +{{ end -}} +``` +新しいチャートは常に、自動的にテンプレート名をベストプラクティスに応じて定義するため、 +`helm create`コマンド経由で作成することを強く推奨します。 + +## テンプレートのフォーマット + +テンプレートは _二つのスペース_ でインデントするべきです。(タブではなく) + +テンプレートディレクティブは、中括弧の開始の後と終わりの前にスペースを入れるべきです。 + +正しい書き方: +``` +{{ .foo }} +{{ print "foo" }} +{{- print "bar" -}} +``` + +正しくない書き方: +``` +{{.foo}} +{{print "foo"}} +{{-print "bar"-}} +``` + +可能な場合、テンプレートはスペースを詰めるべきです: + +```yaml +foo: + {{- range .Values.items }} + {{ . }} + {{ end -}} +``` + +ブロック(制御文など)は、テンプレートコードのフローを示すために +インデントすることができます。 + +``` +{{ if $foo -}} + {{- with .Bar }}Hello{{ end -}} +{{- end -}} +``` + +しかし、YAMLはスペース指向の言語のため、時折その慣習に従うことができません。 + +## 生成されたテンプレートのスペース + +生成されるテンプレートに含まれるスペースの量は最小限に抑えるのが望ましいです。 +特に、多数の空行が互いに隣接するべきではありません。 +しかし、時には(特に論理的なセクションの間の)空行は使っても良いでしょう。 + +ベストな書き方: + +```yaml +apiVersion: batch/v1 +kind: Job +metadata: + name: example + labels: + first: first + second: second +``` + +書いても良いコード: + +```yaml +apiVersion: batch/v1 +kind: Job + +metadata: + name: example + + labels: + first: first + second: second + +``` + +しかし、この書き方は避けるべきです: + +```yaml +apiVersion: batch/v1 +kind: Job + +metadata: + name: example + + + + + + labels: + first: first + + second: second + +``` + +## コメント(YAMLコメント vs. テンプレートコメント) + +YAMLとHelmテンプレートにはどちらもコメントの書き方があります。 + +YAMLコメント: +```yaml +# This is a comment +type: sprocket +``` + +テンプレートコメント: +```yaml +{{- /* +This is a comment. +*/}} +type: frobnitz +``` + +テンプレートコメントは、テンプレートの機能を文書化する際に使用されるべきで、例えば、 +定義されたテンプレートを説明する際に使用されます: + +```yaml +{{- /* +mychart.shortname provides a 6 char truncated version of the release name. +*/}} +{{ define "mychart.shortname" -}} +{{ .Release.Name | trunc 6 }} +{{- end -}} + +``` + +Helm使用者にとって(おそらく)デバッグ中に見るコメントとして便利な場合、テンプレートの中で、 +YAMLコメントが使われることがあります。 + +```yaml +# This may cause problems if the value is more than 100Gi +memory: {{ .Values.maxMem | quote }} +``` + +上のコメントは、ユーザーが`helm install --debug`を実行した時に見ることができますが、 +一方、`{{- /* */}}`の中のコメントは見ることができません。 + +## テンプレートとテンプレートの出力でのJSONの使用 + +YAMLはJSONのスーパーセットです。いくつかの場合、JSONの書き方は他のYAMLの表現よりも +読みやすい場合があります。 + +例えば、このYAMLは通常のYAMLのリストの表現方法に近いです: + +```yaml +arguments: + - "--dirname" + - "/foo" +``` + +しかし、JSONのリスト表現に落とし込んだ方が読みやすいでしょう: + +```yaml +arguments: ["--dirname", "/foo"] +``` + +JSONを読みやすさの向上のために使うことは良いことです。しかし、JSONの文法はより複雑な +構造を表現するために使うべきではありません。 + +YAMLの中に純粋なJSONを埋め込む(初期化コンテナの設定のような)必要がある場合は、 +もちろんJSONのフォーマットを使うのは適切でしょう。 diff --git a/content/ja/docs/chart_best_practices/values.md b/content/ja/docs/chart_best_practices/values.md new file mode 100644 index 0000000000..257ac1a58b --- /dev/null +++ b/content/ja/docs/chart_best_practices/values.md @@ -0,0 +1,151 @@ +--- +title: "値" +description: "どのように値を設定するかを解説します。" +weight: 2 +--- + +ベストプラクティスガイドのこの部分では、値の設定方法を解説します。 +チャートの`values.yaml`の書き方に重点を置いて、値を構造化して利用するおすすめの方法を解説します。 + +## 命名規則 + +変数名は小文字で始める必要があります。また、単語はキャメルケースで区切ってください。 + +正しい書き方: + +```yaml +chicken: true +chickenNoodleSoup: true +``` + +正しくない書き方: + +```yaml +Chicken: true # 最初を大文字にすると予約語と衝突することがあります +chicken-noodle-soup: true # ハイフンは使わないでください +``` + +ユーザー定義のパラメータと区別しやすくするため、Helmの全ての予約語は大文字で始まります。 +例) `.Release.Name`, `.Capabilities.KubeVersion` + +## フラット・ネスト構造の値 + +YAMLは柔軟な形式なので、値を深くネストすることも、フラットにすることもできます。 + +ネスト: + +```yaml +server: + name: nginx + port: 80 +``` + +フラット: + +```yaml +serverName: nginx +serverPort: 80 +``` + +ほとんどの場合、ネストよりフラットな方が好まれます。フラットな方がテンプレートの開発者・ユーザーがよりシンプルに理解できるからです。 + +ネストされた値を安全に扱うためには、全ての階層で値をチェックする必要があります。 + +``` +{{ if .Values.server }} + {{ default "none" .Values.server.name }} +{{ end }} +``` + +ネストされた全ての階層では値が存在するかをチェックする必要があります。 +その一方でフラット構成の場合、このようなチェックをせずにテンプレートを読みやすく、使いやすくすることができます。 + +``` +{{ default "none" .Values.serverName }} +``` + +関連する変数が多数あり、そのうちの少なくとも1つが必須の変数である場合は、 +読みやすさを向上させるためにネストされた値を使うことがあります。 + +## 型の明確化 + +YAMLの型強制ルールは直感に反することがあります。例えば `foo: false`と +`foo: "false"`は同じではありません。`foo: 12345678` のように大きな整数は、 +科学的表記に変換される場合があります。 + +型変換エラーを回避する最も簡単な方法は、文字列は明示的に扱い、その他全ては暗黙的に扱うことです。 +簡潔に言えば、_すべての文字列を引用する_ ということです。 + +多くの場合、整数キャストの問題を回避するには整数を文字列として格納し、 +テンプレートで`{{ int $value }}`のように使用して文字列から整数に戻すと便利です。 + +ほとんどの場合、明示的な型のタグが優先されるため、`foo: !!string 1234`は文字列の`1234`として扱われます。 +_ただし_、YAMLパーサーはタグを消費してしまうので、パースされた後は型情報が失われます。 + +## ユーザーがどのように値を扱うかについて考える + +値は3つの方法で設定することができます。 + +- チャートの`values.yaml`ファイル +- `helm install -f`、`helm upgrade -f`で渡されるファイル +- `helm install`、`helm upgrade`の`--set`、`--set-string` フラグで渡される値 + +値の構造を設計するときは、ユーザーが`-f`フラグや`--set`オプションで +値を上書きしたい場合があることに注意してください。 + +`--set`が一番表現力が制限されているので、`values.yaml`を書くにあたって最初に考えるべきことは、 +`--set`で簡単に上書きできるようにすることです。 + +そのような理由から、大抵の場合はマップを使用して値を構造化するほうがよいです。 + +`--set`の利用が難しい例: + +```yaml +servers: + - name: foo + port: 80 + - name: bar + port: 81 +``` + +上の例は、Helm `<=2.4` では `--set` で表現できません。Helm 2.5では fooのportを +`--set servers[0].port=80`と書くことができます。ユーザーが理解しにくいだけでなく、 +後に`servers`の順番が変更されたときにエラーが発生しやすくなります。 + +使いやすい例: + +```yaml +servers: + foo: + port: 80 + bar: + port: 81 +``` + +`--set servers.foo.port=80` +このように、fooのportをより明確に扱うことができます。 + +## `values.yaml`のドキュメント + +`values.yaml`で定義された全てのプロパティは文書化されているべきです。 +説明文は説明するプロパティ名で始めて、少なくとも1文以上書いてください。 + +正しくない例: + +```yaml +# the host name for the webserver +serverHost: example +serverPort: 9191 +``` + +正しい例: + +```yaml +# serverHost is the host name for the webserver +serverHost: example +# serverPort is the HTTP listener port for the webserver +serverPort: 9191 +``` + +各コメントをパラメータ名で始めるとドキュメントをgrepするのが簡単になるのに加え、 +文書化ツールが説明文をパラメータと確実に紐付けることができるようになります。 diff --git a/content/ja/docs/chart_template_guide/_index.md b/content/ja/docs/chart_template_guide/_index.md new file mode 100644 index 0000000000..962785c091 --- /dev/null +++ b/content/ja/docs/chart_template_guide/_index.md @@ -0,0 +1,24 @@ +--- +title: "チャートテンプレートガイド" +weight: 5 +--- + +# チャートテンプレート開発者ガイド + +このガイドでは、テンプレート言語に重点を置いて、 +Helm のチャートテンプレートの概要を説明します。 + +テンプレートは、Kubernetes が理解できる +YAML 形式のリソース記述であるマニフェストファイルを生成します。 +テンプレートの構造、テンプレートの使用方法、 +Go テンプレートの作成方法、作業のデバッグ方法について説明します。 + +このガイドでは、次の概念に焦点を当てています。 + +- Helm テンプレート言語 +- 値の使用 +- テンプレートを操作するためのテクニック + +このガイドは、Helm テンプレート言語の詳細を学ぶことを目的としています。 +他のガイドは、紹介資料、例、 +およびベストプラクティスを提供します。 diff --git a/content/ja/docs/chart_template_guide/data_types.md b/content/ja/docs/chart_template_guide/data_types.md new file mode 100644 index 0000000000..2e5ba000ee --- /dev/null +++ b/content/ja/docs/chart_template_guide/data_types.md @@ -0,0 +1,26 @@ +--- +title: "Appendix: Go データ型とテンプレート" +description: "テンプレート内の変数の概要。" +weight: 16 +--- + +Helm テンプレート言語は、厳密に型指定された Go プログラミング言語で実装されています。 +そのため、テンプレートの変数は _typed_ です。 +ほとんどの場合、変数は次のタイプのいずれかとして公開されます。 + +- string: テキストの文字列 +- bool: `true` または `false` +- int: 整数値 + (これの8、16、32、および 64 ビットの符号付きおよび符号なし変数もあります) +- float64: 64 ビットの浮動小数点値 + (これには 8、16、32 ビットの種類もあります) +- バイトスライス (`[]byte`)。バイナリデータを (潜在的に) 保持するためによく使用されます +- struct: プロパティとメソッドを持つオブジェクト +- 前のタイプのいずれかのスライス (インデックス付きリスト) +- 文字列キー付きマップ (`map[string]interface{}`) 値は + 前のタイプの1つです + +Go には他にも多くのタイプがあり、テンプレートでそれらの間で変換する必要がある場合があります。 +オブジェクトのタイプをデバッグする最も簡単な方法は、 +テンプレートで `printf "%t"` を介してオブジェクトを渡すことです。 +これにより、タイプが出力されます。`typeOf` および `kindOf` 関数も参照してください。 diff --git a/content/ja/docs/community/_index.md b/content/ja/docs/community/_index.md new file mode 100644 index 0000000000..844cd56cbd --- /dev/null +++ b/content/ja/docs/community/_index.md @@ -0,0 +1,9 @@ +--- +title: "コミュニティ" +weight: 7 +--- + +# コミュニティガイド + +Helm プロジェクト自体の開発プロセスと、貢献方法については、 +こちらをご覧ください。 diff --git a/content/ja/docs/community/developers.md b/content/ja/docs/community/developers.md new file mode 100644 index 0000000000..b1dc62bf83 --- /dev/null +++ b/content/ja/docs/community/developers.md @@ -0,0 +1,127 @@ +--- +title: "開発者ガイド" +description: "Helmを開発するための環境をセットアップする方法を説明します。" +weight: 1 +--- + +このガイドでは、Helmで開発するための環境をセットアップする方法について説明します。 + +## 必要な環境 + +- Goの最新バージョン +- kubectlおよびKubernetesクラスター (optional) +- Git + +## Helmをビルドする + +Makeを使用してプログラムを構築します。最も簡単な方法は次のとおりです: + +```console +$ make +``` + +注意: `$GOPATH/src/helm.sh/helm` のパスにて実行されていない場合、このコマンドは失敗します。 また、`build` +が関連するパッケージが見つけられないため、`helm.sh`ディレクトリをシンボリックリンクにしてはいけません。 + +このコマンドは必要に応じて依存関係をインストールし、`vendor/`ツリーを再ビルドしたのち、configurationを検証します。 その後に`helm`をコンパイルして`bin/helm`に配置します。 + +Helmをローカルで実行するには、`bin/helm`を実行してください。 + +- Helmは、macOSおよびAlpineを含んだほとんどのLinuxディストリビューションで動作することが知られています。 + +## テストの実行 + +すべてのテスト(`vendor/`のテストを除く)を実行するには、`make test`を実行してください。 前提条件として、[golangci-lint](https://golangci-lint.run) +をインストールする必要があります 。 + +## コントリビューションガイドライン + +私たちはコントリビューションを歓迎します。 このプロジェクトは、(a) +コードの品質を高く保ち(b)プロジェクトの一貫性を保ち(c)コントリビューションがオープンソースの法的要件に従うことを保証するため、いくつかのガイドラインを設定しました。 +私たちの目的はコントリビューターに負担をかけることではなく、ユーザーが利益を得ることができるようにエレガントで高品質なオープンソースコードを構築することです。 + +CONTRIBUTINGガイドを読み、理解していることを確認してください。 + +https://github.com/helm/helm/blob/main/CONTRIBUTING.md + +### コードの構造 + +Helmプロジェクトのコードは、以下のように構成されています。 + +- 個々のプログラムは`cmd/`にあります。`cmd/`内のコードはライブラリ再利用を目的として設計されていません。 +- 共有ライブラリは`pkg/`にあります。 +- `scripts/`ディレクトリには多数のユーティリティスクリプトがあります。これらのほとんどはCI/CDパイプラインによって使用されます。 + +Goの依存関係管理は流動的であり、Helmのライフサイクルの過程で変更される可能性があります。 依存関係を手動で管理 _しない_ ことをお勧めします。 その代わりに、プロジェクトの`Makefile`に依存して管理を行うことをお勧めします。 +Helm 3では、Goバージョン1.13以降を使用することをお勧めします。 + +### ドキュメントの作成 + +Helm 3以降、ドキュメントは独自のリポジトリに移動されました。 新しい機能を作成する場合は付属のドキュメントを作成して、[helm-www](https://github.com/helm/helm-www)にsubmitしてください。 + +例外: [Helm CLI output (英語)](https://helm.sh/docs/helm/) は `helm` のバイナリ自体から生成されます。 +このoutputを生成する方法については[Updating the Helm CLI Reference Docs](https://github.com/helm/helm-www#updating-the-helm-cli-reference-docs) +をご覧ください。 翻訳された場合、CLI出力は生成されず`/content//docs/helm`に生成されます。 + +### Git 規約 + +バージョン管理システムにはGitを使用しています。 +`main`ブランチは現在の開発候補の中心です。 リリースにはタグが付けられます。 + +GitHubのPull Requests(PRs)を介してコードの変更を受け付けています。 これを行うためのワークフローの一例は次のとおりです。 + +1. `$GOPATH/src` に移動して `mkdir helm.sh; cd helm.sh` を実行し、 `github.com/helm/helm` + のリポジトリを`git clone` します。 +2. リポジトリをあなたのGitHubアカウントにフォークします +3. あなたのリポジトリを`$GOPATH/src/helm.sh/helm`のリモートとして追加します。 +4. 新しい作業ブランチ (`git checkout -b feat/my-feature`) 作成し、そのブランチで作業を行います。 +5. レビューの準備ができましたら、あなたのブランチをGitHubにプッシュして新しいプルリクエストを開いてください。 + +Git commit messagesに関しては[Semantic Commit Messages](https://karma-runner.github.io/0.13/dev/git-commit-msg.html) +に従います +: + +``` +fix(helm): add --foo flag to 'helm install' + +When 'helm install --foo bar' is run, this will print "foo" in the +output regardless of the outcome of the installation. + +Closes #1234 +``` + +一般的なコミットタイプ: + +- fix: バグまたはエラーを修正 +- feat: 新機能を追加 +- docs: ドキュメントを変更 +- test: テストを改善する +- ref: 既存のコードのリファクタリング + +一般的なスコープ: + +- helm: The Helm CLI +- pkg/lint: lintパッケージ。どのパッケージでも同様の規則に従ってください +- `*`: 2つ以上のスコープ + +さらに読む: + +- [Deis Guidelines](https://github.com/deis/workflow/blob/master/src/contributing/submitting-a-pull-request.md) + がこのセクションのインスピレーションになりました。 +- Karma Runner はthe semantic commit messageの考えを [定義しています](https://karma-runner.github.io/0.13/dev/git-commit-msg.html)。 + +### Go 規約 + +Go coding style standardsに厳密に従っています。だいたいの場合`go fmt`を実行すればコードが美しくなります。 + +また、`go lint`および`gometalinter`によって推奨される規則に従います。 +`make test-style`を実行してスタイルの適合性をテストしてください。 + +さらに読む: + +- Effective Go では[formattingを導入しています](https://golang.org/doc/effective_go.html#formatting). +- The Go Wiki には + [formatting](https://github.com/golang/go/wiki/CodeReviewComments)に関して素晴らしい記事があります。 + +`make test`ターゲットを実行すると、単体テストが実行されるだけでなく、スタイルテストも実行されます。 +`make test`ターゲットが失敗する場合は、それが文体に起因するものであったとしても、あなたのPRがマージに向けた準備ができていないと判断されます。 diff --git a/content/ja/docs/community/history.md b/content/ja/docs/community/history.md new file mode 100644 index 0000000000..6fc8a5c8ee --- /dev/null +++ b/content/ja/docs/community/history.md @@ -0,0 +1,30 @@ +--- +title: "プロジェクトの歴史" +description: "プロジェクトの歴史の概要を提供します。" +weight: 4 +--- + +Helm は [CNCF の Graduated プロジェクト](https://helm.sh/blog/celebrating-helms-cncf-graduation/)です。 + +Helm は、現在 [Helm Classic](https://github.com/helm/helm-classic) として知られているものとして始まりました。 +これは、2015年に開始され、 +最初の KubeCon で導入された Deis プロジェクトです。 + +2016 年 1 月、プロジェクトは Kubernetes Deployment Manager と呼ばれる GCS ツールと統合され、 +プロジェクトは [Kubernetes](https://kubernetes.io) の下に移動されました。 +コードベースの統合の結果、 +Helm 2.0 がその年の後半にリリースされました。 +Helm 2 で生き残った Deployment Manager の主要な機能はサーバー側のコンポーネントで、 +最終的な Helm 2.0 リリースでは DM から Tiller に名前が変更されました。 + +Helm は、2018 年 6 月に Kubernetes サブプロジェクトから本格的な CNCF プロジェクトに昇格しました。 +Helm はトップレベルの管理組織を形成し、 +Monocular、Helm Chart Repo、Chart Museum、そして後に Helm Hub など、 +いくつかのプロジェクトが Helm プロジェクトに組み込まれました。 + +Helm 3 の開発サイクルが始まると、Tiller が削除され、 +Helm はクライアントツールであるという当初のビジョンに近づきました。 +ただし、Helm 3 は引き続き Kubernetes クラスター内のリリースを追跡しているため、 +チームが共同で Helm リリースのセットで作業することができます。Helm 3 は 2019 年 11 月にリリースされました。 + +Helm は、[2020 年 4 月に CNCF の Graduated プロジェクトになりました](https://www.cncf.io/announcement/2020/04/30/cloud-native-computing-foundation-announces-helm-graduation/)。 \ No newline at end of file diff --git a/content/ja/docs/community/localization.md b/content/ja/docs/community/localization.md new file mode 100644 index 0000000000..ccb94c28cd --- /dev/null +++ b/content/ja/docs/community/localization.md @@ -0,0 +1,112 @@ +--- +title: "Helm ドキュメントの国際化" +description: "Helm ドキュメントを国際化するための手順。" +weight: 5 +--- + +このガイドでは Helm ドキュメントをどのように国際化するかを説明します。 + +## はじめに + +翻訳への貢献にはドキュメントへの貢献と同様のプロセスを用います。翻訳は [helm-www](https://github.com/helm/helm-www) git リポジトリへの[プルリクエスト](https://help.github.com/ja/github/collaborating-with-issues-and-pull-requests/about-pull-requests)によって供給され、プルリクエストはウェブサイトの管理チームによってレビューされます。 + +### 2文字言語コード + +ドキュメントは [ISO 639-1 +標準](https://www.loc.gov/standards/iso639-2/php/code_list.php) 言語コードによって管理されます。例えば、韓国語の2文字コードは `ko` です。 + +コンテンツや設定でこの言語コードが使われます。3つ例を示します。 + +- `content` ディレクトリ内で言語コードがサブディレクトリとして存在し、国際化されたコンテンツがそれぞれのディレクトリに入っています。 +- `i18n` ディレクトリはそれぞれの言語について、ウェブサイトで使用されるフレーズについての設定ファイルを保有しています。それらのファイルは `[LANG]` がその言語の2文字コードとなるような `[LANG].toml` というパターンで命名されています。 +- トップレベルの `config.toml` ファイルではナビゲーションやその他の詳細が言語コードごとに管理されています。 + +言語コード `en` を持つ英語が、デフォルトの言語および翻訳元として用いられます。 + +### フォーク、ブランチ、変更、プルリクエスト + +翻訳に貢献するために、まずは Github の [helm-www リポジトリ](https://github.com/helm/helm-www)の[フォークを作る](https://help.github.com/ja/github/getting-started-with-github/fork-a-repo)ことから始めましょう。あなたはまずあなたのフォークに変更をコミットすることから始めるでしょう。 + +初期状態であなたのフォークは `main` として知られるデフォルトブランチに設定されているでしょう。あなたの変更を開発するあるいはプルリクエストを作成するためにブランチを使用してください。もしブランチについて不慣れなら[それらについて Github ドキュメントで読む](https://help.github.com/ja/github/collaborating-with-issues-and-pull-requests/about-branches)ことができます。 + +ブランチを作成出来たら、翻訳を追加したり、コンテンツを国際化したりしましょう。 + +注:helm は [Developers Certificate of +Origin](https://developercertificate.org/) を利用しています。すべてのコミットは署名されている必要があります。コミットを作成する際に `-s` か `--signoff` フラグを用いることで、あなたの Git に設定されている名前とメールアドレスを用いてコミットに署名することができます。詳細については [CONTRIBUTING.md](https://github.com/helm/helm-www/blob/main/CONTRIBUTING.md#sign-your-work) をご覧ください。 + +準備ができたら、[プルリクエスト](https://help.github.com/ja/github/collaborating-with-issues-and-pull-requests/about-pull-requests) を作成し、helm-www リポジトリに反映しましょう。 + +作成されたプルリクエストは管理者によってレビューされます。その過程についての詳細は [CONTRIBUTING.md](https://github.com/helm/helm-www/blob/main/CONTRIBUTING.md) を参照してください。 + +## コンテンツの翻訳 + +全ての Helm コンテンツを国際化するのは大きな仕事です。小さなことから初めて大丈夫です。時間をかけて翻訳を拡大することができます。 + +### 新たな言語を開始する + +新たな言語を開始するには以下の最低要件が必要です。 + +- `_index.md` ファイルを含む `content/[LANG]/docs` ディレクトリを追加する。これはドキュメントランディングページの最上位です。 +- `i18n` ディレクトリに `[LANG].toml` ファイルを作成する。まずは開始地点として `en.toml` ファイルをコピーすることができます。 +- 新たな言語を公開するため、`config.toml` ファイルにその言語のセクションを追加する。既に存在する言語のセクションを開始地点とすることができます。 + +### 翻訳 + +翻訳されたコンテンツは `content/[LANG]/docs` ディレクトリ内に存在する必要があります。それらは英語ソースと同じURLを持ちます。例えば、イントロダクションを韓国語に翻訳するなら以下のように英語ソースをコピーすると便利です。 + +```sh +mkdir -p content/ko/docs/intro +cp content/en/docs/intro/install.md content/ko/docs/intro/install.md +``` + +新しいファイルの内容を別の言語に翻訳することができます。 + +翻訳されていない英語ファイルのコピーを `content/[LANG]/` に追加しないでください。言語がその場所に存在する場合、未翻訳のページは自動的に英語にリダイレクトされます。翻訳には時間がかかるので、常に古いフォークではなく最新のドキュメントを翻訳するようにしてください。 + +全ての `aliases` 行をヘッダーセクションから削除するよう気をつけてください。`aliases: ["/docs/using_helm/"]` のような行は翻訳では持ちません。それらは新たなページには存在しない古いリンクへのリダイレクトです。 + +注:翻訳ツールが助けになるかもしれません。それには機械翻訳が含まれています。機械翻訳は公開前に編集される、またはネイティブ話者によって文法や意味をレビューされる必要があります。 + +## 言語間のナビゲーション + +![Screen Shot 2020-05-11 at 11 24 22 +AM](https://user-images.githubusercontent.com/686194/81597103-035de600-937a-11ea-9834-cd9dcef4e914.png) + +サイトグローバルな [config.toml](https://github.com/helm/helm-www/blob/main/config.toml#L83L89) ファイルで言語ナビゲーションが設定されています。 + +新たな言語を追加するには、上で定義した新たな[2文字言語コード](./localization/#2文字言語コード)を追加する必要があります。例: + +``` +# Korean +[languages.ko] +title = "Helm" +description = "Helm - The Kubernetes Package Manager." +contentDir = "content/ko" +languageName = "한국어 Korean" +weight = 1 +``` + +## 内部リンクの解決 + +翻訳されたコンテンツは時々別言語にしか存在しないページへのリンクを含んでいるでしょう。これによって[ビルドエラー](https://app.netlify.com/sites/helm-merge/deploys)が発生します。例: + +``` +12:45:31 PM: htmltest started at 12:45:30 on app +12:45:31 PM: ======================================================================== +12:45:31 PM: ko/docs/chart_template_guide/accessing_files/index.html +12:45:31 PM: hash does not exist --- ko/docs/chart_template_guide/accessing_files/index.html --> #basic-example +12:45:31 PM: ✘✘✘ failed in 197.566561ms +12:45:31 PM: 1 error in 212 documents +``` + +これを解決するために、あなたのコンテンツの内部リンクを確認する必要があります。 + +* アンカーリンクは翻訳された `id` の値を反映する必要があります。 +* 内部リンクを修正する必要があります。 + +存在しない _(もしくはまだ翻訳されていない)_ 内部ページについては、修正がされるまでサイトがビルドされません。代わりに、下記のようにコンテンツが _存在する_ 別の言語にURLを向けることができます。 + + +`< relref path="/docs/topics/library_charts.md" lang="en" >` + +詳細については [言語間相互リファレンスについての Hugo ドキュメント](https://gohugo.io/content-management/cross-references/#link-to-another-language-version) をご覧ください。 diff --git a/content/ja/docs/faq/_index.md b/content/ja/docs/faq/_index.md new file mode 100644 index 0000000000..910f43ea27 --- /dev/null +++ b/content/ja/docs/faq/_index.md @@ -0,0 +1,487 @@ +--- +title: "よくある質問" +weight: 8 +--- + +# よくある質問 + +> Helm 2 と Helm 3 の主な違いはなんですか? +> このページでは、最もよくある質問に答えることで、理解の助けとなる事柄を説明します。 + +このドキュメントを改善する**あなたの助けを歓迎します**。情報の追加、訂正、削除などを行うには、[issue を作る](https://github.com/helm/helm-www/issues)か、pull request を送ってください。 + +## Helm 2 からの変更点 + +以下に、Helm 3 で導入されたすべての主要な変更の包括的なリストを示します。 + +### Tiller の削除 + + +Helm 2 の開発サイクルの中で、私たちは Tiller を導入しました。Tiller は共有クラスターで作業をするチームに対して重要な役割を果たしました。Tillerのおかげで複数の異なるオペレータが同じリリースセットとやり取りできるようになったのです。 + +ロールベースアクセス制御 (RBAC) が Kubernetes 1.6 でデフォルトで有効になると、Tiller を本番環境で使用し続けるのはしだいに管理が難しくなっていきました。セキュリティポリシーには非常に多くの可能性があるため、私たちはデフォルトでパーミッシブな設定にする立場を取りました。このおかげで、初めてのユーザーはセキュリティ制御に頭を悩ませずに Helm と Kubernetes を試せるようになりました。残念ながらこのパーミッシブな設定は、本来は持つべきではないユーザーに広範な権限を与えてしまう可能性があります。DevOps や SRE がマルチテナントのクラスターに Tiller をインストールするときには、追加のオペレーションのステップを学ばなければなりませんでした。 + +コミュニティメンバーの特定のシナリオ下での Helm の使い方について調査をした結果、Tiller のリリース管理システムがステートを保持して Helm のリリース情報のセントラルハブとして動作するためには、クラスタ内のオペレータに依存する必要はなかったことがわかりました。 + +Tiller の主目的は Tiller がなくても実現できたことがわかったため、Helm 3 に関して私たちが下した最初の決定は Tiller を完全に取り除くことでした。 + +Tiller を取り除くと、Helm セキュリティモデルは著しく単純化されました。このおかげで Helm 3 は、最近の Kubernetes が持つモダンなセキュリティ、ID、認証の機能のすべてをサポートできるようになりました。Helm の権限は [kubeconfig +file](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/) を使用して評価されます。クラスタ管理者は要求に合った任意の粒度でユーザー権限を制限できます。リリースは今でもクラスター内に保存され、Helm の他の機能もそのまま変わりません。 + +### アップグレード戦略の改善: 3方向戦略的マージパッチ (3-way Strategic Merge Patches) + +Helm 2 では、2方向戦略的マージパッチが使用されていました。アップグレード時には、最新のチャートのマニフェストと (`helm upgrade` 中に) 与えられたチャートのマニフェストを比較します。Helm 2 はこの2つのチャート間で変更を比較して、Kubernetes 内のリソースに適用する必要がある変更を決定します。もしクラスターへの変更がチャート外で (たとえば `kubectl edit` などで) 適用されていた場合、この変更は考慮されません。その結果、リソースは過去の状態にロールバックできなくなります。Helm は最後に適用されたチャートのマニフェストだけを最新状態とみなすため、チャートの状態に変更がなければ、現在の状態は変更されていないと判断されるためです。 + +Helm 3 では、新しく3方向戦略的マージパッチが使われるようになります。パッチの生成をするときに、Helm は古いマニフェスト、その現在の状態、新しいマニフェストを考慮します。 + +#### 例 + +Let's go through a few common examples what this change impacts. + +##### 実際の状態が変更した時点へのロールバック + +Your team just deployed their application to production on Kubernetes using +Helm. The chart contains a Deployment object where the number of replicas is set +to three: + +```console +$ helm install myapp ./myapp +``` + +A new developer joins the team. On their first day while observing the +production cluster, a horrible coffee-spilling-on-the-keyboard accident happens +and they `kubectl scale` the production deployment from three replicas down to +zero. + +```console +$ kubectl scale --replicas=0 deployment/myapp +``` + +Another developer on your team notices that the production site is down and +decides to rollback the release to its previous state: + +```console +$ helm rollback myapp +``` + +What happens? + +In Helm 2, it would generate a patch, comparing the old manifest against the new +manifest. Because this is a rollback, it's the same manifest. Helm would +determine that there is nothing to change because there is no difference between +the old manifest and the new manifest. The replica count continues to stay at +zero. Panic ensues. + +In Helm 3, the patch is generated using the old manifest, the live state, and +the new manifest. Helm recognizes that the old state was at three, the live +state is at zero and the new manifest wishes to change it back to three, so it +generates a patch to change the state back to three. + +##### 実際の状態が変更した時点へのアップグレード + +Many service meshes and other controller-based applications inject data into +Kubernetes objects. This can be something like a sidecar, labels, or other +information. Previously if you had the given manifest rendered from a Chart: + +```yaml +containers: +- name: server + image: nginx:2.0.0 +``` + +And the live state was modified by another application to + +```yaml +containers: +- name: server + image: nginx:2.0.0 +- name: my-injected-sidecar + image: my-cool-mesh:1.0.0 +``` + +Now, you want to upgrade the `nginx` image tag to `2.1.0`. So, you upgrade to a +chart with the given manifest: + +```yaml +containers: +- name: server + image: nginx:2.1.0 +``` + +What happens? + +In Helm 2, Helm generates a patch of the `containers` object between the old +manifest and the new manifest. The cluster's live state is not considered during +the patch generation. + +The cluster's live state is modified to look like the following: + +```yaml +containers: +- name: server + image: nginx:2.1.0 +``` + +The sidecar pod is removed from live state. More panic ensues. + +In Helm 3, Helm generates a patch of the `containers` object between the old +manifest, the live state, and the new manifest. It notices that the new manifest +changes the image tag to `2.1.0`, but live state contains a sidecar container. + +The cluster's live state is modified to look like the following: + +```yaml +containers: +- name: server + image: nginx:2.1.0 +- name: my-injected-sidecar + image: my-cool-mesh:1.0.0 +``` + +### リリース名が名前空間でスコープされるようになった + +Tiller の削除に伴い、各リリースの情報はどこか別の場所に移動する必要が出てきました。Helm 2 では、リリースの情報は Tiller と同じ名前空間に保存されていました。実際には、一度でもリリースで名前が使われてしまうと、たとえ他の名前空間にデプロイしたとしても、他のリリースが同じ名前を使えないということです。 + +Helm 3 では、特定のリリースの情報は新しくリリース自体と同じ名前空間に保存されるようになりました。つまり、これからはユーザーが `helm install wrodpress stable/wordpress` というコマンドを2つの別の名前空間で実行できるようになったということです。それぞれのリリースは、現在の名前空間のコンテキストを切り替えることで (例: `helm list --namespace foo`)、`helm list` を使用して参照できます。 + +ネイティブのクラスターの名前空間に大きく近づけたことにより、`helm list` コマンドはデフォルトではすべてのリリースを一覧しなくなりました。代わりに、現在の Kubernetes のコンテキストの名前空間 (たとえば、`kubectl config view --minify` などを実行すると表示される名前空間) の中にあるリリースだけが表示されるようになります。Helm 2 に近い動作にするには、`helm list` に `--all-namespaces` フラッグを与える必要があります。 + +### Secret がデフォルトのストレージドライバーになった + +Helm 3 からは、Secret が[デフォルトのストレージドライバー](/ja/docs/topics/advanced/#ストレージバックエンド)として使われるようになりました。Helm 2 では、ConfigMap がデフォルトでリリース情報を保存するために使用されていました。Helm 2.7.0 でリリース情報を保存するために Secret を使用する新しいストレージバックエンドが実装され、Helm 3 からはデフォルトで使用されるようになりました。 + +Helm 3 で Secret がデフォルトに変更されたことで、Kubernetes のリリースの Secret の暗号化と組み合わせて、チャートを保護する際のセキュリティが強化できます。 + +Kubernetesでのシークレット暗号化のリリースに関連してチャートを保護する際のセキュリティが強化されます。 + +[Secret の保存時の暗号化](https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/)は Kubernetes 1.7 でアルファ版の機能として利用可能になり、Kubernetes 1.13 で安定版になりました。これを利用することで、ユーザーは Helm のリリースのメタデータを保存時に暗号化できるようになるため、あとで Vault などを利用する場合によい出発地点となります。 + +### Go の import path の変更 + +Helm 3 では、Helm は Go のインポートパスを `k8s.io/helm` から `helm.sh/helm/v3` に変更しました。Helm 3 の Go クライアントライブラリをアップグレードする場合には、手元のインポートパスも変更するようにしてください。 + +### Capabilities + +レンダリングステージで利用可能な `.Capabilities` 組み込みオブジェクトが簡略されました。 + +[ビルトインオブジェクト](/docs/chart_template_guide/builtin_objects/) + +### チャートの Values の JSONSchema による検証 + +チャートの値に JSON Schema で制約を与えられるようになりました。これにより、ユーザーから与えられた値がチャートのメンテナが作ったスキーマに従っていることが保証されるため、ユーザーが間違った値をチャートに与えた場合によりよいエラー報告を行えるようになります。 + +検証は次のいずれかのコマンドが呼ばれたときに行われます。 + +* `helm install` +* `helm upgrade` +* `helm template` +* `helm lint` + +詳しい情報は、ドキュメントの [Schema files](/docs/topics/charts#schema-files) をご覧ください。 + +### `requirements.yaml` の `Chart.yaml` への統合 + +チャートの依存関係の管理システムは、requirements.yaml と +requirements.lock から、Chart.yaml と Chart.lock に変更されました。私たちは、Helm 3 向けの新しいチャートは新しいフォーマットを使用することを推奨します。しかし、Helm 3 は現在でも Chart API バージョン 1 (`v1`) も理解できるため、既存の `requirements.yaml` ファイルを読み込みます。 + +Helm 2 の `requirements.yaml` は以下のような形式でした。 + +```yaml +dependencies: +- name: mariadb + version: 5.x.x + repository: https://charts.helm.sh/stable + condition: mariadb.enabled + tags: + - database +``` + +Helm 3 でも依存関係は同じように表現されますが、`Chart.yaml` 以下に移動されます。 + +```yaml +dependencies: +- name: mariadb + version: 5.x.x + repository: https://charts.helm.sh/stable + condition: mariadb.enabled + tags: + - database +``` + +現在でもチャートは `charts/` ディレクトリに配置されるため、`charts/` ディレクトリに追加されたサブチャートは修正なしで動作し続けます。 + +### Name (または --generate-name) がインストール時に必須となった + +Helm 2 では、名前が与えられなかった場合に、自動生成された名前が設定されるようになっていました。本番環境では、この機能は役に立つ場合よりも迷惑になる場合のほうが多いことがわかりました。そのため、Helm 3 では、`helm install` に名前が与えられなかった場合には Helm がエラーを返します。 + +まだ名前の自動生成が必要なユーザーは、`--generate-name` フラグを使用すると名前を自動生成できます。 + +### チャートを OCI レジストリに push する + +これは Helm 3 で導入された実験的な機能です。使用するには、環境変数 `HELM_EXPERIMENTAL_OCI=1` を設定してください。 + +At a high level, a Chart Repository is a location where Charts can be stored and +shared. The Helm client packs and ships Helm Charts to a Chart Repository. +Simply put, a Chart Repository is a basic HTTP server that houses an index.yaml +file and some packaged charts. + +While there are several benefits to the Chart Repository API meeting the most +basic storage requirements, a few drawbacks have started to show: + +- Chart Repositories have a very hard time abstracting most of the security + implementations required in a production environment. Having a standard API + for authentication and authorization is very important in production + scenarios. +- Helm’s Chart provenance tools used for signing and verifying the integrity and + origin of a chart are an optional piece of the Chart publishing process. +- In multi-tenant scenarios, the same Chart can be uploaded by another tenant, + costing twice the storage cost to store the same content. Smarter chart + repositories have been designed to handle this, but it’s not a part of the + formal specification. +- Using a single index file for search, metadata information, and fetching + Charts has made it difficult or clunky to design around in secure multi-tenant + implementations. + +Docker’s Distribution project (also known as Docker Registry v2) is the +successor to the Docker Registry project. Many major cloud vendors have a +product offering of the Distribution project, and with so many vendors offering +the same product, the Distribution project has benefited from many years of +hardening, security best practices, and battle-testing. + +Please have a look at `helm help chart` and `helm help registry` for more +information on how to package a chart and push it to a Docker registry. + +For more info, please see [this page](/docs/topics/registries/). + +### `helm serve` の廃止 + +`helm serve` ran a local Chart Repository on your machine for development +purposes. However, it didn't receive much uptake as a development tool and had +numerous issues with its design. In the end, we decided to remove it and split +it out as a plugin. + +For a similar experience to `helm serve`, have a look at the local filesystem +storage option in +[ChartMuseum](https://chartmuseum.com/docs/#using-with-local-filesystem-storage) +and the [servecm plugin](https://github.com/jdolitsky/helm-servecm). + + +### ライブラリチャートのサポート + +Helm 3 supports a class of chart called a “library chart”. This is a chart that +is shared by other charts, but does not create any release artifacts of its own. +A library chart’s templates can only declare `define` elements. Globally scoped +non-`define` content is simply ignored. This allows users to re-use and share +snippets of code that can be re-used across many charts, avoiding redundancy and +keeping charts [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself). + +Library charts are declared in the dependencies directive in Chart.yaml, and are +installed and managed like any other chart. + +```yaml +dependencies: + - name: mylib + version: 1.x.x + repository: quay.io +``` + +We’re very excited to see the use cases this feature opens up for chart +developers, as well as any best practices that arise from consuming library +charts. + +### Chart.yaml apiVersion のバージョンアップ + +With the introduction of library chart support and the consolidation of +requirements.yaml into Chart.yaml, clients that understood Helm 2's package +format won't understand these new features. So, we bumped the apiVersion in +Chart.yaml from `v1` to `v2`. + +`helm create` now creates charts using this new format, so the default +apiVersion was bumped there as well. + +Clients wishing to support both versions of Helm charts should inspect the +`apiVersion` field in Chart.yaml to understand how to parse the package format. + +### XDG のベースディレクトリのサポート + +[XDG ベースディレクトリの仕様](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html)は、ファイルシステム上の設定、データ、キャッシュの各ファイルの格納場所を定めたポータブルな標準です。 + +In Helm 2, Helm stored all this information in `~/.helm` (affectionately known +as `helm home`), which could be changed by setting the `$HELM_HOME` environment +variable, or by using the global flag `--home`. + +In Helm 3, Helm now respects the following environment variables as per the XDG +Base Directory Specification: + +- `$XDG_CACHE_HOME` +- `$XDG_CONFIG_HOME` +- `$XDG_DATA_HOME` + +Helm plugins are still passed `$HELM_HOME` as an alias to `$XDG_DATA_HOME` for +backwards compatibility with plugins looking to use `$HELM_HOME` as a scratchpad +environment. + +Several new environment variables are also passed in to the plugin's environment +to accommodate this change: + +- `$HELM_PATH_CACHE` for the cache path +- `$HELM_PATH_CONFIG` for the config path +- `$HELM_PATH_DATA` for the data path + +Helm plugins looking to support Helm 3 should consider using these new +environment variables instead. + +### CLI コマンドの名前変更 + +In order to better align the verbiage from other package managers, `helm delete` +was re-named to `helm uninstall`. `helm delete` is still retained as an alias to +`helm uninstall`, so either form can be used. + +In Helm 2, in order to purge the release ledger, the `--purge` flag had to be +provided. This functionality is now enabled by default. To retain the previous +behavior, use `helm uninstall --keep-history`. + +Additionally, several other commands were re-named to accommodate the same +conventions: + +- `helm inspect` -> `helm show` +- `helm fetch` -> `helm pull` + +These commands have also retained their older verbs as aliases, so you can +continue to use them in either form. + +### 名前空間の自動生成 + +When creating a release in a namespace that does not exist, Helm 2 created the +namespace. Helm 3 follows the behavior of other Kubernetes tooling and returns +an error if the namespace does not exist. Helm 3 will create the namespace if +you explicitly specify `--create-namespace` flag. + +### .Chart.ApiVersion に何が起こりましたか? + +Helm follows the typical convention for CamelCasing which is to capitalize an +acronym. We have done this elsewhere in the code, such as with +`.Capabilities.APIVersions.Has`. In Helm v3, we corrected `.Chart.ApiVersion` +to follow this pattern, renaming it to `.Chart.APIVersion`. + +## インストール + +### Fedora などの Linux ディストリビューション向けの Helm のネイティブパッケージが存在しないのはなぜですか? + +The Helm project does not maintain packages for operating systems and +environments. The Helm community may provide native packages and if the Helm +project is made aware of them they will be listed. This is how the Homebrew +formula was started and listed. If you're interested in maintaining a package, +we'd love it. + +### なぜ `curl ...|bash` で実行するスクリプトを提供しているのですか? + +There is a script in our repository (`scripts/get-helm-3`) that can be executed +as a `curl ..|bash` script. The transfers are all protected by HTTPS, and the +script does some auditing of the packages it fetches. However, the script has +all the usual dangers of any shell script. + +We provide it because it is useful, but we suggest that users carefully read the +script first. What we'd really like, though, are better packaged releases of +Helm. + +### Helm クライアントのファイルをデフォルト以外の場所に配置するにはどうすればいいですか? + +Helm uses the XDG structure for storing files. There are environment variables +you can use to override these locations: + +- `$XDG_CACHE_HOME`: set an alternative location for storing cached files. +- `$XDG_CONFIG_HOME`: set an alternative location for storing Helm + configuration. +- `$XDG_DATA_HOME`: set an alternative location for storing Helm data. + +Note that if you have existing repositories, you will need to re-add them with +`helm repo add...`. + +## アンインストール + +### ローカルの Helm を削除したいです。Helm の全ファイルはどこにありますか? + +Along with the `helm` binary, Helm stores some files in the following locations: + +- $XDG_CACHE_HOME +- $XDG_CONFIG_HOME +- $XDG_DATA_HOME + +The following table gives the default folder for each of these, by OS: + +| Operating System | Cache Path | Configuration Path | Data Path | +|------------------|-----------------------------|----------------------------------|---------------------------| +| Linux | `$HOME/.cache/helm ` | `$HOME/.config/helm ` | `$HOME/.local/share/helm` | +| macOS | `$HOME/Library/Caches/helm` | `$HOME/Library/Preferences/helm` | `$HOME/Library/helm ` | +| Windows | `%TEMP%\helm ` | `%APPDATA%\helm ` | `%APPDATA%\helm` | + +## トラブルシューティング + +### GKE (Google Container Engine) 上で "No SSH tunnels currently open" というメッセージが表示されました + +``` +Error: Error forwarding ports: error upgrading connection: No SSH tunnels currently open. Were the targets able to accept an ssh-key for user "gke-[redacted]"? +``` + +エラーメッセージの変種には次のようなものもあります。 + +``` +Unable to connect to the server: x509: certificate signed by unknown authority +``` + +The issue is that your local Kubernetes config file must have the correct +credentials. + +When you create a cluster on GKE, it will give you credentials, including SSL +certificates and certificate authorities. These need to be stored in a +Kubernetes config file (Default: `~/.kube/config` so that `kubectl` and `helm` +can access them. + +### Helm 2 からのマイグレーション後、`helm list` リリースの一部 (または全部) が表示されません + +It is likely that you have missed the fact that Helm 3 now uses cluster +namespaces throughout to scope releases. This means that for all commands +referencing a release you must either: + +* rely on the current namespace in the active kubernetes context (as described + by the `kubectl config view --minify` command), +* specify the correct namespace using the `--namespace`/`-n` flag, or +* for the `helm list` command, specify the `--all-namespaces`/`-A` flag + +This applies to `helm ls`, `helm uninstall`, and all other `helm` commands +referencing a release. + +### macOS 上で `/etc/.mdns_debug` というファイルへのアクセスがあります。なぜですか? + +We are aware of a case on macOS where Helm will try to access a file named +`/etc/.mdns_debug`. If the file exists, Helm holds the file handle open while it +executes. + +This is caused by macOS's MDNS library. It attempts to load that file to read +debugging settings (if enabled). The file handle probably should not be held open, and +this issue has been reported to Apple. However, it is macOS, not Helm, that causes this +behavior. + +If you do not want Helm to load this file, you may be able to compile Helm to as +a static library that does not use the host network stack. Doing so will inflate the +binary size of Helm, but will prevent the file from being open. + +This issue was originally flagged as a potential security problem. But it has since +been determined that there is no flaw or vulnerability caused by this behavior. + +### 以前は動作していた helm repo add が失敗する + +In helm 3.3.1 and before, the command `helm repo add ` will give +no output if you attempt to add a repo which already exists. The flag +`--no-update` would raise an error if the repo was already registered. + +In helm 3.3.2 and beyond, an attempt to add an existing repo will error: + +`Error: repository name (reponame) already exists, please specify a different name` + +The default behavior is now reversed. `--no-update` is now ignored, while if you +want to replace (overwrite) an existing repo, you can use `--force-update`. + +This is due to a breaking change for a security fix as explained in the [Helm +3.3.2 release notes](https://github.com/helm/helm/releases/tag/v3.3.2). diff --git a/content/ja/docs/glossary/_index.md b/content/ja/docs/glossary/_index.md new file mode 100644 index 0000000000..686d5f2c16 --- /dev/null +++ b/content/ja/docs/glossary/_index.md @@ -0,0 +1,160 @@ +--- +title: "用語集" +description: "Helm のアーキテクチャのコンポーネントを説明するために使用される用語。" +weight: 9 +--- + +# 用語集 + +## チャート + +Kubernetes リソースのセットを Kubernetes クラスターにインストールするのに +十分な情報が含まれている Helm パッケージ。 + +チャートには、`Chart.yaml` ファイル、テンプレート、デフォルト値 (`values.yaml`)、 +依存関係が含まれています。 + +チャートは明確に定義されたディレクトリ構造で開発され、 +_Chart アーカイブ_ と呼ばれるアーカイブ形式にパッケージ化されます。 + +## Chart アーカイブ + +_Chart アーカイブ_ は、tar 形式で gzip 圧縮された (オプションで署名された) チャートです。 + +## チャートの依存関係 (サブチャート) + +チャートは他のチャートに依存する場合があります。依存関係が発生する方法は2つあります。 + +- ソフトな依存関係: 別のチャートがクラスターにインストールされていないと、チャートが機能しない可能性があります。 + Helm はこの場合のツールを提供していません。 + この場合、依存関係は個別に管理できます。 +- ハードな依存関係: チャートには、(`charts/` ディレクトリ内に) 依存する別のチャートが含まれる場合があります。 + この場合、チャートをインストールすると、 + その依存関係がすべてインストールされます。 + この場合、チャートとその依存関係はコレクションとして管理されます。 + +チャートが (`helm package` を介して) パッケージ化されると、 +そのすべてのハードな依存関係がチャートにバンドルされます。 + +## チャートのバージョン + +チャートは、[SemVer 2 仕様](https://semver.org) に従ってバージョン管理されています。 +すべてのチャートにバージョン番号が必要です。 + +## Chart.yaml + +チャートに関する情報は、`Chart.yaml` と呼ばれる特別なファイルに保存されます。 +すべてのチャートにこのファイルが必要です。 + +## Helm (と helm) + +Helm は Kubernetes のパッケージマネージャーです。 +オペレーティングシステムのパッケージマネージャーを使用すると、OS にツールを簡単にインストールできます。 +Helm を使用すると、アプリケーションやリソースを Kubernetes クラスターに簡単にインストールできます。 + +_Helm_ はプロジェクトの名前ですが、コマンドラインクライアントの名前も `helm` です。 +慣例により、プロジェクトについて言うとき、_Helm_ は大文字です。 +クライアントの場合、_helm_ は小文字です。 + +## Helm 設定ファイル (XDG) + +Helm は構成ファイルを XDG ディレクトリに保存します。 +これらのディレクトリは、`helm` が初めて実行されたときに作成されます。 + +## Kube Config (KUBECONFIG) + +Helm クライアントは、_Kube config_ ファイル形式のファイルを使用して、 +Kubernetes クラスターについて学習します。 +デフォルトでは、Helm はこのファイルを `kubectl` が作成した場所 (`$HOME/.kube/config`) で見つけようとします。 + +## Lint (Linting) + +チャートを _lint_ するには、それが Helm チャート標準の規則と要件に従っていることを検証します。 +Helm はこれを行うためのツール、 +特に `helm lint` コマンドを提供します。 + +## Provenance (Provenance ファイル) + +Helm チャートには、チャートの出所とその内容に関する情報を提供する +_Provenance ファイル_ が添付されている場合があります。 + +Provenance ファイルは、Helm のセキュリティストーリーの一部です。 +Provenance には、Chart アーカイブファイルの暗号化ハッシュ、Chart.yaml データ、 +および署名ブロック (OpenPGP "clearsign" ブロック) が含まれています。 +キーチェーンと組み合わせると、チャートユーザーは次のことができるようになります。 + +- チャートが信頼できる当事者によって署名されたことを検証する +- チャートのファイルが改ざんされていないことを検証する +- チャートのメタデータ (`Chart.yaml`) の内容を検証する +- チャートをその Provenance データにすばやく一致させる + +Provenance ファイルには `.prov` 拡張子が付いており、 +チャートリポジトリサーバーまたはその他の HTTP サーバーから提供できます。 + +## リリース + +チャートがインストールされると、 +Helm ライブラリはそのインストールを追跡するための _リリース_ を作成します。 + +1 つのチャートを同じクラスターに何度もインストールして、さまざまなリリースを作成できます。 +たとえば、`helm install` を異なるリリース名で 3 回実行することで、 +3 つの PostgreSQL データベースをインストールできます。 + +## リリース番号 (リリースバージョン) + +1 つのリリースを複数回更新することができます。 +シーケンシャルカウンタは、リリースの変更を追跡するために使用されます。 +最初に `helm install` を実行すると、_リリース番号_ は 1 になります。 +リリースがアップグレードされたり、ロールバックされたりするたびに、リリース番号は増加します。 + +## ロールバック + +リリースは、新しいチャートまたは構成にアップグレードできます。 +ただし、リリース履歴が保存されているため、リリースを前のリリース番号に _ロールバックする_ こともできます。 +これは、`helm rollback` コマンドで行われます。 + +重要なのは、ロールバックされたリリースには新しいリリース番号が付与されます。 + +| 操作 | リリース番号 | +|------------|------------------------------------------------------| +| インストール | リリース 1 | +| アップグレード | リリース 2 | +| アップグレード | リリース 3 | +| ロールバック 1 | リリース 4 (ただし リリース 1 と同じ構成を実行している) | + +上の表は、インストール、アップグレード、およびロールバックで +リリース番号がどのように増加するかを示しています。 + +## Helm ライブラリ (または SDK) + +Helm ライブラリ (または SDK) は、Kubernetes API サーバーと直接対話して、 +Kubernetes リソースをインストール、アップグレード、クエリ、および削除する Go コードを指します。 +プロジェクトにインポートして、 +CLI の代わりに Helm をクライアントライブラリとして使用できます。 + +## リポジトリ (レポ, チャートリポジトリ) + +Helm チャートは、_チャートリポジトリ_ (_リポジトリ_、または単に_レポ_) と呼ばれる +専用の HTTP サーバに保存できます。 + +チャートリポジトリサーバは、 +チャートのバッチを記述する `index.yaml` ファイルを提供できるシンプルな HTTP サーバであり、 +各チャートのダウンロード元に関する情報を提供します。 +(多くのチャートリポジトリは、チャートと `index.yaml` ファイルを提供します。) + +Helm クライアントは、0個以上のチャートリポジトリを指すことができます。 +デフォルトでは、Helm クライアントはチャートリポジトリで構成されていません。 +チャートリポジトリは、`helm repo add` コマンドを使用していつでも追加できます。 + +## Values (Values ファイル, values.yaml) + +Values は、テンプレートのデフォルトを独自の情報で上書きする方法を提供します。 + +Helm チャートは「パラメータ化」されています。 +つまり、チャートの開発者は、インストール時にオーバーライドできる構成を公開することがあります。 +たとえば、チャートは、サービスのユーザー名を設定できる `username` フィールドを公開する場合があります。 + +これらの公開された変数は、Helm の用語では _values_ と呼ばれます。 + +Values は、`helm install` および `helm upgrade` の操作中に直接渡すか、 +または `values.yaml` ファイルを使用して設定できます。 diff --git a/content/ja/docs/helm/_index.md b/content/ja/docs/helm/_index.md new file mode 100644 index 0000000000..3c186ba87b --- /dev/null +++ b/content/ja/docs/helm/_index.md @@ -0,0 +1,10 @@ +--- +title: "Helm コマンド" +description: "helm CLI コマンドの完全なリストのドキュメント。" +weight: 6 +slug: helm +--- + +# Helm コマンド + +ここでは、Helm の CLI コマンドのリストと、それらの使用法に関するヘルプ情報を確認できます。 diff --git a/content/ja/docs/howto/_index.md b/content/ja/docs/howto/_index.md new file mode 100644 index 0000000000..31cf82144c --- /dev/null +++ b/content/ja/docs/howto/_index.md @@ -0,0 +1,11 @@ +--- +title: "How-to" +weight: 2 +--- + +# How-to ガイド + +ここでは、「どうすればよいですか?」といった種類の質問に対する短い回答を示します。 +これらの How-to ガイドでは、トピックについて詳しく説明していません。 +そのトピックは[トピックガイド](../topics)に記載されています。 +ただし、これらのガイドは、一般的なタスクをすばやく実行するのに役立ちます。 diff --git a/content/ja/docs/howto/charts_tips_and_tricks.md b/content/ja/docs/howto/charts_tips_and_tricks.md new file mode 100644 index 0000000000..e71b3168fd --- /dev/null +++ b/content/ja/docs/howto/charts_tips_and_tricks.md @@ -0,0 +1,308 @@ +--- +title: "チャート開発のヒントとコツ" +description: "Helm チャート開発者がプロダクション品質のチャートを構築する際に学んだヒントやコツを紹介しています。" +weight: 1 +--- + +このガイドでは、 +Helm チャート開発者がプロダクション品質のチャートを構築する際に学んだヒントやコツを紹介しています。 + +## テンプレートの関数を知る + +Helm はリソースファイルのテンプレートに [Go テンプレート](https://godoc.org/text/template)を使用します。 +Go にはいくつかの組み込み機能がありますが、 +他にも多くの機能が追加されています。 + +まず、 +[Sprig ライブラリ](https://masterminds.github.io/sprig/)の関数をすべて追加しました。 + +また、`include` と `required` の2つの特別なテンプレート関数を追加しました。 +`include` 関数では、別のテンプレートを持ち込んで、 +その結果を他のテンプレート関数に渡すことができます。 + +例えば、このテンプレートスニペットは `mytpl` というテンプレートを含み、 +その結果を小文字にして二重引用符で囲んでいます。 + +```yaml +value: {{ include "mytpl" . | lower | quote }} +``` + +`required` 関数では、テンプレートレンダリングに必要な特定の値のエントリを宣言することができます。 +値が空の場合、テンプレートのレンダリングは +ユーザーが送信したエラーメッセージで失敗します。 + +以下の `required` 関数の例は、.Values.who のエントリが必須であることを宣言し、 +そのエントリが見つからない場合に +エラーメッセージを表示します。 + +```yaml +value: {{ required "A valid .Values.who entry required!" .Values.who }} +``` + +## 文字列を引用する、整数を引用しない + +文字列データを扱う際には、文字列をそのままにしておくよりも、 +引用符で囲んだ方が安全です。 + +```yaml +name: {{ .Values.MyName | quote }} +``` + +しかし、整数で作業するときは _値を引用しないでください_。 +これは多くの場合、Kubernetes 内部で parse エラーを引き起こす可能性があります。 + +```yaml +port: {{ .Values.Port }} +``` + +この注意事項は、たとえそれが整数を表す場合でも、 +文字列であることが予想される env 変数の値には適用されません。 + +```yaml +env: + - name: HOST + value: "http://host" + - name: PORT + value: "1234" +``` + +## 'include' 関数の使用 + +Go は、組み込みの `template` ディレクティブを使って、 +あるテンプレートを別のテンプレートに含める方法を提供しています。 +しかし、組み込み関数はGoテンプレートパイプラインでは使用できません。 + +テンプレートをインクルードして、そのテンプレートの出力に対して操作を行うことができるようにするために、 +Helm には特別な `include` 関数があります。 + +``` +{{ include "toYaml" $value | indent 2 }} +``` + +上記には `toYaml` というテンプレートが含まれており、それに `$value` を渡し、 +そのテンプレートの出力を `indent` 関数に渡しています。 + +YAML はインデントレベルと空白に意味を与えるので、 +これはコードのスニペットをインクルードし、 +関連するコンテキストでインデントを処理するための素晴らしい方法です。 + +## 'required' 関数を使う + +Go では、マップに存在しないキーでマップがインデックス付けされている場合の動作を制御するために、 +テンプレートオプションを設定する方法を提供しています。 +通常、これは `template.Options("missingkey=option")` で設定され、 +`option` には `default`、`zero`、または `error` を指定できます。 +このオプションをエラーに設定すると、エラーで実行が停止しますが、 +これはマップ内に存在しないすべてのキーに適用されます。 +チャート開発者が `values.yaml` ファイル内の選択値にこの動作を適用したい場合があるかもしれません。 + +`required` 関数は、 +テンプレートのレンダリングに必要な値エントリを宣言する機能を開発者に提供します。 +`values.yaml` のエントリが空の場合、 +テンプレートはレンダリングされず、開発者によって提供されたエラーメッセージを返します。 + +例えば + +``` +{{ required "A valid foo is required!" .Values.foo }} +``` + +上記は `.Values.foo` が定義されている場合はテンプレートをレンダリングしますが、 +`.Values.foo` が未定義の場合はレンダリングに失敗して終了します。 + +## 'tpl' 関数の使用 + +`tpl` 関数は、開発者がテンプレート内のテンプレートとして文字列を評価することを可能にします。 +これは、テンプレートの文字列を値としてチャートに渡したり、外部の設定ファイルをレンダリングしたりするのに便利です。 +構文は次の通りです: `{{ tpl TEMPLATE_STRING VALUES }}` + +例: + +```yaml +# values +template: "{{ .Values.name }}" +name: "Tom" + +# template +{{ tpl .Values.template . }} + +# output +Tom +``` + +外部設定ファイルをレンダリングします。 + +```yaml +# 外部設定ファイル conf/app.conf +firstName={{ .Values.firstName }} +lastName={{ .Values.lastName }} + +# values +firstName: Peter +lastName: Parker + +# template +{{ tpl (.Files.Get "conf/app.conf") . }} + +# output +firstName=Peter +lastName=Parker +``` + +## イメージプルの Secret の作成 +イメージプルの Secret は、基本的には _registry_、_username_、_password_ の組み合わせです。 +デプロイするアプリケーションで必要になるかもしれませんが、 +それらを作成するには `base64` を数回実行する必要があります。 +シークレットのペイロードとして使用するために、Docker の設定ファイルを構成するヘルパーテンプレートを書くことができます。 +以下に例を示します。 + +まず、`values.yaml` ファイルに +以下のようにクレデンシャルが定義されているとします。 +```yaml +imageCredentials: + registry: quay.io + username: someone + password: sillyness + email: someone@host.com +``` + +次に、ヘルパーテンプレートを以下のように定義します。 +``` +{{- define "imagePullSecret" }} +{{- with .Values.imageCredentials }} +{{- printf "{\"auths\":{\"%s\":{\"username\":\"%s\",\"password\":\"%s\",\"email\":\"%s\",\"auth\":\"%s\"}}}" .registry .username .password .email (printf "%s:%s" .username .password | b64enc) | b64enc }} +{{- end }} +{{- end }} +``` + +最後に、より大きなテンプレートでヘルパーテンプレートを使用して、 +Secret マニフェストを作成します。 +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: myregistrykey +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +``` + +## デプロイメントの自動ロール + +ConfigMaps や Secrets がコンテナ内の設定ファイルとして注入されていたり、 +他の外部依存関係の変更があってローリングポッドを必要としたりすることがよくあります。 +アプリケーションによっては、後続の `helm upgrade` でこれらが更新された場合、 +再起動が必要になるかもしれませんが、デプロイの仕様自体が変更されていない場合、 +アプリケーションは古い設定で実行され続け、 +結果として一貫性のないデプロイになってしまいます。 + +`sha256sum` 関数を使用すると、 +別のファイルが変更された場合にデプロイメントの annotations セクションを確実に更新することができます。 + +```yaml +kind: Deployment +spec: + template: + metadata: + annotations: + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} +[...] +``` + +デプロイメントを常にロールさせたい場合は、上記と同様の annotation ステップを使用できますが、 +代わりにランダムな文字列に置き換えて、 +常に変化してデプロイメントがロールするようにします。 + +```yaml +kind: Deployment +spec: + template: + metadata: + annotations: + rollme: {{ randAlphaNum 5 | quote }} +[...] +``` + +これらの方法はどちらも、ダウンタイムを回避するために、 +デプロイメントに組み込まれた更新戦略ロジックを活用することができます。 + +NOTE: 過去には別のオプションとして `--recreate-pods` フラグの使用を推奨していました。 +このフラグは Helm 3 で非推奨とされ、 +上記のより宣言的な方法が採用されました。 + +## リソースをアンインストールしないように Helm に伝える + +Helm が `helm uninstall` を実行したときに、アンインストールしてはいけないリソースが存在することがあります。 +チャート開発者は、リソースがアンインストールされないように、 +リソースに annotation を追加することができます。 + + +```yaml +kind: Secret +metadata: + annotations: + "helm.sh/resource-policy": keep +[...] +``` + +(引用符が必要です。) + +`"helm.sh/resource-policy": keep` アノテーションは、 +Helm の操作 (`helm uninstall`, `helm upgrade`, `helm rollback` など) によってこのリソースが削除されてしまう場合に、 +削除をスキップするように指示します。 +_しかし_、このリソースは孤立します。 +Helm はもはやどのような方法でもこのリソースを管理することはできません。 +これは、既にアンインストールされていてリソースを保持しているリリースで `helm install --replace` を使用した場合に問題が発生する可能性があります。 + +## "Partials" とテンプレートのインクルードの使用 + +ブロックでもテンプレートの Partials でも、 +チャートの中に再利用可能なパーツを作成したいと思うことがあります。 +そして、多くの場合、これらを独自のファイルに保存しておいた方がすっきりします。 + +`templates/` ディレクトリにおいて、アンダースコア (`_`) で始まるファイルは、 +Kubernetes のマニフェストファイルを出力することは期待されていません。 +そのため、慣習的にヘルパーテンプレートと Partials は `_helpers.tpl` ファイルに配置されます。 + +## 多くの依存関係を持つ複雑なチャート + +[公式のチャートリポジトリ](https://github.com/helm/charts) にあるチャートの多くは、 +より高度なアプリケーションを作成するための「ビルディングブロック」です。 +しかし、チャートは大規模なアプリケーションのインスタンスを作成するために使用されることもあります。 +そのような場合、1つのアンブレラチャートが複数のサブチャートを持ち、 +それぞれが全体の一部として機能することがあります。 + +離散的なパーツから複雑なアプリケーションを構成するための現在のベストプラクティスは、 +グローバルな構成を公開するトップレベルのアンブレラチャートを作成し、 +`charts/` サブディレクトリを使用して +各コンポーネントを埋め込むことです。 + +## YAML は JSON のスーパーセット + +YAML の仕様によると、YAML は JSON のスーパーセットです。 +つまり、どんな有効な JSON 構造も YAML で有効でなければなりません。 + +これには長所があります。 +時にテンプレート開発者は、YAML の空白感度に対処するよりも、 +JSON ライクな構文でデータ構造を表現する方が簡単だと思うかもしれません。 + +ベストプラクティスとして、JSON 構文が書式問題のリスクを大幅に軽減 _しない限り_、 +テンプレートは YAML ライクな構文に従うべきです。 + +## ランダムな値の生成には注意が必要 + +Helm にはランダムなデータや暗号鍵などを生成する機能があります。 +これらは使っても問題ありません。 +しかし、アップグレード中にテンプレートが再実行されることに注意してください。 +テンプレートの実行で前回の実行とは異なるデータが生成されると、そのリソースの更新がトリガーされます。 + +## 1つのコマンドでリリースをインストールまたはアップグレード + +Helm は、インストールやアップグレードを単一のコマンドで実行する方法を提供します。 +`helm upgrade` コマンドで `--install` を付けて使ってください。 +これにより、Helm はリリースが既にインストールされているかどうかを確認します。 +インストールされていない場合は、インストールを実行します。されている場合は、既存のリリースがアップグレードされます。 + +```console +$ helm upgrade --install --values +``` diff --git a/docs.helm.sh/themes/helmdocs/static/images/create-a-bucket.png b/content/ja/docs/images/create-a-bucket.png old mode 100755 new mode 100644 similarity index 100% rename from docs.helm.sh/themes/helmdocs/static/images/create-a-bucket.png rename to content/ja/docs/images/create-a-bucket.png diff --git a/docs.helm.sh/themes/helmdocs/static/images/create-a-gh-page-button.png b/content/ja/docs/images/create-a-gh-page-button.png old mode 100755 new mode 100644 similarity index 100% rename from docs.helm.sh/themes/helmdocs/static/images/create-a-gh-page-button.png rename to content/ja/docs/images/create-a-gh-page-button.png diff --git a/docs.helm.sh/themes/helmdocs/static/images/edit-permissions.png b/content/ja/docs/images/edit-permissions.png old mode 100755 new mode 100644 similarity index 100% rename from docs.helm.sh/themes/helmdocs/static/images/edit-permissions.png rename to content/ja/docs/images/edit-permissions.png diff --git a/content/ja/docs/images/make-bucket-public.png b/content/ja/docs/images/make-bucket-public.png new file mode 100644 index 0000000000..e457e34b23 Binary files /dev/null and b/content/ja/docs/images/make-bucket-public.png differ diff --git a/docs.helm.sh/rootfs/public/images/nothing.png b/content/ja/docs/images/nothing.png similarity index 100% rename from docs.helm.sh/rootfs/public/images/nothing.png rename to content/ja/docs/images/nothing.png diff --git a/docs.helm.sh/themes/helmdocs/static/images/set-a-gh-page.png b/content/ja/docs/images/set-a-gh-page.png old mode 100755 new mode 100644 similarity index 100% rename from docs.helm.sh/themes/helmdocs/static/images/set-a-gh-page.png rename to content/ja/docs/images/set-a-gh-page.png diff --git a/content/ja/docs/intro/_index.md b/content/ja/docs/intro/_index.md new file mode 100644 index 0000000000..fe4f801eda --- /dev/null +++ b/content/ja/docs/intro/_index.md @@ -0,0 +1,8 @@ +--- +title: "概要" +weight: 1 +--- + +# Helm の概要 + +Helm は初めてですか? これが出発点です! diff --git a/content/ja/docs/intro/install.md b/content/ja/docs/intro/install.md new file mode 100755 index 0000000000..9db620e774 --- /dev/null +++ b/content/ja/docs/intro/install.md @@ -0,0 +1,144 @@ +--- +title: "Helm のインストール" +description: "Helm をインストールして実行する方法を学びます。" +weight: 2 +--- + +このガイドでは、Helm CLI のインストール方法を示します。Helm はソースから、またはビルド済みのバイナリリリースから +インストールできます。 + +## Helm プロジェクトから + +Helm プロジェクトは、Helm をフェッチしてインストールする2つの方法を提供します。 +これらは Helm リリースを取得するための公式の方法です。さらに、Helm コミュニティは、 +さまざまなパッケージマネージャーを通じて Helm をインストールする方法を提供しています。 +これらの方法によるインストールは、公式の方法の下にあります。 + +### バイナリリリースから + +Helm のすべての [リリース](https://github.com/helm/helm/releases) は、さまざまな OS のバイナリリリースを提供します。 +これらのバイナリバージョンは、手動でダウンロードして +インストールできます。 + +1. [任意のバージョン](https://github.com/helm/helm/releases)をダウンロードします +2. ダウンロードしたパッケージを展開します (`tar -zxvf helm-v3.0.0-linux-amd64.tar.gz`) +3. 展開したディレクトリで `helm` バイナリを見つけ、 + 目的の場所に移動します (`mv linux-amd64/helm /usr/local/bin/helm`) + +そこから、クライアントを実行し、[Stable リポジトリを追加](https://helm.sh/docs/intro/quickstart/#initialize-a-helm-chart-repository)できるはずです: `helm help` を参考 + +**注**: Helm 自動テストは、CircleCi のビルドとリリース中にのみLinux AMD64 に対して実行されます。 +他の OS のテストは、 +対象の OS の Helm を要求するコミュニティの責任の元で行われています。 + +### スクリプトから + +Helm に、最新バージョンの Helm を自動的に取得して +[ローカルにインストールする](https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3) +インストーラースクリプトが追加されました。 + +そのスクリプトをフェッチして、ローカルで実行できます。 +十分に文書化されているため、実行する前にそれを読んで何が行われているかを理解できます。 + +```console +$ curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 +$ chmod 700 get_helm.sh +$ ./get_helm.sh +``` + +もちろん、 +最新版で実施したい場合は、 +`curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash` を使用できます。 + + +## パッケージマネージャーを使用したインストール + +Helm コミュニティは、オペレーティングシステムのパッケージマネージャーを介して Helm をインストールする機能を提供します。 +これらは Helm プロジェクトではサポートされておらず、 +信頼できるサードパーティとは見なされません。 + +### Homebrew から (macOS) + +Helm コミュニティのメンバーは、Homebrew に Helm フォーミュラビルドを提供しています。 +この式は一般に最新です。 + +```console +brew install helm +``` + +(注: 別のプロジェクトである emacs-helm の式もあります。) + +### Chocolatey から (Windows) + +Helm コミュニティのメンバーが [Chocolatey](https://chocolatey.org/) に +[Helm パッケージ](https://chocolatey.org/packages/kubernetes-helm) のビルドを提供しました。 +このパッケージは一般に最新です。 + +```console +choco install kubernetes-helm +``` + +### Apt から (Debian/Ubuntu) + +Helm コミュニティのメンバーは、Apt の [Helm パッケージ](https://helm.baltorepo.com/stable/debian/) を提供しています。 +このパッケージは一般に最新です。 + +```console +curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null +sudo apt-get install apt-transport-https --yes +echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list +sudo apt-get update +sudo apt-get install helm +``` + +### Snap から + +[Snapcrafters](https://github.com/snapcrafters) コミュニティは、 +[Helm パッケージ](https://snapcraft.io/helm)の Snap バージョンを維持しています。 + +```console +sudo snap install helm --classic +``` + +### Development ビルド + +リリースに加えて、Helm の開発スナップショットをダウンロードまたはインストールできます。 + +### Canary ビルドから + +"Canary" ビルドは、最新のマスターブランチからビルドされた Helm ソフトウェアのバージョンです。 +これらは公式リリースではなく、安定しない可能性があります。 +ただし、これらは最先端の機能をテストする機会を提供します。 + +Canary Helm バイナリは [get.helm.sh](https://get.helm.sh) に保存されます。 +一般的なビルドへのリンクは次のとおりです。 + +- [Linux AMD64](https://get.helm.sh/helm-canary-linux-amd64.tar.gz) +- [macOS AMD64](https://get.helm.sh/helm-canary-darwin-amd64.tar.gz) +- [Experimental Windows + AMD64](https://get.helm.sh/helm-canary-windows-amd64.zip) + +### Source から (Linux, macOS) + +ソースか Helm をビルドするのは少し手間がかかりますが、 +最新の (プレリリース) Helm バージョンをテストする場合に最適な方法です。 + +Go 環境が動作している必要があります。 + +```console +$ git clone https://github.com/helm/helm.git +$ cd helm +$ make +``` + +必要に応じて、依存関係をフェッチしてキャッシュし、構成を検証します。 +次に、`helm` をコンパイルして `bin/helm` に配置します。 + +## まとめ + +ほとんどの場合、インストールは、事前に構築された `helm` バイナリを取得するのと同じくらい簡単です。 +このドキュメントでは、Helm でより高度なことを実行したい人のための +追加のケースについて説明します。 + +Helm クライアントが正常にインストールされたら、Helm を使用してチャートを管理し、 +[Stable リポジトリを追加](https://helm.sh/docs/intro/quickstart/#initialize-a-helm-chart-repository) できます。 diff --git a/content/ja/docs/intro/quickstart.md b/content/ja/docs/intro/quickstart.md new file mode 100644 index 0000000000..eb741472e5 --- /dev/null +++ b/content/ja/docs/intro/quickstart.md @@ -0,0 +1,126 @@ +--- +title: "クイックスタートガイド" +description: "ディストリビューション、FAQ、プラグインの手順を含む、Helm のインストール方法と使用方法。" +weight: 1 +--- + +このガイドでは、Helm をすぐに使い始める方法について説明します。 + +## 前提条件 + +Helm を正しく安全に使用するには、 +次の前提条件が必要です。 + +1. Kubernetes クラスター +2. インストールに適用するセキュリティ構成がある場合は、それを決定する +3. Helm のインストールと構成 + +### Kubernetes をインストールするか、クラスターにアクセスする + +- Kubernetes がインストールされている必要があります。 + Helm の最新リリースには、Kubernetesの最新の安定リリースをお勧めします。 + これは、ほとんどの場合、2番目に新しいマイナーリリースです。 +- ローカルに設定された `kubectl` のコピーも必要です。 + +注: 1.6 より前のバージョンの Kubernetes では、ロールベースのアクセス制御 (RBAC) のサポートが制限されているか、 +サポートされていません。 + +## Helm のインストール + +Helm クライアントのバイナリリリースをダウンロードします。`homebrew` のようなツールを使うか、 +[公式リリースページ](https://github.com/helm/helm/releases) を見ることができます。 + +詳細またはその他のオプションについては、 +[インストールガイド]({{< ref "install.md" >}}) を参照してください。 + +## Helm チャートリポジトリを初期化する + +Helm の準備ができたら、チャートリポジトリを追加できます。 +ポピュラーな開始場所の1つは、公式の Helm Stable チャートです。 + +```console +$ helm repo add stable https://charts.helm.sh/stable +``` + +これがインストールされると、インストールできるチャートを一覧表示できるようになります。 + +```console +helm search repo stable +NAME CHART VERSION APP VERSION DESCRIPTION +stable/acs-engine-autoscaler 2.2.2 2.1.1 DEPRECATED Scales worker nodes within agent pools +stable/aerospike 0.2.8 v4.5.0.5 A Helm chart for Aerospike in Kubernetes +stable/airflow 4.1.0 1.10.4 Airflow is a platform to programmatically autho... +stable/ambassador 4.1.0 0.81.0 A Helm chart for Datawire Ambassador +# ... and many more +``` + +## サンプルチャートをインストールする + +チャートをインストールするには、`helm install` コマンドを実行します。 +Helm には、チャートを見つけてインストールする方法がいくつかありますが、最も簡単なのは、 +公式の `stable` チャートの1つを使用することです。 + +```console +$ helm repo update # チャートの最新のリストを取得していることを確認してください +$ helm install stable/mysql --generate-name +Released smiling-penguin +``` + +上記の例では、`stable/mysql` チャートがリリースされており、 +新しいリリースの名前は `smiling-penguin` です。 + +`helm show chart stable/mysql` を実行すると、この MySQL チャートの機能の簡単なアイデアが得られます。 +または `helm show all stable/mysql` を実行して、 +チャートに関するすべての情報を取得することもできます。 + +チャートをインストールするたびに、新しいリリースが作成されます。 +したがって、1つのチャートを同じクラスターに複数回インストールできます。 +また、それぞれを個別に管理およびアップグレードできます。 + +`helm install` コマンドは、多くの機能を備えた非常に強力なコマンドです。 +詳細については、[Helm の使用ガイド]({{< ref "using_helm.md" >}}) をご覧ください。 + +## リリースについて学ぶ + +Helm を使用してリリースされた内容を簡単に確認できます。 + +```console +$ helm ls +NAME VERSION UPDATED                   STATUS   CHART +smiling-penguin 1 Wed Sep 28 12:59:46 2016 DEPLOYED mysql-0.1.0 +``` + +`helm list` 機能は、デプロイされたすべてのリリースのリストを表示します。 + +## リリースをアンインストールする + +リリースをアンインストールするには、`helm uninstall` コマンドを使用します。 + +```console +$ helm uninstall smiling-penguin +Removed smiling-penguin +``` + +これにより、Kubernetes から `smiling-penguin` がアンインストールされ、 +リリースに関連するすべてのリソースとリリース履歴が削除されます。 + +`--keep-history` フラグを指定すると、リリース履歴が保持されます。 +そのリリースに関する情報をリクエストできます。 + +```console +$ helm status smiling-penguin +Status: UNINSTALLED +... +``` + +Helm はリリースをアンインストールした後でもリリースを追跡するため、クラスターの履歴を監査したり、 +(`helm rollback` を使用して) リリースを元に戻したりすることができます。 + +## ヘルプテキストを読む + +使用可能な Helm コマンドの詳細については、`helm help` を使用するか、 +コマンドに続けて `-h` フラグを入力してください。 + +```console +$ helm get -h +``` diff --git a/content/ja/docs/intro/using_helm.md b/content/ja/docs/intro/using_helm.md new file mode 100755 index 0000000000..d4d0c800de --- /dev/null +++ b/content/ja/docs/intro/using_helm.md @@ -0,0 +1,531 @@ +--- +title: "Helm の使い方" +description: "Helm の基本について説明します。" +weight: 3 +--- + +このガイドでは、Helm を使用して Kubernetes クラスタ上のパッケージを管理する基本について説明します。 +Helm クライアントが既に [インストール済み]({{< ref "install.md" >}}) であると +想定しています。 + +いくつかのクイックコマンドを実行したいだけの場合は、 +[クイックスタートガイド]({{< ref "quickstart.md" >}}) から始めてください。 +この章では、Helm コマンドの詳細について説明し、Helm の使用方法を説明します。 + +## 3つの大きな概念 + +*チャート* は Helm パッケージです。 +これには、Kubernetes クラスタ内でアプリケーション、ツール、またはサービスを実行するために必要なすべてのリソース定義が含まれています。 +Kubernetes に置ける Homebrew の式、Apt dpkg、 +または Yum RPM ファイルに相当するようなものと考えてください。 + +*リポジトリ* は、チャートを収集して共有できる場所です。 +Perl の [CPAN アーカイブ](https://www.cpan.org) や [Fedora パッケージデータベース](https://src.fedoraproject.org/)に似ていますが、 +Kubernetes パッケージが対象です。 + +*リリース* は、Kubernetes クラスタで実行されているチャートのインスタンスです。 +多くの場合、1つのチャートを同じクラスターに何度もインストールできます。 +そして、それがインストールされるたびに、新しい _リリース_ が作成されます。 +MySQL チャートを考えてみましょう。クラスターで2つのデータベースを実行する場合は、そのチャートを2回インストールできます。 +それぞれに独自の _リリース_ があり、次に独自の _リリース名_ が付けられます。 + +これらの概念を念頭に置いて、Helm を次のように説明できます。 + +Helm は _チャート_ を Kubernetes にインストールし、インストールごとに新しい _リリース_ を作成します。 +また、新しいチャートを見つけるには、Helm チャート _リポジトリ_ を検索できます。 + +## 'helm search': チャートを見つける + +Helm には強力な検索コマンドが付属しています。 +2つの異なるタイプのソースの検索に使用できます。 + +- `helm search hub` は、[Helm Hub](https://hub.helm.sh) を検索します。 + これは、多数の異なるリポジトリの Helm チャートで構成されています。 +- `helm search repo` は、(`helm repo add` で) ローカルの helm クライアントに追加したリポジトリを検索します。 + この検索はローカルデータ上で行われ、 + パブリックネットワーク接続は必要ありません。 + +`helm search hub` を実行すると、公開されているチャートを見つけることができます。 + +```console +$ helm search hub wordpress +URL CHART VERSION APP VERSION DESCRIPTION +https://hub.helm.sh/charts/bitnami/wordpress 7.6.7 5.2.4 Web publishing platform for building blogs and ... +https://hub.helm.sh/charts/presslabs/wordpress-... v0.6.3 v0.6.3 Presslabs WordPress Operator Helm Chart +https://hub.helm.sh/charts/presslabs/wordpress-... v0.7.1 v0.7.1 A Helm chart for deploying a WordPress site on ... +``` + +上記は Helm Hub 上のすべての `wordpress` チャートを検索します。 + +フィルターなしの場合、`helm search hub` は利用可能なすべてのチャートを表示します。 + +`helm search repo` を使用すると、すでに追加したリポジトリでチャートの名前を見つけることができます。 + +```console +$ helm repo add brigade https://brigadecore.github.io/charts +"brigade" has been added to your repositories +$ helm search repo brigade +NAME CHART VERSION APP VERSION DESCRIPTION +brigade/brigade 1.3.2 v1.2.1 Brigade provides event-driven scripting of Kube... +brigade/brigade-github-app 0.4.1 v0.2.1 The Brigade GitHub App, an advanced gateway for... +brigade/brigade-github-oauth 0.2.0 v0.20.0 The legacy OAuth GitHub Gateway for Brigade +brigade/brigade-k8s-gateway 0.1.0 A Helm chart for Kubernetes +brigade/brigade-project 1.0.0 v1.0.0 Create a Brigade project +brigade/kashti 0.4.0 v0.4.0 A Helm chart for Kubernetes +``` + +Helm の検索はあいまい文字列マッチングアルゴリズムを使用するため、単語やフレーズの一部を入力できます。 + +```console +$ helm search repo kash +NAME CHART VERSION APP VERSION DESCRIPTION +brigade/kashti 0.4.0 v0.4.0 A Helm chart for Kubernetes +``` + +検索は、利用可能なパッケージを見つけるための良い方法です。 +インストールするパッケージが見つかったら、`helm install` を使用してインストールできます。 + +## 'helm install': パッケージのインストール + +新しいパッケージをインストールするには、`helm install` コマンドを使用します。 +簡単に言うと、2つの引数を取ります。選択するリリース名と、インストールするチャートの名前です。 + +```console +$ helm install happy-panda stable/mariadb +WARNING: This chart is deprecated +NAME: happy-panda +LAST DEPLOYED: Fri May 8 17:46:49 2020 +NAMESPACE: default +STATUS: deployed +REVISION: 1 +NOTES: +This Helm chart is deprecated + +... + +Services: + + echo Master: happy-panda-mariadb.default.svc.cluster.local:3306 + echo Slave: happy-panda-mariadb-slave.default.svc.cluster.local:3306 + +Administrator credentials: + + Username: root + Password : $(kubectl get secret --namespace default happy-panda-mariadb -o jsonpath="{.data.mariadb-root-password}" | base64 --decode) + +To connect to your database: + + 1. Run a pod that you can use as a client: + + kubectl run happy-panda-mariadb-client --rm --tty -i --restart='Never' --image docker.io/bitnami/mariadb:10.3.22-debian-10-r27 --namespace default --command -- bash + + 2. To connect to master service (read/write): + + mysql -h happy-panda-mariadb.default.svc.cluster.local -uroot -p my_database + + 3. To connect to slave service (read-only): + + mysql -h happy-panda-mariadb-slave.default.svc.cluster.local -uroot -p my_database + +To upgrade this helm chart: + + 1. Obtain the password as described on the 'Administrator credentials' section and set the 'rootUser.password' parameter as shown below: + + ROOT_PASSWORD=$(kubectl get secret --namespace default happy-panda-mariadb -o jsonpath="{.data.mariadb-root-password}" | base64 --decode) + helm upgrade happy-panda stable/mariadb --set rootUser.password=$ROOT_PASSWORD + +``` + +これで `mariadb` チャートがインストールされました。 +チャートをインストールすると、新しい _release_ オブジェクトが作成されることに注意してください。上記のリリースは `happy-panda` という名前です。 +(Helm で名前を生成する場合は、リリース名を省略して `--generate-name` を使用します。) + +インストール中に、`helm` クライアントは、作成されたリソース、リリースの状態、 +さらに実行できる、または実行すべき追加の構成手順があるかどうかに関する +有用な情報を出力します。 + +Helm は、終了する前にすべてのリソースが実行されるまで待機しません。 +多くのチャートには 600M を超えるサイズの Docker イメージが必要であり、 +クラスターへのインストールに長い時間がかかる場合があります。 + +リリースの状態を追跡したり、設定情報を再度読み取るには、 +`helm status` を使用できます。 + +```console +$ helm status happy-panda +NAME: happy-panda +LAST DEPLOYED: Fri May 8 17:46:49 2020 +NAMESPACE: default +STATUS: deployed +REVISION: 1 +NOTES: +This Helm chart is deprecated + +... + +Services: + + echo Master: happy-panda-mariadb.default.svc.cluster.local:3306 + echo Slave: happy-panda-mariadb-slave.default.svc.cluster.local:3306 + +Administrator credentials: + + Username: root + Password : $(kubectl get secret --namespace default happy-panda-mariadb -o jsonpath="{.data.mariadb-root-password}" | base64 --decode) + +To connect to your database: + + 1. Run a pod that you can use as a client: + + kubectl run happy-panda-mariadb-client --rm --tty -i --restart='Never' --image docker.io/bitnami/mariadb:10.3.22-debian-10-r27 --namespace default --command -- bash + + 2. To connect to master service (read/write): + + mysql -h happy-panda-mariadb.default.svc.cluster.local -uroot -p my_database + + 3. To connect to slave service (read-only): + + mysql -h happy-panda-mariadb-slave.default.svc.cluster.local -uroot -p my_database + +To upgrade this helm chart: + + 1. Obtain the password as described on the 'Administrator credentials' section and set the 'rootUser.password' parameter as shown below: + + ROOT_PASSWORD=$(kubectl get secret --namespace default happy-panda-mariadb -o jsonpath="{.data.mariadb-root-password}" | base64 --decode) + helm upgrade happy-panda stable/mariadb --set rootUser.password=$ROOT_PASSWORD +``` + +上記はリリースの現在の状態を示しています。 + +### インストール前のチャートのカスタマイズ + +ここにある方法でインストールすると、 +このチャートのデフォルトの構成オプションのみが使用されます。 +多くの場合、好みの構成を使用するようにチャートをカスタマイズする必要があります。 + +チャートで設定可能なオプションを確認するには、`helm show values` を使用します。 + +```console +$ helm show values stable/mariadb +Fetched stable/mariadb-0.3.0.tgz to /Users/mattbutcher/Code/Go/src/helm.sh/helm/mariadb-0.3.0.tgz +## Bitnami MariaDB image version +## ref: https://hub.docker.com/r/bitnami/mariadb/tags/ +## +## Default: none +imageTag: 10.1.14-r3 + +## Specify a imagePullPolicy +## Default to 'Always' if imageTag is 'latest', else set to 'IfNotPresent' +## ref: https://kubernetes.io/docs/user-guide/images/#pre-pulling-images +## +# imagePullPolicy: + +## Specify password for root user +## ref: https://github.com/bitnami/bitnami-docker-mariadb/blob/master/README.md#setting-the-root-password-on-first-run +## +# mariadbRootPassword: + +## Create a database user +## ref: https://github.com/bitnami/bitnami-docker-mariadb/blob/master/README.md#creating-a-database-user-on-first-run +## +# mariadbUser: +# mariadbPassword: + +## Create a database +## ref: https://github.com/bitnami/bitnami-docker-mariadb/blob/master/README.md#creating-a-database-on-first-run +## +# mariadbDatabase: +# ... +``` + +次に、YAML 形式のファイルでこれらの設定を上書きし、 +インストール中にそのファイルを渡すことができます。 + +```console +$ echo '{mariadbUser: user0, mariadbDatabase: user0db}' > config.yaml +$ helm install -f config.yaml stable/mariadb --generate-name +``` + +上記は `user0` という名前のデフォルトの MariaDB ユーザーを作成し、 +このユーザーに新しく作成された `user0db` データベースへのアクセスを許可しますが、 +そのチャートの残りのデフォルトはすべて受け入れます。 + +インストール中に構成データを渡す方法は2つあります。 + +- `--values` (または `-f`): 上書きする YAML ファイルを指定します。 + これは複数回指定でき、一番右のファイルが優先されます +- `--set`: コマンドラインで上書きする値を指定します + +両方が使用される場合、`--set` 値はより高い優先度で `--values` にマージされます。 +`--set` で指定されたオーバーライドは ConfigMap に永続化されます。 +`--set` されている値は、`helm get values <リリース名>`を使用して、 +特定のリリースで表示できます。 +`--set` になっている値は、`--reset-values` を指定して `helm upgrade` を実行することでクリアできます。 + +#### `--set` の形式と制限 + +`--set` オプションは0個以上の名前と値のペアを取ります。 +簡単に言うと、`--set name=value` のように使用されます。これに相当する YAML は次のとおりです。 + +```yaml +name: value +``` + +複数の値は、`,` 文字で区切られます。したがって、`--set a=b,c=d` は次のようになります。 + +```yaml +a: b +c: d +``` + +より複雑な式がサポートされています。 +たとえば、`--set outer.inner=value` は次のように変換されます。 +```yaml +outer: + inner: value +``` + +リストは、`{` と `}` で値を囲むことで表現できます。 +たとえば、`--set name={a, b, c}` は次のように変換されます。 + +```yaml +name: + - a + - b + - c +``` + +Helm 2.5.0 以降では、配列インデックス構文を使用してリストアイテムにアクセスできます。 +たとえば、`--set servers[0].port=80` は次のようになります。 + +```yaml +servers: + - port: 80 +``` + +この方法で複数の値を設定できます。 +`--set servers[0].port=80,servers[0].host=example` という行は次のようになります: + +```yaml +servers: + - port: 80 + host: example +``` + +`--set` 行で特殊文字を使用する必要がある場合があります。バックスラッシュを使用して文字をエスケープできます。 +`--set name=value1\,value2` は次のようになります。 + +```yaml +name: "value1,value2" +``` + +同様に、ドットシーケンスをエスケープすることもできます。 +これは、チャートが `toYaml` 関数を使用して +注釈、ラベル、ノードセレクターを解析するときに役立つ場合があります。 +`--set nodeSelector."kubernetes\.io/role"=master` の構文は次のようになります。 + +```yaml +nodeSelector: + kubernetes.io/role: master +``` + +深くネストされたデータ構造は、`--set` を使用して表現するのが難しい場合があります。 +チャートの設計者は、`values.yaml` ファイルのフォーマットを設計するときに、 +`--set` の使用法を検討することをお勧めします。 + +### その他のインストール方法 + +`helm install` コマンドはいくつかのソースからインストールできます。 + +- チャートリポジトリ (上記で見たように) +- ローカルチャートアーカイブ (`helm install foo foo-0.1.1.tgz`) +- 展開されたチャートディレクトリ (`helm install foo path/to/foo`) +- 完全な URL (`helm install foo https://example.com/charts/foo-1.2.3.tgz`) + +## 'helm upgrade' と 'helm rollback': リリースのアップグレードと障害時の回復 + +チャートの新しいバージョンがリリースされたとき、またはリリースの構成を変更したいときは、 +`helm upgrade` コマンドを使用できます。 + +アップグレードでは、既存のリリースを取得し、提供された情報に従ってアップグレードします。 +Kubernetes チャートは大きく複雑になる可能性があるため、 +Helm は最も侵襲性の低いアップグレードを実行しようとします。 +最後のリリース以降に変更されたもののみを更新します。 + +```console +$ helm upgrade -f panda.yaml happy-panda stable/mariadb +Fetched stable/mariadb-0.3.0.tgz to /Users/mattbutcher/Code/Go/src/helm.sh/helm/mariadb-0.3.0.tgz +happy-panda has been upgraded. Happy Helming! +Last Deployed: Wed Sep 28 12:47:54 2016 +Namespace: default +Status: DEPLOYED +... +``` + +上記の場合、`happy-panda` リリースは同じチャートでアップグレードされますが、 +新しい YAML ファイルが使用されます。 + +```yaml +mariadbUser: user1 +``` + +`helm get values` を使用して、新しい設定が有効になったかどうかを確認できます。 + +```console +$ helm get values happy-panda +mariadbUser: user1 +``` + +`helm get` コマンドは、クラスター内のリリースを確認するのに役立つツールです。 +上記のように、`panda.yaml` からの新しい値が +クラスターにデプロイされたことを示しています。 + +さて、リリース中に何かが計画どおりに進まなかった場合、 +`helm rollback [RELEASE] [REVISION]` を使用して前のリリースに簡単にロールバックできます。 + +```console +$ helm rollback happy-panda 1 +``` + +上記は、happy-panda を最初のリリースバージョンにロールバックします。 +リリースバージョンは増分リビジョンです。 +インストール、アップグレード、またはロールバックが発生するたびに、リビジョン番号は1ずつ増加します。 +最初のリビジョン番号は常に1です。 +また、`helm history [RELEASE]` を使用して、特定のリリースのリビジョン番号を確認できます。 + +## インストール/アップグレード/ロールバックに役立つオプション + +インストール/アップグレード/ロールバック中の Helm の動作をカスタマイズするために指定できる +他の便利なオプションがいくつかあります。 +これは cli フラグの完全なリストではないことに注意してください。 +すべてのフラグの説明を表示するには、`helm --help` を実行します。 + +- `--timeout`: Kubernetes コマンドが完了するまで待機する秒単位の値 + デフォルトは `5m0s` です +- `--wait`: リリースが成功したとマークする前に、すべてのポッドが準備完了状態になり、 + PVC がバインドされ、デプロイメントには準備ができた状態の最小 (`Desired` - `maxUnavailable`) ポッドがあり、 + サービスに IP アドレス (および `LoadBalancer` の場合は Ingress) があるまで待ちます。 + `--timeout` 値が出るまで待機します。 + タイムアウトに達すると、リリースは `FAILED` としてマークされます。 + 注: Deployment のローリング更新戦略の一環として、Deployment の `replicas` が 1 に設定され、 + `maxUnavailable` が 0 に設定されていない場合、 + `--wait` は、準備完了状態の最小ポッドを満たしているため、準備完了として戻ります。 +- `--no-hooks`: これは、コマンドの実行中のフックをスキップします +- `--recreate-pods` (`upgrade` と `rollback` でのみ使用可能): このフラグにより、すべてのポッドが再作成されます + (デプロイメントに属するポッドを除く)。 + (Helm 3 では非推奨) + +## 'helm uninstall': リリースのアンインストール + +クラスターからリリースをアンインストールするときは、 +`helm uninstall` コマンドを使用します。 + +```console +$ helm uninstall happy-panda +``` + +これにより、リリースがクラスターから削除されます。 +`helm list` コマンドを使用すると、現在デプロイされているすべてのリリースを確認できます。 + +```console +$ helm list +NAME VERSION UPDATED STATUS CHART +inky-cat 1 Wed Sep 28 12:59:46 2016 DEPLOYED alpine-0.1.0 +``` + +上記の出力から、`happy-panda` リリースが +アンインストールされたことがわかります。 + +Helm の以前のバージョンでは、リリースが削除されると、その削除の記録が残りました。 +Helm 3 では、削除によりリリースレコードも削除されます。 +削除リリースレコードを保持する場合は、`helm uninstall --keep-history` を使用します。 +`helm list --uninstalled` を使用すると、 +`--keep-history` フラグでアンインストールされたリリースのみが表示されます。 + +`helm list --all` フラグは、Helm が保持しているすべてのリリースレコードを表示します。 +これには、失敗したアイテムや削除されたアイテムのレコードも含まれます (`--keep-history` が指定されている場合)。 + +```console +$ helm list --all +NAME VERSION UPDATED STATUS CHART +happy-panda 2 Wed Sep 28 12:47:54 2016 UNINSTALLED mariadb-0.3.0 +inky-cat 1 Wed Sep 28 12:59:46 2016 DEPLOYED alpine-0.1.0 +kindred-angelf 2 Tue Sep 27 16:16:10 2016 UNINSTALLED alpine-0.1.0 +``` + +リリースはデフォルトで削除されるようになったため、 +アンインストールされたリソースをロールバックすることはできなくなりました。 + +## 'helm repo': リポジトリの操作 + +Helm 3 には、デフォルトのチャートリポジトリが付属しなくなりました。 +`helm repo` コマンドグループは、リポジトリを追加、一覧表示、削除するコマンドを提供します。 + +`helm repo list` を使用して、設定されているリポジトリを確認できます。 + +```console +$ helm repo list +NAME URL +stable https://charts.helm.sh/stable +mumoshu https://mumoshu.github.io/charts +``` + +そして、新しいリポジトリは `helm repo add` で追加できます。 + +```console +$ helm repo add dev https://example.com/dev-charts +``` + +チャートリポジトリは頻繁に変更されるため、 +`helm repo update` を実行することで、いつでも Helm クライアントが最新であることを確認できます。 + +リポジトリは `helm repo remove` で削除できます。 + +## 独自のチャートを作成する + +[チャート開発ガイド](https://helm.sh/docs/topics/charts/) は、独自のチャートを開発する方法を説明しています。 +ただし、`helm create` コマンドを使用すると、すぐに開始できます。 + +```console +$ helm create deis-workflow +Creating deis-workflow +``` + +今、`./deis-workflow` にチャートがあるとします。 +それを編集して、独自のテンプレートを作成できます。 + +チャートを編集するとき、`helm lint` を実行することにより、 +チャートが整形式であることを検証できます。 + +チャートを配布用にパッケージ化するときは、 +`helm package` コマンドを実行できます。 + +```console +$ helm package deis-workflow +deis-workflow-0.1.0.tgz +``` + +そして、そのチャートは `helm install` によって簡単にインストールできます。 + +```console +$ helm install deis-workflow ./deis-workflow-0.1.0.tgz +... +``` + +パッケージ化されたチャートは、チャートリポジトリにロードできます。 +アップロード方法については、チャートリポジトリサーバーのドキュメントをご覧ください。 + +注: `stable` リポジトリは [Kubernetes Charts GitHub リポジトリ](https://github.com/helm/charts) で管理されています。 +そのプロジェクトは、チャートのソースコードを受け入れ、 +(監査後に) それらをパッケージ化します。 + +## まとめ + +この章では、検索、インストール、アップグレード、アンインストールなど、 +`helm` クライアントの基本的な使用パターンについて説明しました。 +また、`helm status`、`helm get`、`helm repo` などの便利なユーティリティコマンドについても説明しています。 + +これらのコマンドの詳細については、 +Helm の組み込みヘルプである `helm help` をご覧ください。 + +次の章では、チャートを作成するプロセスについて説明します。 diff --git a/content/ja/docs/logos/helm-blue-vector.svg b/content/ja/docs/logos/helm-blue-vector.svg new file mode 100644 index 0000000000..45f2c2f862 --- /dev/null +++ b/content/ja/docs/logos/helm-blue-vector.svg @@ -0,0 +1,43 @@ + + + + +logo +Created with Sketch. + + + + + + diff --git a/content/ja/docs/logos/helm-white-vector.svg b/content/ja/docs/logos/helm-white-vector.svg new file mode 100644 index 0000000000..0f09be31ef --- /dev/null +++ b/content/ja/docs/logos/helm-white-vector.svg @@ -0,0 +1,43 @@ + + + + +logo white +Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + diff --git a/content/ja/docs/logos/helm.svg b/content/ja/docs/logos/helm.svg new file mode 100644 index 0000000000..2d8858e938 --- /dev/null +++ b/content/ja/docs/logos/helm.svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/content/ja/docs/logos/helm_logo_transparent.png b/content/ja/docs/logos/helm_logo_transparent.png new file mode 100644 index 0000000000..cd5526281f Binary files /dev/null and b/content/ja/docs/logos/helm_logo_transparent.png differ diff --git a/content/ja/docs/topics/_index.md b/content/ja/docs/topics/_index.md new file mode 100644 index 0000000000..d7cdae895d --- /dev/null +++ b/content/ja/docs/topics/_index.md @@ -0,0 +1,9 @@ +--- +title: "トピック" +weight: 3 +--- + +# トピックガイド + +ここでは、Helm の必要な、または知りたいすべての主要部分の概要を +説明します。 diff --git a/content/ja/docs/topics/advanced.md b/content/ja/docs/topics/advanced.md new file mode 100644 index 0000000000..7a00c4eada --- /dev/null +++ b/content/ja/docs/topics/advanced.md @@ -0,0 +1,184 @@ +--- +title: "高度な Helm のテクニック" +description: "Helm パワーユーザー向けのさまざまな高度な機能について説明します" +weight: 9 +--- + +このセクションでは、Helm を使用するためのさまざまな高度な機能とテクニックについて説明します。 +このセクションの情報は、チャートとリリースの高度なカスタマイズと操作を行いたい +Helm の「パワーユーザー」を対象としています。 +これらの高度な機能にはそれぞれ独自のトレードオフと警告があり、 +Helm の深い知識を駆使して慎重に使用する必要があります。 +言い換えれば、[ピーター・パーカーの原則](https://en.wikipedia.org/wiki/With_great_power_comes_great_responsibility) +を覚えておいてください + +## ポストレンダリング +ポストレンダリングにより、チャートインストーラーは、Helm によってインストールされる前に、 +レンダリングされたマニフェストを手動で操作、構成、または検証することができます。 +これにより、高度な構成を持つユーザーは、[`kustomize`](https://kustomize.io) などのツールを使用して、 +パブリックチャートをフォークしたり、 +チャートのメンテナーがソフトウェアの最後の構成オプションをすべて指定したりする必要なく、 +構成の変更を適用できます。 +エンタープライズ環境での一般的なツールやサイドカーの注入、 +展開前のマニフェストの分析のユースケースもあります。 + +### 前提条件 +- Helm 3.1+ + +### 使い方 +ポストレンダラーは、STDIN でレンダリングされた Kubernetes マニフェストを受け入れ、 +STDOUT で有効な Kubernetes マニフェストを返す任意の実行可能ファイルです。 +失敗した場合は、0 以外の終了コードを返します。 +これは、2つのコンポーネント間の唯一の "API" です。 +これにより、ポストレンダリングプロセスで実行できる操作に大きな柔軟性がもたらされます。 + +ポストレンダラーは、`install`、`upgrade`、および `template` で使用できます。 +ポストレンダラーを使用するには、 +使用するレンダラー実行可能ファイルへのパスで `--post-renderer` フラグを使用します。 + +```shell +$ helm install mychart stable/wordpress --post-renderer ./path/to/executable +``` + +パスにセパレータが含まれていない場合は、$PATH で検索されます。 +それ以外の場合は、相対パスが完全修飾パスに解決されます。 + +複数のポストレンダラーを使用したい場合は、それらをすべてスクリプトで呼び出すか、 +ビルドしたバイナリツールで一緒に呼び出します。 +bash では、これは `renderer1 | renderer2 | renderer3` のように単純です。 + +`kustomize` をポストレンダラーとして使用する例は +[here](https://github.com/thomastaylor312/advanced-helm-demos/tree/master/post-render)で見ることができます。 + +### 警告事項 +ポストレンダラーを使用する際には、いくつかの重要なことを覚えておく必要があります。 +その中でも最も重要なのは、ポストレンダラーを使用する場合、 +そのリリースを変更するすべての人は、ビルドを再現可能にするために、同じレンダラーを使用 **しなければならない** ということです。 +この機能は、ユーザーが使用しているレンダラーを切り替えたり、 +レンダラーの使用を停止したりできるように意図的に構築されていますが、 +これは偶発的な変更やデータの損失を避けるために意図的に行う必要があります。 + +もう一つの重要な注意点は、セキュリティに関するものです。 +ポストレンダラを使用する場合は、 +信頼できるソースからのものであることを確認する必要があります (他の任意の実行ファイルの場合と同様です)。 +信頼されていない、または検証されていないレンダラーを使用することは推奨されません。 +レンダリングされたテンプレートに完全にアクセスできるため、秘密のデータが含まれていることが多いからです。 + +### カスタムポストレンダラー +ポストレンダラーステップは、Go SDK で使用するとさらに柔軟性が増します。 +ポストレンダラーは、以下の Go インターフェースを実装するだけで済みます。 + +```go +type PostRenderer interface { + // Run expects a single buffer filled with Helm rendered manifests. It + // expects the modified results to be returned on a separate buffer or an + // error if there was an issue or failure while running the post render step + Run(renderedManifests *bytes.Buffer) (modifiedManifests *bytes.Buffer, err error) +} +``` + +Go SDK の使用方法については、[Go SDK セクション](#go-sdk)を参照してください。 + +## Go SDK +Helm 3 では、Helm を活用したソフトウェアやツールを構築する際の操作性を向上させるために、 +完全に再構築された Go SDK がデビューしました。 +完全なドキュメントは [https://pkg.go.dev/helm.sh/helm/v3](https://pkg.go.dev/helm.sh/helm/v3) にありますが、 +最も一般的なパッケージの簡単な概要と簡単な例を以下に示します。 + +### パッケージ概要 +よく使われるパッケージを、 +それぞれについて簡単に解説します。 + +- `pkg/action`: Helm のアクションを実行するためのメインの「クライアント」が含まれています。 + これは、CLI がフードの下で使用しているのと同じパッケージです。 + 他の Go プログラムから基本的な Helm コマンドを実行する必要がある場合は、 + このパッケージが適しています。 +- `pkg/{chart,chartutil}`: チャートの読み込みと操作に使用される + メソッドとヘルパー +- `pkg/cli` とそのサブパッケージ: 標準 Helm 環境変数のすべてのハンドラを含み、 + そのサブパッケージには + 出力と値のファイル処理が含まれています。 +- `pkg/release`: `Release` オブジェクトとステータスを定義します + +これら以外にもたくさんのパッケージがあるのは明らかなので、 +詳しくはドキュメントをチェックしてみてください。 + +### 簡単な例 +これは、Go SDK を使って `helm list` を実行する簡単な例です。 + +```go +package main + +import ( + "log" + "os" + + "helm.sh/helm/v3/pkg/action" + "helm.sh/helm/v3/pkg/cli" +) + +func main() { + settings := cli.New() + + actionConfig := new(action.Configuration) + // You can pass an empty string instead of settings.Namespace() to list + // all namespaces + if err := actionConfig.Init(settings.RESTClientGetter(), settings.Namespace(), os.Getenv("HELM_DRIVER"), log.Printf); err != nil { + log.Printf("%+v", err) + os.Exit(1) + } + + client := action.NewList(actionConfig) + // Only list deployed + client.Deployed = true + results, err := client.Run() + if err != nil { + log.Printf("%+v", err) + os.Exit(1) + } + + for _, rel := range results { + log.Printf("%+v", rel) + } +} + +``` + +## ストレージバックエンド + +Helm 3 はデフォルトでリリース情報をリリースのネームスペースに Secrets として保存するように変更しました。 +Helm 2 はデフォルトでリリース情報を ConfigMaps として Tiller インスタンスの名前空間に保存します。 +以下のサブセクションでは、異なるバックエンドを設定する方法を示します。 +この設定は、環境変数 `HELM_DRIVER` に基づいています。 +`[configmap, secret]` のいずれかの値を設定することができます。 + +### ConfigMap ストレージバックエンド + +ConfigMap バックエンドを有効にするには、 +環境変数 `HELM_DRIVER` を `configmap` に設定する必要があります。 + +次のようにシェルで設定します。 + +```shell +export HELM_DRIVER=configmap +``` + +デフォルトのバックエンドから ConfigMap バックエンドに切り替えたい場合は、 +自分でマイグレーションを行う必要があります。 +リリース情報は以下のコマンドで取得できます。 + +```shell +kubectl get secret --all-namespaces -l "owner=helm" +``` + +**プロダクションの注意**: リリース情報には、不正アクセスから保護する必要がある機密データ (パスワード、秘密鍵、その他の資格情報など) が含まれている可能性があります。 +Kubernetes の認証を管理する際に、 +例えば [RBAC](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) を使用して、 +Secret リソースへのアクセスを制限しつつ、 +ConfigMap リソースへの幅広いアクセスを許可することができます。 +例えば、デフォルトの[ユーザー向けロール](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#user-facing-roles)「view」では、 +ほとんどのリソースへのアクセスを許可しますが、 +Secrets へのアクセスは許可しません。 +さらに、Secrets データは[encrypted ストレージ](https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/)に設定することができます。 +ConfigMap バックエンドに切り替える場合は、 +アプリケーションの機密データが漏洩する可能性があることを念頭に置いてください。 diff --git a/content/ja/docs/topics/architecture.md b/content/ja/docs/topics/architecture.md new file mode 100644 index 0000000000..ccf3ba7b93 --- /dev/null +++ b/content/ja/docs/topics/architecture.md @@ -0,0 +1,63 @@ +--- +title: "Helm アーキテクチャ" +description: "Helm アーキテクチャの概要を説明します。" +weight: 8 +--- + +# Kubernetes Helm アーキテクチャ + +このドキュメントでは、Helm アーキテクチャの概要について説明します。 + +## Helm の目的 + +Helm は、_チャート_ と呼ばれる Kubernetes パッケージを管理するためのツールです。 +Helm は次のことができます。 + +- 最初から新しいチャートを作成する +- チャートをチャートアーカイブ (tgz) ファイルにパッケージ化する +- チャートが保存されているチャートリポジトリを操作する +- チャートを既存の Kubernetes クラスターにインストールおよびアンインストールする +- Helm でインストールされたチャートのリリースサイクルを管理する + +Helm には、3つの重要な概念があります。 + +1. _チャート_ は、Kubernetes アプリケーションのインスタンスを作成するために必要な +情報のバンドルです +2. _コンフィグ_ には、リリース可能なオブジェクトを作成するためにパッケージ化された + チャートにマージできる構成情報が含まれています +3. _リリース_ は、特定の _コンフィグ_ と組み合わせた _チャート_ の + 実行中のインスタンスです + +## コンポーネント + +Helm は、2つの異なる部分に実装される実行可能ファイルです。 + +**Helm クライアント** は、エンドユーザー向けのコマンドラインクライアントです。 +クライアントは次のことを担当します。 + +- ローカルチャート開発 +- リポジトリの管理 +- リリースの管理 +- Helm ライブラリとのインターフェース + - インストールするチャートを送信する + - 既存のリリースのアップグレードまたはアンインストールの要求 + +**Helm ライブラリ** は、すべての Helm 操作を実行するためのロジックを提供します。 +Kubernetes API サーバーとインターフェースし、次の機能を提供します。 + +- チャートと構成を組み合わせてリリースを構築する +- チャートを Kubernetes にインストールし、後続のリリースオブジェクトを提供する +- Kubernetes との対話によるチャートのアップグレードとアンインストール + +スタンドアロンの Helm ライブラリは Helm ロジックをカプセル化しているため、 +さまざまなクライアントが活用できます。 + +## 実装 + +Helm クライアントとライブラリは、Go プログラミング言語で記述されています。 + +ライブラリは、Kubernetes クライアントライブラリを使用して Kubernetes と通信します。 +現在、そのライブラリは REST + JSON を使用しています。 +Kubernetes 内にあるシークレットに情報を保存します。独自のデータベースは必要ありません。 + +構成ファイルは、可能な場合は YAML で作成されます。 diff --git a/content/ja/docs/topics/chart_tests.md b/content/ja/docs/topics/chart_tests.md new file mode 100644 index 0000000000..49d41f41b1 --- /dev/null +++ b/content/ja/docs/topics/chart_tests.md @@ -0,0 +1,98 @@ +--- +title: "チャートのテスト" +description: "チャートを実行およびテストする方法について説明します。" +weight: 3 +--- + +チャートには、連携して動作するいくつかの Kubernetes リソースとコンポーネントが含まれています。 +チャートの作成者は、チャートがインストールされたときにチャートが期待どおりに機能することを検証するテストを作成することができます。 +これらのテストは、 +チャートの利用者がチャートで何をするかを理解するのにも役立ちます。 + +Helm チャートの **テスト** は、`templates/` ディレクトリの下にあり、 +実行する特定のコマンドを含むコンテナーを指定するジョブ定義です。 +テストが成功したと見なされるには、コンテナが正常に終了 (exit 0) する必要があります。 +ジョブ定義には、helm テストフックアノテーション `helm.sh/hook: test` が含まれている必要があります。 + +テストの例: + +- values.yaml ファイルの構成が適切に挿入されたことを確認する + - 正しいユーザー名とパスワードが機能することを確認する + - 正しくないユーザー名とパスワードが機能しないことを確認する +- サービスが稼働しており、正しく負荷分散されていることを確認する +- など + +コマンド `helm test <リリース名>` を使用して、リリースの Helm で事前定義されたテストを実行できます。チャートの利用者にとって、これはチャート (またはアプリケーション) のリリースが期待どおりに機能することを正常性チェックする優れた方法です。 + +## テストの例 + +以下は、mariadb チャートの例における Helm テストポッド定義の例です。 + +``` +mariadb/ + Chart.yaml + README.md + values.yaml + charts/ + templates/ + templates/tests/test-mariadb-connection.yaml +``` + +`wordpress/templates/tests/test-mariadb-connection.yaml` の内容 + +```yaml +apiVersion: batch/v1 +kind: Job +metadata: + name: "{{ .Release.Name }}-credentials-test" + annotations: + "helm.sh/hook": test +spec: + template: + spec: + containers: + - name: main + image: {{ .Values.image }} + env: + - name: MARIADB_HOST + value: {{ template "mariadb.fullname" . }} + - name: MARIADB_PORT + value: "3306" + - name: WORDPRESS_DATABASE_NAME + value: {{ default "" .Values.mariadb.mariadbDatabase | quote }} + - name: WORDPRESS_DATABASE_USER + value: {{ default "" .Values.mariadb.mariadbUser | quote }} + - name: WORDPRESS_DATABASE_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "mariadb.fullname" . }} + key: mariadb-password + command: ["sh", "-c", "mysql --host=$MARIADB_HOST --port=$MARIADB_PORT --user=$WORDPRESS_DATABASE_USER --password=$WORDPRESS_DATABASE_PASSWORD"] + restartPolicy: Never +``` + +## リリースでテストスイートを実行する手順 + +1. `$ helm install quirky-walrus mariadb --namespace default` +2. `$ helm test quirky-walrus` + +```cli +NAME: quirky-walrus +LAST DEPLOYED: Mon Feb 13 13:50:43 2019 +NAMESPACE: default +STATUS: deployed +REVISION: 0 +TEST SUITE: quirky-walrus-credentials-test +Last Started: Mon Feb 13 13:51:07 2019 +Last Completed: Mon Feb 13 13:51:18 2019 +Phase: Succeeded +``` + +## メモ + +- 単一の yaml ファイルで必要なだけテストを定義するか、 + `templates/` ディレクトリ内の複数の yaml ファイルに分散することができます +- より分離するために、テストスイートを `/templates/tests/` のような + `tests/` ディレクトリの下にネストすることができます +- テストは [Helm フック](/docs/charts_hooks/)であるため、 + `helm.sh/hook-weight` や `helm.sh/hook-delete-policy` などのアノテーションをテストリソースで使用できます diff --git a/content/ko/blog/2019-11-13-helm-3-released.md b/content/ko/blog/2019-11-13-helm-3-released.md new file mode 100644 index 0000000000..476072bf6c --- /dev/null +++ b/content/ko/blog/2019-11-13-helm-3-released.md @@ -0,0 +1,125 @@ +--- +title: "Helm 3.0.0 출시!" +slug: "helm-3-released" +authorname: "Matthew Fisher" +author: "@bacongobbler" +authorlink: "https://blog.bacongobbler.com" +date: "2019-11-13" +--- + +헬름 팀은 헬름 3의 첫번째 안정적 릴리스를 발표하게 된 것을 자랑스럽게 생각한다. + +헬름 3는 CLI 도구의 최신 주(major) 릴리스이다. 헬름 2의 성공을 기반으로, 헬름 3도 진화하는 생태계의 요구에 계속 부응하고 있다. + +헬름 3의 내부 구현은 헬름 2와는 상당히 다르게 변경되었다. 가장 눈에 띄는 변화는 틸러(Tiller)가 제거된 것이다. 다만 새 릴리스에서 다른 변경사항들도 확인해두는 게 좋다. 커뮤니티의 의견과 요구사항에 따라 다양한 새로운 기능들이 추가되었다. 일부 기능은 헬름 2와 호환되지 않는 방식으로, 더 이상 사용되지 않거나 리팩토링되었다. OCI 지원을 포함하는 일부 실험적 기능도 도입되었다. + +추가로, 헬름 Go SDK 도 범용적으로 리팩토링되었다. 목표는 오픈 소스로 만든 코드를 Go 커뮤니티와 폭넓게 공유하고 재사용하는 것이다. 자신의 프로젝트에 헬름을 연계하여 사용하는 다른 엔지니어들의 의견을 활발하게 수용하고 있으며, [#헬름-개발 쿠버네티스 슬랙 채널](https://slack.k8s.io/)에서도 여러분들의 의견을 듣고자 한다. + +다음은 헬름 3의 몇 가지 리소스이다: + +- [문서](https://helm.sh/docs/) +- [FAQ: 헬름 2에서 바뀐 점](https://helm.sh/docs/faq/#changes-since-helm-2) +- [헬름 설치](https://helm.sh/docs/intro/install/) +- [헬름 2에서 헬름 3로의 마이그레이션에 대한 문서](https://helm.sh/docs/topics/v2_v3_migration/) +- [헬름 2에서 헬름 3로 마이그레이션하는데 도움이 되는 플러그인](https://github.com/helm/helm-2to3) +- [#헬름-사용자 쿠버네티스 슬랙 채널](https://slack.k8s.io/)에서 개발자 및 참여자와 채팅 +- 에서 버그 신고 + +## 헬름이란? + +헬름은 쿠버네티스 내에서 애플리케이션의 생성, 설치, 관리를 협업하는 데에 필요한 도구를 팀에 제공한다. + +헬름을 통하여, 사용자는 다음과 같은 것들을 할 수 있다. + +- 설치하여 사용할만한 패키징된 소프트웨어(차트) 찾기 +- 자신만의 패키지를 쉽게 만들고 호스팅 +- 모든 쿠버네티스 클러스터에 패키지 설치 +- 클러스터에 질의하여 설치되어 실행중인 패키지 확인 +- 설치된 패키지의 이력을 업데이트, 삭제, 롤백 및 조회 + +헬름을 사용하면 쉽게 쿠버네티스 내에서 애플리케이션을 실행할 수 있다. + +## 함께 살펴보자! + +쿠버네티스 클러스터가 구동 중이고 `kubectl` 이 알맞게 설정되었다면, 헬름 작업은 식은 죽 먹기이다. + +헬름을 사용하면 커뮤니티에서 호스팅하는 저장소를 추가하여 새 차트를 쉽게 검색할 수 있다. + +```bash +$ helm repo add nginx https://helm.nginx.com/stable +``` + +저장소를 추가했다면 차트를 검색할 수 있다: + +```bash +$ helm search repo nginx-ingress +NAME CHART VERSION APP VERSION DESCRIPTION +nginx/nginx-ingress 0.3.7 1.5.7 NGINX Ingress Controller +``` + +헬름은 `helm install` 을 사용하여 차트를 빠르게 설치할 수 있는 방법을 제공한다. + +```bash +$ helm install my-ingress-controller nginx/nginx-ingress +``` + +`kubectl` 로 클러스터를 확인해 보면: + +```bash +$ kubectl get deployments +``` + +구동 중인 인그레스 컨트롤러(ingress controller)가 있다! `helm uninstall my-ingress-controller` 로 간단히 제거할 수 있다. + +자, 이제 몇 가지 차트를 적용해보았다. 또한 일부를 커스터마이즈해보았다. 이제 직접 만들 준비가 되었다. 헬름은 이 부분도 쉽게 해준다. + +```bash +$ helm create diy +Creating diy +``` + +이제 `diy` 라는 새 차트가 생겼다. 해당 디렉터리로 이동하여 편집하거나 `helm template` 을 실행하여 렌더링된 출력 결과를 보거나 `helm install` 을 사용하여 설치할 수 있다. + +[헬름 허브](https://hub.helm.sh/)에 업스트림으로 제출할 것인가? 주의하자! 헬름 허브에 [나만의 저장소를 추가](https://github.com/helm/hub/blob/master/Repositories.md)하기 위한 문서를 따라야 한다. + +## 헬름 3에서 변경되는 사항은? + +이쯤에서 이런 의문이 들지도 모르겠다. + +> 헬름 2에서는 워크플로가 어떻게 변경되었나? 헬름 2로 이러한 명령을 실행하면 동일한 출력 결과가 표시될까? + +헬름 2는 차트 생성, 설치, 관리를 위한 워크플로를 기술하였다. 헬름 3는 이러한 워크플로를 기반으로 진화하는 생태계의 요구사항을 충족하도록 기본 인프라를 변경하였다. + +만약 사용자가 헬름 2에 익숙할 경우, 헬름 3 를 사용하면 마치 집에 있는 것처럼 편안하게 느껴질 것이다. + +내부적으로 변경된 사항에 대해 자세히 알아보기 위하여 문서의 [FAQ를 확인](https://helm.sh/docs/faq/)하자. 변경 목록과 관련된 변경 사항에 대한 설명이 여기 제공된다. + +## 헬름의 미래 + +핵심 관리자들은 헬름 3를 출시하게 되어 매우 기쁘다. 헬름의 다음 개발 단계에서는 기존 기능에 대한 안정성 및 향상을 목표로 하는 새로운 기능을 볼 수 있다. 로드맵 상의 기능은 다음과 같다: + +- `helm test` 의 기능 향상 +- 헬름의 OCI 연계 개선 +- Go 클라이언트 라이브러리의 기능 향상 + +### 헬름 2 지원 계획 + +헬름 2.15.0 릴리스 발표에서 헬름 2의 향후 계획에 대한 세부사항을 공유했다. 이 계획에 대한 자세한 내용은 [공지 게시물](https://helm.sh/blog/2019-10-22-helm-2150-released/)에서 확인할 수 있다. + +## 헬름 3와 헬름 1, 2와의 관계 + +2015년 11월, 첫 번째 KubeCon 에서 헬름 첫 번째 버전이 출시되었다. macOS 소프트웨어 인스톨러 [Homebrew](https://brew.sh/)에서 모델링된 헬름 1 (팀에서는 "헬름 클래식" 이라고 한다)은 개별 개발자가 쿠버네티스 리소스 패키지를 만들고 클러스터에 배포할 수 있도록 설계되었다. + +몇 달 후(2016년 1월), Deis 의 코어 헬름 팀은 구글, Skippbox, Bitnami 와 협력하여 개인들에서 팀으로 방점을 옮겨 새로운 버전의 헬름을 제작하였다. 그 과정에서 여러 경험과 교훈들이 적용되었다. 그 결과 팀워크는 핵심가치가 되었고, 정교한 애플리케이션을 설치하려는 쿠버네티스 사용자들의 참여로 급성장한 커뮤니티의 요구를 충족시키기 위해 설계된 도구가 탄생하였다. + +2018년 6월 헬름은 [Cloud Native Computing Foundation에 가입](https://helm.sh/blog/helm-enters-the-cncf/)했다. 헬름 3는 Microsoft, 삼성 SDS, IBM 및 Blood Orange의 구성원을 포함하는 주요 유지관리자들의 공통된 노력이다. 첫 번째 알파 릴리스 이래로, 헬름 3는 여러 시간대(time zone)에 걸쳐 커뮤니티 구성원 37명의 기여가 있었다. 그 결과물은 시시각각 변화하고 진화하며 커뮤니티의 요구를 담아낸 도구이다. + +## 결론 + +우리는 쿠버네티스로의 진입로가 되는 도구를 만들었다. 쿠버네티스 사용자가 운영 수준의 워크로드를 더 쉽게 생성, 공유, 실행할 수 있도록 돕고자 했다. + +설립 이래 500명 이상의 커뮤니티 회원이 헬름 CLI를 위한 코드에 기여해왔다. 수천 명의 커뮤니티 회원이 헬름 허브에서 차트를 활성적으로 관리한다. 수많은 활성 커뮤니티 회원들이 있다. 이는 이 프로젝트를 간단한 Deis 인스톨러를 모든 쿠버네티스 사용자를 위한 강력한 도구로 탈바꿈시킨 쿠버네티스 커뮤니티의 엄청난 노력에 의한 산물이다. + +모두 감사합니다. 깃헙에서 또 봐요! + +- 헬름 팀 :heart: diff --git a/content/ko/blog/2019-11-15-helm-at-cloudnativecon.md b/content/ko/blog/2019-11-15-helm-at-cloudnativecon.md new file mode 100644 index 0000000000..fe1b13e5c2 --- /dev/null +++ b/content/ko/blog/2019-11-15-helm-at-cloudnativecon.md @@ -0,0 +1,17 @@ +--- +title: "KubeCon + CloudNativeCon NA 2019 에서의 헬름" +authorname: "Matt Farina" +author: "@mattfarina" +authorlink: "https://mattfarina.com" +date: "2019-11-15" +--- + +다음 주에는 연례행사인 [KubeCon 과 CloudNativeCon 이 북미에서](https://events19.linuxfoundation.org/events/kubecon-cloudnativecon-north-america-2019/) 열린다. 헬름 프로젝트 및 유지관리자들은 몇 가지를 준비하고 있고 여러분을 초대하고 싶다. + +헬름 관련으로는 유지관리자 트랙 세션이 2개 있으며, [_헬름 소개_](https://sched.co/UajI) 및 [_헬름 3 심층 분석_](https://sched.co/Uagg)에 초점을 둔 내용이다. 헬름을 처음 사용하거나, 사용해야 하는 이유와 방법에 관심이 있는 사람은 _헬름 소개_ 세션에 참석해보자. [최근 출시된 헬름 3](https://helm.sh/blog/helm-3-released/)가 궁금한 사용자는 _헬름 3 심층 분석_ 세션이 적당할 것 같다. 관심을 가질 법한 주변 사람들에게도 널리 알려주자. + +올해는 헬름 프로젝트가 자체 프로젝트만의 독립된 부스를 가지는 첫 해이기도 하다! 헬름 유지관리자와 얘기를 나누고 싶거나 프로젝트에 대해 질문이 있다면 부스를 방문하여, 정기적으로 프로젝트를 진행하는 사람들을 만나보도록 하자. + +올해는 커뮤니티에서 준비한 몇 가지 흥미로운 헬름 관련 세션들도 있다. 예를 들어, CERN 의 Ricarto Rocha 는 [_CERN 에서 Gitops와 함께 헬름 배포 관리하기_](https://sched.co/UabD)에 대한 내용을 발표한다. [공식 일정표](https://events19.linuxfoundation.org/events/kubecon-cloudnativecon-north-america-2019/schedule/)에서 다른 세션에 대한 일정도 확인할 수 있다. + +컨퍼런스가 시작하기 전 주말에 가도 될까? [Cloud_Native Rejekts](https://cloud-native.rejekts.io/)가 계속 진행될 것이며, 헬름 프로젝트 유지관리자 중 한 명인 Taylor Thomas는 [_(헬름으로 배우는) 쿠버네티스와의 고급 상호작용_](https://cfp.cloud-native.rejekts.io/cloud-native-rejekts-na-2019/talk/SQ9DWX/)을 발표할 예정이다. diff --git a/content/ko/blog/2020-04-02-covid-19-extending-helm-v2-bug-fixes.md b/content/ko/blog/2020-04-02-covid-19-extending-helm-v2-bug-fixes.md new file mode 100644 index 0000000000..59939545ce --- /dev/null +++ b/content/ko/blog/2020-04-02-covid-19-extending-helm-v2-bug-fixes.md @@ -0,0 +1,13 @@ +--- +title: "COVID-19: 헬름 v2 버그 수정 확장" +slug: "covid-19-extending-helm-v2-bug-fixes" +authorname: "Matt Farina & Bridget Kromhout" +authorlink: "https://helm.sh" +date: "2020-04-03" +--- + +전 세계가 전염병에 맞서 싸우기 위해 힘을 모으는 것처럼 헬름 유지관리자들도, 개발 및 운영 일정이 조정되는 시기에도 최대 수요로 작동하는 주요 시스템을 유지보수하는 사용자들에게, 도움을 주는 역할을 잘 수행하고 있는지 점검하고자 한다. + +헬름 v3가 2019년 11월에 출시되었을 때, 원래의 약속은 6개월 동안 헬름 v2 버그 수정을 제공하겠다는 것이었다. 버그 수정은 2020년 5월 13일에 종료되고, 그 후로 6개월 간 보안 수정이 예정되어 있었다. 감염병 예방이 우선이라는 전제 하에, 헬름 v2 버그 수정을 2020년 8월 13일까지 3개월 연장하여 헬름 사용자들이 커뮤니티의 가장 필요한 요구 사항에 대응할 계획이다. + +여러 가지 상황으로 인해 추가 일정 조정이 필요한지 확인하기 위해 상황을 모니터링할 것이다. 현재로서는 헬름 v2 지원이 11월 13일에 종료될 예정이다. (다만 보안 수정만은 3개월간으로 계획되어 있다.) 핵심 업무의 단절을 방지하고 안전을 지키기 위해 우리가 할 수 있는 일이 있다면 [커뮤니티 연락, 채팅, 메일링 리스트, 깃헙 저장소'](https://github.com/helm/community/blob/main/communication.md)를 통해 얘기해보자! diff --git a/content/ko/blog/2020-04-30-celebrating-helms-cncf-graduation.md b/content/ko/blog/2020-04-30-celebrating-helms-cncf-graduation.md new file mode 100644 index 0000000000..bbf9aaed0a --- /dev/null +++ b/content/ko/blog/2020-04-30-celebrating-helms-cncf-graduation.md @@ -0,0 +1,34 @@ +--- +title: "헬름의 CNCF 졸업을 축하하며" +slug: "celebrating-helms-cncf-graduation" +authorname: "Matt Butcher" +author: "@technosophos" +authorlink: "https://twitter.com/technosophos" +date: "2020-04-30" +twittertype: "summary_large_image" +twitterimage: "blog/images/helmgraduation-twitter.png" +--- + +![../images/helmgraduation.png](../images/helmgraduation.png) + +오늘 헬름이 [CNCF 사다리의 마지막 단계에 도달한 것](https://www.cncf.io/announcement/2020/04/30/cloud-native-computing-foundation-announces-helm-graduation/)을 보게 되어 기쁘다. 헬름은 [CNCF 프로젝트](https://www.cncf.io/projects/)의 인큐베이팅 단계에서 졸업 단계로 이동하여, 쿠버네티스 등 다른 선택된 프로젝트들과 나란히 서게 되었다. + +헬름은 작은 스타트업 Deis의 해커톤 프로젝트로 소박하게 시작되었는데, 우리의 작은 아기가 완전히 성인으로 성장한 것처럼 기분이 정말 좋다. 그리고 우리는 지난 5년 동안 코딩, 커뮤니티, 조직 정책에 대해 많은 것을 배웠다. 그러나 이것이 우리가 헬름의 졸업을 축하하는 주요 이유는 아니다. + +헬름 프로젝트를 시작하고 몇 달 후, 우리는 쿠버네티스의 하위 프로젝트가 되었다. 그게 2016년 초였는데, 얼마 지나지 않아 사이드 프로젝트 수준이 아닌 쿠버네티스 생태계의 패키지 관리자로 자리매김하게 되었다. 쿠버네티스는 복잡성을 감추지 않고 SRE 및 DevOps 스토리에 집중했지만, 헬름은 다른 접근 방식을 취했다. 2016년 2월 회의에서 [Michelle Noorali](https://twitter.com/michellenoorali)는 화이트 보드에 다음과 같은 문구를 썼다. "5분만에 0에서 도파민까지" 이것이 우리 헬름의 만트라였다. 새로운 사용자를 쿠버네티스에 더 쉽게 접근하게 할 수 있다고 보았다. 우리가 옳았다면, 사용자는 헬름을 설치하고 몇 분 내로 운영 수준의 규격품 구성요소들을 설치할 수 있을 것이다. + +요즘 헬름은 대학생부터 주요 클라우드 제공 업체에 이르기까지 [쿠버네티스 사용자의 70% 이상이 사용](https://www.cncf.io/wp-content/uploads/2020/03/CNCF_Survey_Report.pdf)하고 있다. 신규 쿠버네티스 사용자가 헬름 덕분에 빠르게 설치하고 구동시킬 수 있었다는 얘기를 들을 때가 가장 뿌듯하다. + +한편, 헬름의 졸업은 2번째 구별점을 뜻한다. 헬름의 첫 번째 커밋 이래로 우리는 이것을 "쿠버네티스용 패키지 관리자"라고 불렀다. 즉 전반적인 설계의 초점은 쿠버네티스 리소스 정의 번들의 재배포, 설치, 업그레이드, 삭제를 가능하게 하는 것이다. 우리의 목표는 macOS 에서의 homebrew, 데비안/우분투에서의 apt-get, 윈도우에서의 Chocolatey처럼 쿠버네티스에서의 패키지 관리자가 되는 것이었다. + +당시에는 대단하지 않은 목표로 보였다. 쿠버네티스(버전 1.2) 사용자도 거의 없었다. 그런데 갑자기 쿠버네티스의 인기가 폭발적으로 증가했다. 몇몇 유명 회사에서는 운영 환경에 사용하기 시작했다. 그런 다음에는 주요 클라우드 제공 업체가 호스팅된 쿠버네티스 상품을 만들었다. 그리고 화려함보다 안정성을 추구하던 대기업들도 쿠버네티스를 본격적으로 사용하기 시작했다. 이것은 헬름에 대한 시험대(acid test)였다. 서로 다른 목표와 요구를 가진 사용자 수십만 명의 요구를 충족시킬 수 있는가? 그런 것 같아 보인다. + +"졸업"이라는 용어는 주요 요구사항들을 완수했다는 것을 의미한다. 수많은 사용자 기반을 갖춘 것은 고무적이었지만, CNCF 는 엔터프라이즈 준비도를 시험하는 기준 목록을 제시한다. 안정성, 보안, 강건한 거버넌스, 강력한 커뮤니티 -- 대규모 오픈 소스 프로젝트가 성공하려면 이러한 것들이 절대적으로 필요하다. + +CNCF는 [프로젝트](https://www.cncf.io/projects/)가 대다수의 사용자들이 사용할 수 있도록 준비되었다는 것을 입증할 때만 졸업시킨다. 인큐베이션에서 졸업으로 이동하기 위한 기준 목록은 안정적인 오픈 소스 프로젝트가 무엇인지를 정의하고 있다. 헬름에는 졸업 기준들이 깊이 녹아있다. 헬름은 보안 검토를 그냥 통과한 수준이 아니라 아주 우수한 성적으로 통과했다. 우리는 [CII 뱃지](https://bestpractices.coreinfrastructure.org/en)를 획득했을 뿐 아니라, [인증테스트에서 198%](https://bestpractices.coreinfrastructure.org/en/projects?q=helm%20package%20manager)를 기록했다. 서로 다른 회사의 커미터 2명만 있었지만, 이제는 전세계적으로 수많은 기여자들이 있다. 그리고 지난 수년간 개방적이고 공정한 거버넌스라는 우리의 약속을 지켜왔다. + +그래서 지금 우리는 이 이정표에 서 있다. 우리는 졸업에 관한 마지막 요구사항을 완수하였다. CNCF 기술 감독위원회(TOC)에서 대다수는 헬름이 최고 수준의 프로젝트라는 데에 동의하여 투표하였다. + +그렇다면 앞으로 헬름에는 어떤 변화가 있을까? 프로세스 측면에서는 모든 것이 그대로 유지된다. 우리는 메이저 버전에서 마이너 버전까지 안정성과 호환성에 대한 확고한 약속을 계속 유지할 것이다. 헬름 4에서 어떤 것이 더 필요할지에 대한 초기 단계의 조사도 시작하였다. 우리는 (항상 그랬듯이), 커뮤니티에 자신의 경험을 공유하려는 사용자, 상당한 시간을 들여 프로젝트 유지에 기여하려는 노련한 전문가 등 새로운 참여자를 열렬히 환영한다. 또한 우리는 CNCF 내에서 몇 가지 주요 움직임을 하나로 모으게 될 [CNCF 아티팩트 허브](https://devclass.com/2020/03/12/cncf-starts-new-artifact-hub/)에 대해서도 기대하고 있다. CNCF 커뮤니티와의 협업을 계속 해나는 것도 신나는 일이다. + +우리의 전통에 따라, 헬름의 성공에 기여한 수만 명의 커뮤니티 회원들에게 커다란 감사의 마음으로 전하며 이 글을 마친다. "5분만에 0에서 도파민까지" 경험을 모든 쿠버네티스 사용자에게 전해주기 위한 오랜 노력이 여기에 있다! diff --git a/content/ko/blog/2020-08-13-helm-v2-deprecation-timeline.md b/content/ko/blog/2020-08-13-helm-v2-deprecation-timeline.md new file mode 100644 index 0000000000..48156872d7 --- /dev/null +++ b/content/ko/blog/2020-08-13-helm-v2-deprecation-timeline.md @@ -0,0 +1,45 @@ +--- +title: "헬름 v2 사용중단 타임라인" +slug: "helm-v2-deprecation-timeline" +authorname: "Bridget Kromhout" +author: "@bridgetkromhout" +authorlink: "https://twitter.com/bridgetkromhout" +date: "2020-08-12" +--- + + +_[루이스 캐롤에게 고개를 끄덕이며...](https://www.jabberwocky.com/carroll/walrus.html)_ + + “때가 되었습니다,” 메인테이너(maintainers)는 말한다, + “소프트웨어의 운명에 대하여 이야기하기 위해: + 업그레이드와 -- 헬름 v3의 출시와 -- + 버그의 수정 -- 그리고 k8s. --” + +헬름 v3는 [2019년 11월에 출시되었으며](/blog/helm-3-released/), 커뮤니티의 요구에 부응하여 헬름을 계속 발전시켜온 커뮤니티의 노력의 결과입니다. 간소화된 클라이언트 단독 사용환경, 새로운 보안 관점, 쿠버네티스 API와의 더욱 긴밀한 연계를 통하여 헬름 v3는 쿠버네티스에 대한 운영 테스트 패키지 관리 기능을 계속 제공합니다. 그리고 [졸업한 CNCF 프로젝트](/blog/celebrating-helms-cncf-graduation/)인 헬름은 클라우드 네이티브 생태계의 핵심부분입니다. + +운영 환경에 주(major) 버전 변경사항을 반영하려면 시간이 필요하다는 것을 우리도 인지하고 있다. 헬름 메인테이너(maintainer)는 2020년 5월까지 헬름 v2에 대한 버그픽스([2020년 8월로 연장됨](/blog/covid-19-extending-helm-v2-bug-fixes/)), 2020년 11월까지 헬름 v2에 대한 보안패치를 제공하기로 했다. 그리고 이제 버그픽스 창은 닫힙니다. [헬름 v2.16.10](https://github.com/helm/helm/releases/tag/v2.16.10)은 최종 버그픽스 릴리스이며 2.17.0은 [다운로드 위치가 변경](https://github.com/helm/helm/issues/8346)되어 나올 것이다. + +헬름 사용자에게 이는 어떤 의미인가? + +_2020년 8월 13일 이후, 다음의 변경 사항이 적용된다:_ +- 만약 아직 헬름 v2를 사용중인 경우 지금 [헬름 v3로 마이그레이션](/blog/migrate-from-helm-v2-to-helm-v3/)하는 것이 좋다. 헬름 3.2.4는 널리 사용되고 있으며 운영준비가 되어있다. 대체로 이전 버전과 호환되지만 마이그레이션을 수행할 때 알아야 할 변경사항들이 있다. +- 지금부터, 헬름 v2에 대한 지속적인 지원은 향후 3개월의 보안패치로 제한된다. 즉, 확인된 보안 문제 외에는 더 이상 PR 요청을 수락하지 않는다. +- `stable` 및 `incubator` 저장소는 [2018년 12월에 도입된](/blog/intro-helm-hub/) 헬름 허브에서 삭제된다. [헬름 허브](https://hub.helm.sh)에서 선호하는 저장소를 찾아 구성에 추가하고, [새로운 분산 저장소들로의 마이그레이션을 수행해야](https://github.com/helm/charts/issues/21103) 한다. + + +_2020년 11월 13일 이후로 다음과 같은 변경사항이 적용된다._ +- 더 이상 헬름 v2는 릴리스되지 않는다. (보안 패치조차도) +- 더 이상 [헬름 v2 문서](https://v2.helm.sh/docs)에 대한 업데이트도 없다. 현재로서는 계속 사용될 수도 있지만, 중단될 수도 있다. +- v2와 관련된 기존 및 신규 이슈/PR 은 닫히게 된다. +- [헬름 릴리스와 차트 호스팅에 대한 소유권(ownership)을 CNCF로 이관](https://github.com/helm/community/issues/114). + +| | | +| - | - | +| 제거 예정 | 교체 예정 | +| 구글 클라우드 스토리지를 통한 헬름 v2 클라이언트 다운로드 | [get.helm.sh](/blog/get-helm-sh/)을 통한 클라이언트 다운로드 | +| 구글 컨테이너 레지스트리에 저장된 틸러(Tiller)용 도커 이미지 | [대신 다른 위치에서 사용 가능한](https://github.com/helm/helm/issues/8346) 틸러 이미지를 배포하며, helm init --tiller-image 명령어로 업데이트 가능하게 할 것이다. | +| 안정적(stable)인 인큐베이터 차트 저장소를 위한 구글 클라우드 버킷 | “안정적” 인 “인큐베이터” 저장소 사용 중단; https://github.com/helm/charts 는 사용되지 않음(obsolete)으로 표시 | + +커뮤니티는 헬름 v3가 훨씬 개선된 환경임을 확인했으며, [helm-2to3 플러그인](https://github.com/helm/helm-2to3)과 같은 커뮤니티 리소스를 사용하여 필수 마이그레이션을 지원할 수 있다. 더 이상 보안 패치가 제공되지 않는 소프트웨어를 운영하게 되는 위험을 피하는 가장 좋은 방법은, 11월 13일 이전에 헬름 v3로의 마이그레이션을 완료하는 것이다. + +이 자리를 빌어, 헬름을 사용하거나 개선을 위해 문제를 제기하거나 요청을 제출한 커뮤니티의 모든 분들께 감사드린다. 여러 훌륭한 아이디어들이 헬름에는 맞지 않더라도 [관련 생태계의 프로젝트](https://helm.sh/docs/community/related/)에서 많은 성공을 거두었다. 문서에 대한 업데이트를 제출할 때마다 다른 사용자들이 헬름을 시작하고 더 효과적으로 사용하는 데 도움이 된다. 모두들 감사합니다! diff --git a/content/ko/blog/2020-10-07-helm-hub-moving-artifact-hub.md b/content/ko/blog/2020-10-07-helm-hub-moving-artifact-hub.md new file mode 100644 index 0000000000..3752b7f481 --- /dev/null +++ b/content/ko/blog/2020-10-07-helm-hub-moving-artifact-hub.md @@ -0,0 +1,34 @@ +--- +title: "헬름 허브의 아티팩트 허브로의 이동" +slug: "helm-hub-moving-to-artifact-hub" +authorname: "Matt Farina" +author: "@mattfarina" +authorlink: "https://mattfarina.com" +date: "2020-10-07" +--- + +오늘 헬름 허브가 [아티팩트 허브](https://artifacthub.io/)로 이동한다. 즉, 헬름 허브로 이동하면 아티팩트 허브로 리다이렉션된다. + +## 이것은 무엇을 의미하는가? + +헬름 허브를 검색하거나 헬름 허브에서 차트 목록을 조회할 때 의문이 들지도 모르겠다. 무슨 차이가 있는걸까? + +아티팩트 허브에서는 헬름 허브에서 조회된 것과 동일한 차트 목록이 모두 조회된다. 더 빠른 검색을 제공하며 [국면 검색](https://en.wikipedia.org/wiki/Faceted_search)을 포함한다. 이전과 비슷한 방식으로 차트를 검색할 수 있다. 검색은 헬름 CLI에서도 계속 작동한다. + +아티팩트 허브에는 차트를 검색하는 것 외에도 많은 기능이 있다. 차트가 업데이트되면 이메일 또는 웹훅을 통해 알림을 받을 수 있다. 다른 아티팩트를 찾고 관련 아티팩트를 볼 수 있다. 아티팩트 허브에는 헬름 허브보다도 많은 것을 제공한다. + +헬름 허브에 차트 저장소를 나열하고 아티팩트 허브에 아직 나열하지 않은 경우 자동으로 가져온다. 아티팩트 허브는 저장소를 요청하고 새 저장소를 나열하는 수단을 제공한다. 저장소를 나열할 때 사용자 계정 또는 다중 사용자 조직에 연결할 수 있다. + +## 왜 이렇게 해야 하는가? + +헬름 허브는 모노큘러(Monocular) 프로젝트를 기반으로 구축되었다. 이 프로젝트는 제한된 수의 헬름 저장소를 처리하도록 빌드되었으며, 가능한한 많은 차트 저장소의 공개 목록과 약간 다른 사용 사례를 위해 설계되었다. 헬름 프로젝트를 잘 수행해왔지만, 헬름 차트 및 저장소 수가 증가함에 따라 몇가지 제한 사항들이 나타나기 시작했다.헬름 허브를 사용하여 이 문제에 대해 뭔가를 해야 한다는 것을 우리도 알고 있었다. + +우리가 성장에 대한 문제를 경험하기 시작하면서 아티팩트 허브가 등장했다. 아티팩트 허브의 자체 인스턴스를 운영하거나 스케일링 문제를 처리하기 위해 자체 소프트웨어를 작성하는 대신 차트 검색 및 관리를 처리하기 위해 아티팩트 허브를 사용하기로 결정했다. 아티팩트 허브는 단순히 차트만 제공하는 것이 아니라 더 많은 CNCF 생태계를 지원하고 홍보하고 있다. + +## 질문, 우려 또는 문제점 + +만약 전환하다가 문제가 있으면 알려 달라. 알리는 방법은 몇 가지가 있다. + +1. 문제가 마이그레이션 간 아티팩트 허브의 차트 저장소에 대한 것이라면, [헬름 허브 저장소](https://github.com/helm/hub)에 이슈를 등록하자. +2. 아티팩트 허브 사이트에 문제가 있다면 [아티팩트 허브 프로젝트](https://github.com/artifacthub/hub)에 이슈를 등록할 수 있다. 이 곳은 CNCF 프로젝트이자 오픈소스 프로젝트이다. +3. 헬름 CLI를 사용하여 아티팩트 허브를 검색하는 데 문제가 있는가? [헬름](https://github.com/helm/helm)에 이 이슈를 등록할 수 있다. 차트의 URL은 검색에서 찾을 때 기본적으로 `hub.helm.sh` 로 시작된다. diff --git a/content/ko/blog/2020-10-19-helm-turns-five.md b/content/ko/blog/2020-10-19-helm-turns-five.md new file mode 100644 index 0000000000..3eabec0fa1 --- /dev/null +++ b/content/ko/blog/2020-10-19-helm-turns-five.md @@ -0,0 +1,41 @@ +--- +title: "헬름 5주년과 깃헙으로부터의 차트 선물" +slug: "helm-turns-five" +authorname: "Matt Butcher & Matt Farina" +author: "@technosophos & @mattfarina" +authorlink: "https://helm.sh" +date: "2020-10-19" +--- + +{{< figure src="https://helm.sh/blog/images/happy-5th.png" alt="헬름의 5번째 생일 축하" >}} + +5년 전, Deis(그 후 마이크로스프트에 인수됨)의 해커톤에서 헬름이 탄생했다. + + +``` +commit ecad6e2ef9523a0218864ec552bbfc724f0b9d3d +Author: Matt Butcher +Date: Mon Oct 19 17:43:26 2015 -0600 + + initial add +``` + +[이 커밋](https://github.com/helm/helm-classic/commit/ecad6e2ef9523a0218864ec552bbfc724f0b9d3d)은 헬름 v1 용 코드베이스가 있는 헬름 클래식 깃 저장소에서 찾을 수 있다. + +이것은 디플로이먼트 매니저와 병합되어 쿠버네티스에 합쳐지기 전의 원래 헬름이다. 이것이 모든 것이 시작된 곳이다. + +첫날부터 헬름 프로젝트는 소스 관리, 풀 요청 관리 및 문제 추적을 위해 깃헙을 사용해왔다. 졸업한 CNCF 프로젝트로서, 헬름 조직은 이제 수십 개의 깃헙 저장소를 운영하고 있다. 하지만 패키징된 차트를 호스팅할 때는, 구글 클라우드에서 호스팅하는 객체 스토리지 버킷에 저장했다. 당시의 이러한 결정은 구글이 헬름의 주요 기여자였다는 점이 반영된 것이다. + +최근, 구글의 공식 헬름 차트 저장소 지원기간이 종료되었다. 지난 몇 년동안 구글이 헬름 차트 저장소를 호스팅해준 것에 대해 감사한다. 또한 이 일은 차트 개발 파이프라인을 깃헙과 통합할 수 있는 기회가 되었다. + +{{< figure src="../images/octocat.png" alt="Hello Github Octocat!" width="350px" >}} + +그래서 오늘의 생일 축하 행사에서, 헬름 `stable` 및 `incubator` 차트 저장소가 깃헙에서 직접 호스팅된다는 것을 알리고자 한다. 또한, 깃헙 액션으로 차트 게시를 위한 파이프라인이 강화되었다. 깃헙의 엄청 빠른 네트워크 덕분에 차트 다운로드가 그 어느 때보다 더욱 빨라졌다! + +깃헙 마켓 플레이스에 공식 헬름 깃헙 액션을 게시하였다. 깃헙에서 헬름 차트를 호스팅하는 방법에 대해서는 [헬름 차트 릴리서(Helm Chart Releaser)](https://github.com/marketplace/actions/helm-chart-releaser)를 참고하자. + +헬름 2는 지원이 종료되었지만, [공식 틸러 도커 이미지](https://github.com/orgs/helm/packages)는 깃헙의 컨테이너 저장소에도 옮겨 놓았다. + +깃헙에서 제공한 도구와 여러 오픈 소스 프로젝트에 대한 지원에 깊이 감사한다. + +생일 축하한다, 헬름! diff --git a/content/ko/blog/2020-10-26-new-location-stable-incubator-charts.md b/content/ko/blog/2020-10-26-new-location-stable-incubator-charts.md new file mode 100644 index 0000000000..d9c254052a --- /dev/null +++ b/content/ko/blog/2020-10-26-new-location-stable-incubator-charts.md @@ -0,0 +1,96 @@ +--- +title: "Stable 및 Incubator 차트를 위한 새로운 공간" +slug: "new-location-stable-incubator-charts" +authorname: "Matt Farina" +author: "@mattfarina" +authorlink: "https://mattfarina.com" +date: "2020-10-26" +--- + +[이전에 발표한 것과 같이](https://helm.sh/ko/blog/helm-turns-five/), stable 및 incubator 저장소가 새로운 공간으로 이동하게 된다. +이 게시물은 새로운 위치에 대한 업데이트를 제공하고 그것을 사용하는 방법을 제공한다. + +_**중요한 참고사항:** 이는 2019 년에 발표된 stable 및 incubator 저장소의 오래된 타임 라인에 영향을 주지 않는다. +2020 년 11 월 13 일에 stable 및 incubator 차트 저장소는 개발이 끝나고 아카이브가 된다. +많은 차트가 커뮤니티에서 관리하는 다른 저장소로 이동했음을 알 수 있다. +[아티팩트 허브](https://artifacthub.io/)에서 확인할 수 있다. +노후화에 대한 자세한 정보는 향후 블로그 게시물 및 커뮤니케이션에서 이어질 예정이다._ + +stable 저장소의 새 위치는 https://charts.helm.sh/stable이고 incubator 저장소의 새 위치는 https://charts.helm.sh/incubator 이다. +아래의 이전 위치 중 하나에서 차트를 사용하는 경우 2020 년 11 월 13 일 이전에 사용하는 저장소를 업데이트 해야한다. +새 위치는 깃헙 페이지를 사용하여 호스팅된다. + +| 이름 | 이전 위치 | 새 위치 | +| --------- | ------------ | ------------ | +| stable | https://kubernetes-charts.storage.googleapis.com | https://charts.helm.sh/stable | +| incubator | https://kubernetes-charts-incubator.storage.googleapis.com | https://charts.helm.sh/incubator | + + +새 위치와 함께 헬름 v2.17.0 및 v3.4.0 이 릴리스 되어 새 위치에서 사용할 수 있다. +최신 버전으로 업그레이드하는 것이 좋다. + +## 헬름 v3.4.0 + +헬름 v3.4.0은 이제 이전 위치로 구성된 안정 및 인큐베이터 저장소가 있는지 감지하고 구성을 새 위치로 업데이트해야 함을 경고한다. +단일 명령을 사용하여 이를 수행 할 수 있다. +예를 들어 `stable` 이라는 이름으로 설정된 안정적인 저장소를 업데이트하려면 다음을 실행할 수 있다. + +``` +helm repo add stable https://charts.helm.sh/stable --force-update +``` + +이 명령은 v3.4.0 이전의 헬름 v3 버전에서도 작동한다. +최신 헬름 v3 릴리스로 업데이트하지 않고도 사용할 수 있다. + +또한 `helm repo add` 를 사용하여 이전 위치에 있는 저장소 중 하나를 추가하려고 하면 Helm v3.4.0 이상 버전은 저장소를 추가하지 못하고 새 위치를 사용하도록 경고한다. +자동으로 새 위치를 추가하는 대신 사람들에게 위치 변경을 알리고 싶은 의도이다. +이전 위치 중 하나를 사용해야하는 이유가 있는 경우 새로운 `--allow-deprecated-repos` 플래그를 사용할 수 있다. +플래그는 이전 위치가 계속 작동하는 동안에만 유용하다. + +## 헬름 v2.17.0 + +헬름 v2 에서는 `helm init` 가 실행될 때 기본적으로 stable 저장소를 추가했다. +이로 인해 v2.17.0 부터는 헬름 v2 에 대한 다른 솔루션이 도입되었다. + +stable 저장소 또는 로컬 저장소가 필요하지 않은 경우 `helm init` 를 실행할 때 `--skip-repos` 플래그를 사용할 수 있다. +이것은 v2.17.0의 새로운 플래그이다. +안정적인 저장소를 사용하지 않는 CI 시스템과 같은 일부 사용 사례에서 성능상의 이점이 있을 수 있다. + +v2.17.0 에서 `helm init` 가 실행되면 이전 위치 대신 새 위치가 사용된다. +이것은 정기적으로 `helm init` 를 실행하는 CI 시스템에서 발생한다. +이전 위치를 계속 사용해야 하는 경우 새로운 `--use-deprecated-stable-repository` 플래그를 `helm init` 에 전달할 수 있습니다. +이것은 이전 위치가 계속 작동하는 동안에만 작동한다. + +stable 또는 incubator 저장소에 대해 구성된 이전 위치가 이미 있는 경우 헬름은 새 위치로 전환해야 한다는 경고를 표시한다. +Helm v2에서는 작업 수행 시 두 개의 명령을 사용해야 한다는 점에서 +Helm v3와 약간 다르다. +예를 들어 `stable` 저장소를 변경하려면 다음을 실행할 수 있다. + +``` +helm repo rm stable +helm repo add stable https://charts.helm.sh/stable +``` + +이 명령은 v2.17.0 이전의 Helm v2 버전에서 작동한다. +최신 Helm v2 릴리스로 업데이트 하지 않고도 사용할 수 있다. + +_참고 : GitHub 페이지로 이동하는 stable 및 incubator 저장소 외에도 +[틸러(Tiller)의 기본 위치가 GitHub 컨테이너 저장소 (ghcr.io)로 이동되었다](https://github.com/orgs/helm/packages/container/package/tiller). +[틸러는 GCR에서 계속 사용할 수 있다](https://gcr.io/kubernetes-helm/tiller) (이전 위치). +[도커 허브] (https://hub.docker.com/r/helmpack/tiller) 및 [Quay] (http://quay.io/helmpack/tiller)에서도 틸러를 다운로드 할 수 있다. +틸러의 기본 위치가 아닌 위치를 지정하려면 `helm init`를 실행할 때 `-i` 또는 `--tiller-image` 플래그를 사용할 수 있다._ + +## 사용자만의 복제본 호스팅 하기 + +헬름이 네트워크 호출을 할 수 있는 위치를 제어 할 수 있고 +헬름이 깃헙 페이지를 호출하지 않도록 하는 경우가 있다. +stable 또는 incubator 저장소의 차트가 필요한 경우 한 가지 옵션은 +자신의 저장소에 필요한 차트 및 차트 버전의 사본을 호스팅하는 것이다. +[ChartMuseum] (https://github.com/helm/chartmuseum), [Harbor] (https://goharbor.io/), 정적 웹 서버 또는 다른 시스템으로 이 저장소를 호스팅 할 수 있다. + +헬름 조직 및 차트 관리자 중 한 명인 Scott Rigby는 [차트와 기록의 전체 또는 일부를 복사 할 수있는 스크립트](https://github.com/scottrigby/helm-adopt-package-history)를 만들었다(이전 차트 버전). +이 도구 및 이와 유사한 도구를 사용하여 사용하는 차트의 복사본을 만들 수 있다. +이것은 다른 위치에서 제공 될 수 있다. + +헬름 v2 에서는 `--stable-repo-url` 플래그를 사용하여 `helm init` 를 실행할 때 +안정적인 저장소의 대체 위치를 지정할 수 있다. diff --git a/content/ko/blog/2020-10-30-charts-repo-deprecation.md b/content/ko/blog/2020-10-30-charts-repo-deprecation.md new file mode 100644 index 0000000000..833a45fed1 --- /dev/null +++ b/content/ko/blog/2020-10-30-charts-repo-deprecation.md @@ -0,0 +1,38 @@ +--- +title: "헬름 차트 저장소 지원 중단 업데이트" +slug: "charts-repo-deprecation" +authorname: "Vic Iglesias" +author: "@vicnastea" +authorlink: "https://twitter.com/vicnastea" +date: "2020-10-30" +--- + +2019 년에 헬름 v2 지원 타임 라인 및 수명 종료 계획이 발표되었을 때 [helm/charts GitHub 저장소](https://github.com/helm/charts)의 [지원 중단](https://github.com/helm/charts#deprecation-timeline)도 발표되었다. 지원 중단의 주된 이유는 [저장소 관리자](https://github.com/helm/charts/blob/master/OWNERS)의 유지 관리가 크게 증가했기 때문이다. 지난 몇 년 동안 유지 관리중인 차트 수가 100 개 이하에서 300 개 이상으로 증가하여 저장소에 대한 풀 요청 및 업데이트가 이에 상응하게 증가했다. 안타깝게도 검토 및 유지 관리 작업을 자동화하려는 많은 노력에도 불구하고 관리자의 유지 관리 시간은 단축되지 않았다. + +지원 중단을 발표했을 때 우리는 helm/charts repo를 유지하는 데 사용했던 도구와 지침도 공유하기 시작했다. 자체 저장소를 호스팅하고 유지하려는 사람들을 위해 이제 다음 도구를 사용하여 프로세스를 간소화 할 수 있다. + +- [차트 테스트](https://github.com/helm/chart-testing)는 차트에 대한 PR 린팅(Linting) 및 테스트를 제공한다. +- [차트 Releaser](https://github.com/helm/chart-releaser) 는 아티팩트를 호스팅하는 데 사용되는 깃헙 릴리스 및 페이지를 사용하여 자체 차트 저장소를 호스팅 하는데 도움이 되는 도구를 제공한다. +- [깃헙 동작 테스트 및 릴리징](https://github.com/helm?q=chart+action) 는 위에서 설명한 깃헙 동작을 사용하여 도구를 자동화 한다. + +이러한 도구를 사용하여 활성 유지 관리를 위해 많은 차트를 [자체 저장소로 마이그레이션] (https://github.com/helm/charts/issues/21103) 할 수 있다. + +## 주요 날짜 및 권장되는 조치 + +계획이 수정되면서 다음에 일어날 일에 대한 혼란/질문이 있었기에 앞으로 진행할 주요 이벤트 및 ** 권장 조치 **의 타임 라인을 제공하고자 한다. + +* 2020년 11월 2일 - 지원 중단되지 않는 모든 차트의 README 에 더 이상 업데이트 되지 않는다는 메모가 추가된다. + * **권장 조치** - 차트 저장소의 차트에 의존하는 경우 새 공식 위치를 찾아야 한다. 존재하지 않을 경우 차트의 적용을 고려하라. +* 2020년 11월 6일 - [아티팩트 허브](https://artifacthub.io/)에서 stable 및 incubator 차트 저장소가 삭제된다. + * **권장 조치** - 없음 +* 2020년 11월 13일 - [helm/charts 저장소](https://github.com/helm/chart)의 CI가 비활성화되고 더 이상 Pull Request 가 허용되지 않는다. + * **권장 조치** - 차트를 새 저장소로 재배치하기 위한 진행중인 발의(initiative) 대한 자세한 내용은 [이 문제](https://github.com/helm/charts/issues/21103)를 참조하자. +* 2020년 11월 13일 *이후* - 이전 위치에서 차트를 다운로드하면 GitHub 페이지에서 사용할 수있는 읽기 전용 아카이브로 리디렉션된다. 이 날짜 이후에는 이전 위치를 더 이상 사용할 수 없다. + * **권장 조치** - [보관된 stable 및 incubator 차트로의 전환](https://helm.sh/docs/faq/#i-am-getting-a-warning-about-unable-to-get-an-update-from-the-stable-chart-repository)에 대한 정보를 참조하라. 이 차트는 더 이상 버그 수정이나 보안 패치로 업데이트되지 않는다. + + +## 참조 + +* [차트 저장소 지원 중단 일정](https://github.com/helm/charts/issues/23944) +* [패키지 이력 재배치](https://github.com/helm/charts/issues/23850) +* [헬름 차트 호스팅을 CNCF로 전환하도록 요청](https://github.com/helm/community/issues/114) diff --git a/content/ko/blog/images/happy-5th.png b/content/ko/blog/images/happy-5th.png new file mode 100644 index 0000000000..8d99085b9e Binary files /dev/null and b/content/ko/blog/images/happy-5th.png differ diff --git a/content/ko/blog/images/helm-2to3.png b/content/ko/blog/images/helm-2to3.png new file mode 100644 index 0000000000..a5372385cb Binary files /dev/null and b/content/ko/blog/images/helm-2to3.png differ diff --git a/content/ko/blog/images/helmgraduation-twitter.png b/content/ko/blog/images/helmgraduation-twitter.png new file mode 100644 index 0000000000..c8be7e89bc Binary files /dev/null and b/content/ko/blog/images/helmgraduation-twitter.png differ diff --git a/content/ko/blog/images/helmgraduation.png b/content/ko/blog/images/helmgraduation.png new file mode 100644 index 0000000000..019b6eecdd Binary files /dev/null and b/content/ko/blog/images/helmgraduation.png differ diff --git a/content/ko/blog/images/octocat.png b/content/ko/blog/images/octocat.png new file mode 100644 index 0000000000..ac88aec901 Binary files /dev/null and b/content/ko/blog/images/octocat.png differ diff --git a/content/ko/docs/_index.md b/content/ko/docs/_index.md new file mode 100644 index 0000000000..f91e4555b5 --- /dev/null +++ b/content/ko/docs/_index.md @@ -0,0 +1,26 @@ +--- +title: "문서 홈" +description: "문서 구성에 관해 알아야 할 모든 것" +--- + +# 환영 + +[헬름](https://helm.sh/ko) 문서에 온 것을 환영한다. +헬름은 쿠버네티스를 위한 패키지 관리 도구이며, +자세한 배경 지식은 +[CNCF 헬름 프로젝트 여정 보고서](https://www.cncf.io/cncf-helm-project-journey/)에서 확인할 수 있다. + +# 문서 구성 + +헬름은 많은 문서를 가지고 있다. 구성 방법에 대한 대략의 개요를 보면 +무엇을 어디서 찾아볼지를 알 수 있어 도움이 될 것이다. + +- [튜토리얼](intro)은 나의 첫번째 차트 만들기 단계별 과정을 통해 이끌어 준다. + 헬름이 처음이라면 여기서 시작하자. +- [주제 가이드](topics)는 대략의 핵심 주제와 개념을 다루며 + 유용한 배경 정보와 설명을 제공한다. +- [커뮤니티 가이드](community)는 헬름 커뮤니터와 관련된 주제를 다룬다. + 헬름 자체의 개발 과정이나 기여하는 방법을 알아보려면 여기서 시작하자. +- [방법 가이드](howto)는 일종의 요리법(recipes)이다. + 주요 문제 및 사용 사례들을 다루는 절차를 안내한다. + 튜토리얼보다 심화된 내용으로서, 헬름이 작동하는 방식에 대한 지식이 어느 정도 있다고 가정한다. diff --git a/content/ko/docs/chart_best_practices/_index.md b/content/ko/docs/chart_best_practices/_index.md new file mode 100644 index 0000000000..1f4402b63e --- /dev/null +++ b/content/ko/docs/chart_best_practices/_index.md @@ -0,0 +1,15 @@ +--- +title: "모범 사례" +sidebar: true +weight: 4 + +--- + +# 차트 모범 사례 가이드 + +이 가이드에서는 헬름 팀이 고려한 차트 생성 모범 사례를 다룹니다. +주로 차트를 구성하는 방법에 중점을 둘 것입니다. + +여기에서는 주로 공개 배포 가능한 차트의 모범 사례에 중점을 둡니다. +물론 많은 차트들이 내부 사용 목적으로 작성되고, +그런 차트의 작성자들은 여기에 제안된 것들을 활용하여 내부에서 사용하는 방법을 찾을 것이라는 것도 알고 있습니다. diff --git a/content/ko/docs/chart_best_practices/conventions.md b/content/ko/docs/chart_best_practices/conventions.md new file mode 100644 index 0000000000..70e1f1126a --- /dev/null +++ b/content/ko/docs/chart_best_practices/conventions.md @@ -0,0 +1,46 @@ +--- +title: "일반적인 관례" +description: "차트에 대한 일반적인 관례" +weight: 1 +--- + +이 부분은 모범사례 가이드의 일부로서 일반적인 관례를 설명한다. + +## 차트 이름 + +차트 이름은 소문자와 숫자여야 한다. 단어는 대시(-)로 구분할 수 있다. + +예시: + +``` +drupal +nginx-lego +aws-cluster-autoscaler +``` + +대문자나 밑줄문자는 차트 이름에 사용할 수 없다. 점도 사용할 수 없다. + +## 버전 번호 + +가능하다면 어디서든, 헬름은 버전 번호를 표현할 때 [SemVer 2](https://semver.org)를 사용한다. +(도커 이미지 태그는 SemVer를 따를 필요가 없고 +아쉽지만 규칙에서 예외로 취급된다는 점을 알아두자.) + +SemVer 버전을 쿠버네티스 레이블로 저장할 때, +관례적으로 `+` 문자를 `_` 문자로 변경하는데, +`+` 기호는 레이블 값으로 허용되지 않기 때문이다. + +## YAML 형식 + +YAML 파일은 _2칸_ (탭이 아니다) 들여쓰기해야 한다. + +## 헬름과 차트 단어의 사용 + +_Helm_ 과 _helm_ 단어 사용에 관한 관례는 다음과 같다. + +- _Helm_(헬름)은 전체 프로젝트를 가리킨다. +- `helm`은 클라이언트측 명령어를 가리킨다. +- `chart`는 첫글자를 대문자로 쓸 필요가 없는데, 고유명사가 아니기 때문이다. +- 반면, `Chart.yaml`는 첫글자를 대문자로 써야 하는데, 파일명에는 대소문자 구분이 있기 때문이다. + +애매할 때는 _Helm_(대문자 'H', 헬름)을 쓰자. diff --git a/content/ko/docs/chart_best_practices/custom_resource_definitions.md b/content/ko/docs/chart_best_practices/custom_resource_definitions.md new file mode 100644 index 0000000000..dae9914c81 --- /dev/null +++ b/content/ko/docs/chart_best_practices/custom_resource_definitions.md @@ -0,0 +1,57 @@ +--- +title: "커스텀 리소스 데피니션(CRD)" +description: "CRD를 생성하고 사용하는 방법" +weight: 7 +--- + +이 부분은 모범사례 가이드의 일부로서 커스텀 리소스 데피니션 객체를 생성하고 사용하는 것을 다룬다. + +커스텀 리소스 데피니션(CRD)를 다룰 때에는, 다음 2가지를 구분하는 것이 중요하다. + +- CRD의 선언이 있다. 이것은 종류(kind)가 `CustomResourceDefinition`인 YAML 파일이다. +- 그리고 그 CRD를 사용하는 리소스들이 있다. 어떤 CRD가 `foo.example.com/v1`를 정의한다고 해보자. + `apiVersion: example.com/v1`가 있고 종류(kind)가 `Foo`인 모든 리소스들은 그 CRD를 사용하는 리소스이다. + +## 리소스를 사용하기 전에 CRD 선언을 설치하기 + +헬름은 되도록 많은 리소스들을 빨리 쿠버네티스 내에 로드(load)하도록 최적화되어 있다. +설계상, 쿠버네티스는 전체 매니페스트 세트를 받고 온라인으로 반영한다(이것을 조정(reconciliation) 루프라고 한다). + +하지만 CRD의 경우는 약간 다르다. + +해당 CRD 종류(kind) 리소스가 사용되기 전에, CRD 선언이 먼저 등록되어 있어야 한다. +그리고 등록 과정은 때에 따라 몇 초 정도 걸린다. + +### 방법 1: `helm`이 처리하게 하기 + +헬름 3이 나오면서, 더 단순한 방안을 위해 구식 `crd-install` 훅(hook)은 없어졌다. +이제는 `crds`라는 특수 디렉토리가 있어서, CRD를 만들고자 할 때 차트 내에 생성할 수 있다. +CRD는 템플릿은 아니지만 차트를 `helm install`으로 실행하면 기본으로 설치될 것이다. +CRD가 이미 있으면, 경고(warning)가 나오면서 넘어가게 된다. +CRD 설치 단계를 그냥 넘기고 싶다면, `--skip-crds` 플래그를 쓰면 된다. + +#### 주의사항 (및 설명) + +지금으로서는 헬름으로 CRD를 업그레이드하거나 삭제하는 것이 지원되지 않는다. +이는 의도치 않은 데이터 유실 위험을 우려한 커뮤니티 상의 많은 논의에 따른 명시적인 결정이다. +또한, 현재로서는 CRD와 그 수명주기를 어떻게 다룰 지에 대해 커뮤니티의 컨센서스가 없다. +논의가 진행되면 헬름은 그러한 사용사례에 대해 지원할 수 있게 될 것이다. + +현재 `helm install`와 `helm upgrade`의 `--dry-run` 플래그는 CRD를 지원하지 않는다. +"드라이런(Dry Run)"의 목적은 차트가 실제로 서버에 전송되었을 때 처리되어 나올 결과물을 검증하는 것이다. +그런데 CRD는 서버의 행동 자체를 변경시킨다. +헬름은 드라이런으로 CRD를 설치할 수 없으므로, 디스커버리 클라이언트는 커스텀 리소스(CR)에 대해 알 수 없고 검증은 실패하게 될 것이다. +대안으로 CRD를 별도의 CRD 자체의 차트로 옮기거나, `helm template`을 사용할 수 있다. + +CRD 지원 논의에서 고려할 다른 중요한 포인트는 템플릿 렌더링을 어떻게 처리할 것인지이다. +헬름 2에서 사용되던 `crd-install`의 뚜렷한 단점의 하나는 +API 기능범위 변경 때문에 차트를 제대로 검증할 수 없다는 점이다(CRD는 쿠버네티스 클러스터에 사용가능한 API를 실제로 추가한다). +차트가 CRD를 설치하면, `helm`이 사용하던 유효한 API 버전 세트가 더 이상 유효하지 않은 것이다. +이는 CRD에서 템플릿 지원이 제거된 데에 깔린 이유이기도 한다. +CRD를 설치하는 새로운 `crds` 방법에서는, `helm`이 클러스터의 현재 상태에 대해 완전히 유효한 정보를 가지고 있음이 보장된다. + +### 방법 2: 차트 분리하기 + +다른 방법으로는 한 차트에는 CRD 정의(definition)를 넣고 _다른_ 차트에는 CRD를 사용하는 리소스들을 넣는 방법이 있다. + +이 방법으로 할 때는, 각 차트가 따로 설치되어야 한다. 하지만, 이러한 작업방식은 클러스터에 어드민으로 접근하는 클러스터 운영자들에게 더 유용할 것이다. diff --git a/content/ko/docs/chart_best_practices/dependencies.md b/content/ko/docs/chart_best_practices/dependencies.md new file mode 100644 index 0000000000..18c26ecb0b --- /dev/null +++ b/content/ko/docs/chart_best_practices/dependencies.md @@ -0,0 +1,69 @@ +--- +title: "의존성" +description: "차트 의존성에 관한 모범사례를 다룬다." +weight: 4 +--- + +이 부분은 가이드의 일부로서 `Chart.yaml`에서 선언되는 `dependencies`에 관한 모범사례를 다룬다. + +## 버전 + +가능하면 특정 버전을 콕 집어서 사용하기 보다는 버전 범위를 사용하자. +권장되는 기본값은 다음과 같이 패치-수준의 버전 매치(match)를 사용하는 것이다. + +```yaml +version: ~1.2.3 +``` + +이렇게 하면 `1.2.3`과 그 릴리스의 다른 패치들도 매치된다. +다시 말하면 `~1.2.3`은 `>= 1.2.3, < 1.3.0`과 동등하다. + +버전 매칭 구문에 대한 자세한 설명은 [semver +문서](https://github.com/Masterminds/semver#checking-version-constraints)에서 볼 수 있다. + +### 리포지터리 URL + +가능하면 `https://` 리포지터리 URL 뒤에 `http://` URL을 사용하자. + +리포지터리가 리포지터리 인덱스 파일에 추가되면, 리포지터리 이름은 URL의 별칭으로 사용될 수 있다. +`alias:`나 `@` 뒤에 리포지터리 이름을 쓰자. + +차트에서 파일 URL(`file://...`)은 고정된 배포 파이프라인에서 만들어지는 "특이한 경우"로 취급된다. +공식 헬름 리포지터리에는 `file://`을 사용하는 차트가 허용되지 않는다. + +#### OCI 레지스트리에서 호스팅되는 차트에 대한 실험적 기능지원 + +[실험적 OCI 지원을 활성화(enabled)](/docs/registries/)했다면, +리포지터리 URL의 OCI 참조(`oci://registry/group/image:tag`)를 지정할 수 있다. + +OCI 참조를 지정한 경우, 리포지터리 URL이 이미지 태그(`oci://nginx:1.10`)를 가지고 있으면 `version` 인자를 생략해도 된다. +URL에 태그를 지정하지 않으면, `version`이 태그로 사용될 것이다. +이것은 OCI URL이 **SemVer 제약사항을 지원하지 않지만**, 태그된 버전은 지원한다는 것을 뜻한다. + +태그와 버전을 둘다 지정했다면, 태그가 우선 적용되며 버전은 무시된다. + +## 조건과 태그 + +조건과 태그는 _선택적(optional)_인 모든 의존성에 추가되어야 한다. + +조건의 권장되는 형식은 다음과 같다. + +```yaml +condition: somechart.enabled +``` + +여기서 `somechart`는 의존성의 차트 이름이다. + +여러 서브차트(의존성)들이 선택적 또는 교체가능한 기능을 공동으로 제공하는 경우, +그 차트들은 동일한 태그를 사용해야 한다. + +예를 들어, `nginx`와 `memcached`가 차트 내 메인 앱에 대한 성능 최적화 기능을 +공동으로 제공하는 경우, 그리고 그 기능의 활성화시에 둘다 있어야 한다면 +둘다 다음과 같은 태그 섹션이 있어야 한다. + +```yaml +tags: + - webaccelerator +``` + +이렇게 하면 사용자는 하나의 태그로 기능을 켜거나 끌 수 있다. diff --git a/content/ko/docs/chart_best_practices/labels.md b/content/ko/docs/chart_best_practices/labels.md new file mode 100644 index 0000000000..2b000dfd43 --- /dev/null +++ b/content/ko/docs/chart_best_practices/labels.md @@ -0,0 +1,42 @@ +--- +title: "레이블과 어노테이션" +description: "차트 내에서 레이블과 어노테이션을 사용하는 모범사례를 다룬다." +weight: 5 +--- + +이 부분은 모범사례 가이드의 일부로서 차트 내에서 레이블과 어노테이션을 사용하는 모범사례에 대해 논한다. + +## 레이블인가, 어노테이션인가? + +다음 조건에 해당하는 메타데이터 항목은 레이블이어야 한다. + +- 쿠버네티스에서 해당 리소스를 식별하기 위해 사용된다. +- 시스템 쿼리를 목적으로 운영자에게 유용하게 노출되어야 한다. + +예를 들어, `helm.sh/chart: NAME-VERSION`을 레이블로서 사용하는 것을 권장하는데, +이렇게 하면 운영자는 레이블을 통해 특정 차트의 모든 인스턴스들을 편리하게 찾을 수 있다. + +메타데이터 항목이 쿼리에 사용되지 않는다면, 어노테이션으로 설정해야 한다. + +헬름 훅은 항상 어노테이션이다. + +## 표준 레이블 + +아래 표에 헬름 차트에서 널리 사용되는 레이블이 있다. +헬름 자체는 특정 레이블을 필요로 하지 않는다. +REC로 표시된 레이블은 권장되는 것으로서, 전체적인 정합성 유지를 위해 차트에 있어야 한다. +OPT로 표시된 레이블은 선택사항이다. +이것들은 관용적 또는 일반적으로 사용하지만, 운영 목적에서는 그렇게 자주 사용하지 않는다. + +이름|상태|설명 +-----|------|---------- +`app.kubernetes.io/name` | REC | 전체 앱을 잘 나타내는 앱 이름을 써야 한다. 흔히 `{{ template "name" . }}`로 쓴다. 많은 쿠버네티스 매니페스트에서 사용되는 것으로서, 헬름에만 있는 것이 아니다. +`helm.sh/chart` | REC | 차트 이름과 버전을 써야 한다. `{{ .Chart.Name }}-{{ .Chart.Version \| replace "+" "_" }}`. +`app.kubernetes.io/managed-by` | REC | 항상 `{{ .Release.Service }}`로 설정해야 한다. 헬름이 관리하는 모든 것을 찾기 위한 것이다. +`app.kubernetes.io/instance` | REC | `{{ .Release.Name }}`이어야 한다. 동일한 애플리케이션의 다른 인스턴스들을 구별하는 데 도움이 된다. +`app.kubernetes.io/version` | OPT | 앱의 버전이며, `{{ .Chart.AppVersion }}`로 설정할 수 있다. +`app.kubernetes.io/component` | OPT | 하나의 애플리케이션 내에서 각 부분들이 맡은 역할을 표시하는 일반적인 레이블이다. 예를 들면 `app.kubernetes.io/component: frontend`. +`app.kubernetes.io/part-of` | OPT | 하나의 애플리케이션을 구성하는 데 여러 차트 또는 소프트웨어 부분들이 함께 사용되는 경우(예를 들어, 웹사이트를 제공하는 애플리케이션 소프트웨어와 데이터베이스), 그것들이 지원하는 최상위 애플리케이션으로 설정할 수 있다. + +`app.kubernetes.io` 접두어를 가진 쿠버네티스 레이블에 대한 더 자세한 정보는 +[쿠버네티스 문서](https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/)에서 찾아볼 수 있다. diff --git a/content/ko/docs/chart_best_practices/pods.md b/content/ko/docs/chart_best_practices/pods.md new file mode 100644 index 0000000000..b5722a00c6 --- /dev/null +++ b/content/ko/docs/chart_best_practices/pods.md @@ -0,0 +1,74 @@ +--- +title: "파드와 파드템플릿" +description: "차트 매니페스트에 있는 파드와 파드템플릿 부분의 형식을 논한다." +weight: 6 +--- + +이 부분은 모범사례 가이드의 일부로서 차트 매니페스트에 있는 파드와 파드템플릿 부분의 형식을 논한다. + +파드템플릿을 사용하는 리소스들(일부)은 다음과 같다. + +- 디플로이먼트(Deployment) +- 레플리케이션컨트롤러(ReplicationController) +- 레플리카셋(ReplicaSet) +- 데몬셋(DaemonSet) +- 스테이트풀셋(StatefulSet) + +## 이미지 + +컨테이너 이미지는 고정된 태그나 이미지의 SHA를 사용해야 한다. +`latest`, `head`, `canary` 등 "유동적인" 목적으로 고안된 태그를 +사용해서는 안된다. + +이미지를 쉽게 교체하기 위해 `values.yaml` 파일 내에 이미지를 정의할 수 있다. + +```yaml +image: {{ .Values.redisImage | quote }} +``` + +`values.yaml` 내에서 이미지와 태그를 각각의 필드로 정의할 수도 있다. + +```yaml +image: "{{ .Values.redisImage }}:{{ .Values.redisTag }}" +``` + +## ImagePullPolicy + +`deployment.yaml`는 + +```yaml +imagePullPolicy: {{ .Values.image.pullPolicy }} +``` + +`values.yaml`는 + +```yaml +image: + pullPolicy: IfNotPresent +``` + +라고 하면 그에 따라 `helm create`는 `imagePullPolicy` 기본값으로 `IfNotPresent`을 설정하게 된다. + +비슷하게, 쿠버네티스에서도 따로 정의하지 않더라도 `imagePullPolicy`의 기본값은 `IfNotPresent`이 된다. +`IfNotPresent` 외에 다른 값을 사용하려면, `values.yaml`에 있는 값을 원하는 값으로 바꾸면 된다. + + +## 파드템플릿에는 셀렉터가 선언되어야 한다 + +모든 파드템플릿 섹션에는 셀렉터를 지정해야 한다. 예를 들면, + +```yaml +selector: + matchLabels: + app.kubernetes.io/name: MyName +template: + metadata: + labels: + app.kubernetes.io/name: MyName +``` + +위의 것은 잘된 사례인데, 셋(set)과 파드 사이에 관계가 맺어졌기 때문이다. + +이것은 디플로이먼트와 같은 셋(set)의 경우에 더욱 중요하다. +관계가 맺어져 있지 않다면, _모든_ 레이블들이 매칭되는 파드 선택에 사용되며, +버전이나 릴리스 날짜와 같이 변경되는 레이블을 사용하는 경우 깨질 수 있다. diff --git a/content/ko/docs/chart_best_practices/rbac.md b/content/ko/docs/chart_best_practices/rbac.md new file mode 100644 index 0000000000..2046088313 --- /dev/null +++ b/content/ko/docs/chart_best_practices/rbac.md @@ -0,0 +1,79 @@ +--- +title: "역할 기반 접근 제어" +description: "차트 매니페스트에 있는 RBAC 리소스의 생성과 형식을 논한다." +weight: 8 +--- + +이 부분은 모범사례 가이드의 일부로서 차트 매니페스트에 있는 RBAC 리소스의 생성과 형식을 논한다. + +RBAC 리소스는 다음과 같다. + +- ServiceAccount (네임스페이스 구분) +- Role (네임스페이스 구분) +- ClusterRole +- RoleBinding (네임스페이스 구분) +- ClusterRoleBinding + +## YAML 설정 + +RBAC과 서비스어카운트(ServiceAccount) 설정은 개별 키로 되어야 한다. +둘은 별개의 것이다. +이 두가지 개념을 YAML 내에서 구분함으로써 둘 사이의 애매함을 없애고 명확히 할 수 있다. + +```yaml +rbac: + # RBAC 리소스를 생성할지 지정 + create: true + +serviceAccount: + # 서비스어카운트를 생성할지 지정 + create: true + # 사용할 서비스어카운트 이름 + # create가 true인데 이름이 지정되지 않으면, 풀네임 템플릿에 따라 이름이 생성됨 + name: +``` + +이 구조는 여러 개의 서비스어카운트를 필요로 하는 더 복잡한 차트로 확장할 수 있다. + +```yaml +someComponent: + serviceAccount: + create: true + name: +anotherComponent: + serviceAccount: + create: true + name: +``` + +## RBAC 리소스는 기본값으로 생성해야 한다 + +`rbac.create`는 RBAC 리소스를 생성할지를 컨트롤하는 불리언 값이어야 한다. +기본값은 `true`여야 한다. +RBAC 접근 제어를 직접 관리하려는 사용자는 +이 값을 `false`로 지정할 수 있다. (아래의 사례 참고) + +## RBAC 리소스 사용하기 + +`serviceAccount.name`는 차트로 생성된 접근제어 리소스가 사용할 +ServiceAccount 이름으로 설정해야 한다. +`serviceAccount.create`가 true이면, 그 이름으로 서비스어카운트가 생성된다. +이름이 설정되지 않았다면 `fullname` 템플릿을 사용하여 이름이 생성된다. +`serviceAccount.create`이 false이면, 서비스어카운트가 생성되지는 않지만, +나중에 RBAC 리소스를 수동으로 생성하고 참조하여 정상 작동하게 하려면 동일한 리소스들과 연계되어야 한다. +`serviceAccount.create`가 false이고 이름이 지정되지 않으면, 기본 서비스어카운트를 사용한다. + +서비스어카운트에 다음 헬퍼 템플릿을 사용해야 한다. + +```yaml +{{/* +사용할 서비스어카운트 이름 생성 +*/}} +{{- define "mychart.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "mychart.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} +``` diff --git a/content/ko/docs/chart_best_practices/templates.md b/content/ko/docs/chart_best_practices/templates.md new file mode 100644 index 0000000000..89a40fea7e --- /dev/null +++ b/content/ko/docs/chart_best_practices/templates.md @@ -0,0 +1,209 @@ +--- +title: "템플릿" +description: "템플릿에 관한 모범사례 들여다보기" +weight: 3 +--- + +이 부분은 모범사례 가이드의 일부로서 템플릿을 자세히 알아본다. + +## `templates/`의 구조 + +`templates/` 디렉토리는 다음과 같이 구조화되어야 한다. + +- YAML을 만드는 템플릿 파일들은 확장자가 `.yaml`이어야 한다. + 형식이 정해지지 않은 컨텐츠를 만드는 템플릿 파일에는 `.tpl` 확장자를 쓸 수 + 있다. +- 템플릿 파일 이름은 대시 표기법(`my-example-configmap.yaml`)을 따라야 하며, + 카멜 표기법이 아니다. +- 각 리소스 정의는 자체 템플릿 파일 내에 있어야 한다. +- 템플릿 파일 이름은 이름 내에 리소스 종류를 반영해야 한다. 예 : + `foo-pod.yaml`,`bar-svc.yaml` + +## 정의된 템플릿의 이름 + +정의된 템플릿 (`{{ define }}` 지시문 내에 생성된 템플릿)은 +전역에서 접근가능하다. 즉, 차트와 그 모든 하위 차트는 +`{{ define }}` 으로 생성된 모든 템플릿에 접근할 수 있다. + +위와 같은 이유로, _모든 정의된 템플릿 이름은 네임스페이스별로 구분되어야 한다._ + +올바른 경우: + +```yaml +{{- define "nginx.fullname" }} +{{/* ... */}} +{{ end -}} +``` + +잘못된 경우: + +```yaml +{{- define "fullname" -}} +{{/* ... */}} +{{ end -}} +``` +이 모범 사례에 따라 템플릿 이름이 자동으로 정의되므로, +`helm create` 명령을 통해 새 차트를 생성하는 것이 좋다. + +## 템플릿 형식 + +템플릿은 _스페이스 2개_ (탭 아님)를 사용하여 들여쓰기 해야 한다. + +템플릿 지시문에서 여는 중괄호 뒤와 닫는 중괄호 앞에는 +공백을 두어야 한다. + +올바른 경우: +``` +{{ .foo }} +{{ print "foo" }} +{{- print "bar" -}} +``` + +잘못된 경우: +``` +{{.foo}} +{{print "foo"}} +{{-print "bar"-}} +``` + +템플릿은 가능한 경우 공백을 줄여야 한다. + +```yaml +foo: + {{- range .Values.items }} + {{ . }} + {{ end -}} +``` + +블록 (예 : 제어 구조)은 템플릿 코드의 흐름을 나타내기 위해 +들여쓰기 할 수 있다. + +``` +{{ if $foo -}} + {{- with .Bar }}Hello{{ end -}} +{{- end -}} +``` + +하지만, YAML은 공백 지향 언어이기 때문에, +규칙에 따른 코드 들여쓰기가 불가능한 경우가 많다. + +## 생성된 템플릿의 화이트스페이스 + +생성된 템플릿의 공백을 최소로 유지하는 것이 좋다. +특히, 많은 수의 빈 줄이 서로 인접해 있으면 안된다. +그러나 가끔씩 나오는 빈 줄(특히 논리 섹션 사이)은 +무방하다. + +가장 좋은 경우: + +```yaml +apiVersion: batch/v1 +kind: Job +metadata: + name: example + labels: + first: first + second: second +``` + +괜찮은 경우: + +```yaml +apiVersion: batch/v1 +kind: Job + +metadata: + name: example + + labels: + first: first + second: second + +``` + +지양해야 할 경우: + +```yaml +apiVersion: batch/v1 +kind: Job + +metadata: + name: example + + + + + + labels: + first: first + + second: second + +``` + +## 주석 (YAML 주석 vs. 템플릿 주석) + +YAML과 헬름 템플릿 모두 주석 마커가 있다. + +YAML 주석: +```yaml +# This is a comment +type: sprocket +``` + +템플릿 주석: +```yaml +{{- /* +This is a comment. +*/}} +type: frobnitz +``` + +정의된 템플릿 설명과 같이 템플릿의 기능을 문서화할 때는, +템플릿 주석을 사용해야 한다. + +```yaml +{{- /* +mychart.shortname 은 릴리스 이름에서 6자만 자른 것을 제공한다. +*/}} +{{ define "mychart.shortname" -}} +{{ .Release.Name | trunc 6 }} +{{- end -}} + +``` + +템플릿 내에서, YAML 주석은 헬름 사용자가 디버깅 중에 주석을 볼 때 +유용하게 사용될 수 있다. + +```yaml +# 값이 100Gi를 넘으면 문제가 발생할 수 있다 +memory: {{ .Values.maxMem | quote }} +``` + +위의 주석은 사용자가 `helm install --debug` 를 실행할 때 표시되는데, +`{{-/ * * /-}}` 섹션에 지정된 주석은 표시되지 않는다. + +## 템플릿과 템플릿 출력에서 JSON 사용하기 + +YAML은 JSON의 상위집합이다. 경우에 따라서는, JSON 구문을 사용하는 것이 +다른 YAML 표현보다 더 읽기 쉬울 수 있다. + +예를 들어, 이 YAML은 목록을 표현하는 일반적인 YAML 방법에 더 가깝다. + +```yaml +arguments: + - "--dirname" + - "/foo" +``` + +그러나 JSON 목록 스타일로 축약하면 읽기가 더 쉽다. + +```yaml +arguments: ["--dirname", "/foo"] +``` + +가독성을 높이기 위해 JSON을 사용하는 것은 좋다. 하지만, 더 복잡한 구조를 나타내는 데에 +JSON 구문을 사용해서는 안된다. + +YAML (예를 들어 init 컨테이너 설정)에 포함된 순수 JSON을 다룰 때에는, +당연히 JSON 형식을 사용하는 것이 적절하다. diff --git a/content/ko/docs/chart_best_practices/values.md b/content/ko/docs/chart_best_practices/values.md new file mode 100644 index 0000000000..8a7e671fc9 --- /dev/null +++ b/content/ko/docs/chart_best_practices/values.md @@ -0,0 +1,162 @@ +--- +title: "값" +description: "값을 구성하고 사용하는 방법을 집중적으로 다룬다." +weight: 2 +--- + +이 부분은 모범사례 가이드의 일부로서 값(values)을 사용하는 방법을 다룬다. +여기서는 차트의 `values.yaml` 파일을 설계하는 데 초점을 맞추고, 값을 어떻게 구성하고 사용할지에 대한 권고사항을 제시한다. + +## 네이밍 컨벤션 + +변수 이름은 소문자로 시작해야하며 단어는 카멜케이스로 +구분해야 한다. + +올바른 경우: + +```yaml +chicken: true +chickenNoodleSoup: true +``` + +잘못된 경우: + +```yaml +Chicken: true # 첫 글자가 대문자이면 빌트인 변수와 충돌이 발생할 수 있다 +chicken-noodle-soup: true # 변수명에 하이픈(-)을 사용하지 말자 +``` + +헬름의 모든 빌트인 변수는 사용자 정의 값과 쉽게 구분할 수 있도록 +대문자로 시작한다: `.Release.Name`, +`.Capabilities.KubeVersion`. + +## 평면화(flat) 값, 중첩된(nested) 값 + +YAML 은 유연한 형식으로, 값은 깊게 중첩되거나 평면화 될 수 있다. + +중첩된 경우: + +```yaml +server: + name: nginx + port: 80 +``` + +평면화된 경우: + +```yaml +serverName: nginx +serverPort: 80 +``` + +대부분의 경우, 중첩된 경우보다는 평면화된 경우를 선호하게 된다. 그 이유는 템플릿 개발자와 +사용자에게 더 간단하기 때문이다. + + +최적의 안전성을 위해, 모든 수준에서 중첩된 값을 확인해야 한다. + +``` +{{ if .Values.server }} + {{ default "none" .Values.server.name }} +{{ end }} +``` + +모든 중첩된 계층에 대하여 존재 유무를 점검해야 한다. 다만 평면화된 +구성의 경우, 이러한 검사를 건너뛸 수 있으므로 템플릿을 더 쉽게 읽고 +사용할 수 있다. + +``` +{{ default "none" .Values.serverName }} +``` + +관련 변수가 많고 그 중 하나 이상이 선택 사항이 아닌 경우, 중첩된 값을 +사용하여 가독성을 높일 수 있다. + +## 자료형을 명확히 하자 + +YAML 의 유형에 대한 강제적인 규칙은 때때로 직관적이지 못하다. 예를 들어 +`foo: false` 는 `foo: "false"` 와 동일하지 않다. `foo: 12345678` 과 같은 +큰 정수는 경우에 따라 수학적 표기법으로 변환된다. + +유형 변환 오류를 피하는 가장 쉬운 방법은 문자열에 대해서만 명시하고 이 외에는 명시하지 않는 것이다. +혹은 더 간단하게, _모두 인용부호로 감싸서 문자열로 만드는 것이다_. + +종종 정수형의 캐스팅 문제를 방지하기위해, 정수도 문자열로 저장하고 템플릿에서 +`{{ int $value }}` 를 사용하여 문자열에서 다시 정수로 변환하는 것이 +유리하다. + +대부분의 경우 명시적 유형 태그가 존중되므로 `foo: !!string 1234` 는 +`1234` 를 문자열로 처리해야 한다. _그러나_ YAML 파서는 태그를 사용하므로 한번의 구문 분석 후에는 +유형 데이터가 손실된다. + +## 사용자가 값을 어떻게 사용할지를 고려하자 + +값에는 다음과 같은 세 가지 출처가 있다. +There are three potential sources of values: + +- 차트의 `values.yaml` 파일 +- `helm install -f` 또는 `helm upgrade -f` 에서 제공하는 값 파일 +- `helm install` 또는 `helm upgrade` 의 `--set` 또는 `--set-string` 플래그에 + 전달된 값 + +값의 구조를 디자인 할 때 차트 사용자는 `-f` 플래그 또는 `--set` +옵션을 통해 값을 재정의 +할 수 있다. + +`--set` 은 표현력이 더 제한적이므로, `values.yaml` 파일을 작성하기 위한 +첫 번째 지침은, _`--set` 에서 쉽게 재정의 할 수 있도록 하는 것이다_. + +이러한 이유로 맵을 사용하여 값 파일을 구조화하는 것이 더 좋다. + +`--set` 과 함께 사용하기 어려운 경우 + +```yaml +servers: + - name: foo + port: 80 + - name: bar + port: 81 +``` + +위의 내용은 헬름 `<=2.4` 에서는 `--set` 으로 표현할 수 없다. 헬름 2.5 에서 +foo 의 포트에 액세스 하는 것은 `--set servers[0].port=80` 이다. +사용자가 파악하기 어려울 뿐만 아니라 나중에 `서버` 의 순서가 변경되면 +오류가 발생하기 쉽다. + +사용하기 쉬운 경우: + +```yaml +servers: + foo: + port: 80 + bar: + port: 81 +``` + +foo 의 포트에 접근하는 것이 훨씬 명확하다: `--set servers.foo.port=80`. + +## `values.yaml`을 문서화하자 + +`values.yaml` 에 정의된 모든 속성은 문서화 되어야 한다. 문서 +문자열은 설명하는 속성의 이름으로 시작하고 최소한 한 문장으로 된 +설명을 제공해야 한다. + +잘못된 경우: + +```yaml +# the host name for the webserver +serverHost: example +serverPort: 9191 +``` + +올바른 경우: + +```yaml +# serverHost is the host name for the webserver +serverHost: example +# serverPort is the HTTP listener port for the webserver +serverPort: 9191 +``` + +각 주석을 문서화하는 매개 변수의 이름으로 시작하면 +문서를 쉽게 정리할 수 있으며, 문서화 도구가 문서 문자열과 이를 설명하는 매개변수를 안정적으로 연관시킬 수 있게 해준다. diff --git a/content/ko/docs/chart_template_guide/_index.md b/content/ko/docs/chart_template_guide/_index.md new file mode 100644 index 0000000000..b4585d9d96 --- /dev/null +++ b/content/ko/docs/chart_template_guide/_index.md @@ -0,0 +1,20 @@ +--- +title: "차트 템플릿 가이드" +weight: 5 +--- + +# 차트 템플릿 개발자 가이드 + +본 가이드는 헬름 차트 템플릿을 소개하며, 템플릿 언어를 중점적으로 다룬다. + +템플릿은 쿠버네티스가 이해할 수 있는 YAML-형식 리소스 명세인 매니페스트 파일을 생성한다. +템플릿이 어떻게 구성되는지, 그것을 사용하는 방법, Go 템플릿을 작성하는 방법, 디버그 하는 방법을 살펴볼 것이다. + +이 가이드는 다음 개념들을 집중적으로 설명한다. + +- 헬름 템플릿 언어 +- 값(values) 사용 +- 템플릿 작성 기법 + +이 가이드는 헬름 템플릿 언어를 세밀하게 알아 보는 것을 지향점으로 한다. +다른 가이드에서는 소개 자료, 예시, 모범사례를 다룰 것이다. diff --git a/content/ko/docs/chart_template_guide/accessing_files.md b/content/ko/docs/chart_template_guide/accessing_files.md new file mode 100644 index 0000000000..796edf8407 --- /dev/null +++ b/content/ko/docs/chart_template_guide/accessing_files.md @@ -0,0 +1,242 @@ +--- +title: "템플릿 내부 파일 접근하기" +description: "템플릿 안에 있는 파일에 접근하는 방법" +weight: 10 +--- + +이전 항목에서 지명 템플릿을 만들고 액세스하는 몇 가지 방법을 살펴보았다. +이런 방법으로 다른 템플릿에서 필요한 템플릿을 쉽게 가져올 수 있다. +하지만 때로는 _템플릿이 아닌 파일_ 을 가져와서 +그 내용을 템플릿 렌더러(renderer)로 보내지 않고 직접 주입(inject)하려고 하는 경우가 +있을 수 있다. + +헬름은 `.Files` 객체를 통해 파일에 액세스할 수 있게 해준다. 템플릿 예제를 확인하기 전에 +어떻게 작동하는지 살펴보자. + +- 헬름 차트에 파일을 추가해도 된다. 추가된 파일들은 하나로 묶인다. + 다만, 쿠버네티스 객체 저장소에는 제한이 있어 + 차트는 1M 보다 작아야 한다. +- 어떤 파일은 `.Files` 객체를 통해 액세스할 수 없는데, + 주로 보안 상의 이유 때문이다. + - `templates/`에 있는 파일은 액세스할 수 없다. + - `.helmignore`를 사용하여 제외된 파일은 액세스할 수 없다. +- 차트는 UNIX 모드 정보를 보존해주지 않으므로 + `.Files` 객체에서 온 파일의 경우, 파일 수준의 권한(permission)은 + 파일의 가용성에 영향을 미치지 않는다. + + + + + +- [기본-예제](#기본-예제) +- [경로-헬퍼](#경로-헬퍼) +- [글롭glob-패턴](#글롭glob-패턴) +- [컨피그맵configmap과-시크릿secret-도구-함수](#컨피그맵configmap과-시크릿secret-도구-함수) +- [인코딩](#인코딩) +- [lines-메소드](#lines-메소드) + + + +## 기본 예제 + +With those caveats behind, let's write a template that reads three files into +our ConfigMap. To get started, we will add three files to the chart, putting all +three directly inside of the `mychart/` directory. + +`config1.toml`: + +```toml +message = Hello from config 1 +``` + +`config2.toml`: + +```toml +message = This is config 2 +``` + +`config3.toml`: + +```toml +message = Goodbye from config 3 +``` + +Each of these is a simple TOML file (think old-school Windows INI files). We +know the names of these files, so we can use a `range` function to loop through +them and inject their contents into our ConfigMap. + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + {{- $files := .Files }} + {{- range tuple "config1.toml" "config2.toml" "config3.toml" }} + {{ . }}: |- + {{ $files.Get . }} + {{- end }} +``` + +This config map uses several of the techniques discussed in previous sections. +For example, we create a `$files` variable to hold a reference to the `.Files` +object. We also use the `tuple` function to create a list of files that we loop +through. Then we print each file name (`{{ . }}: |-`) followed by the contents +of the file `{{ $files.Get . }}`. + +Running this template will produce a single ConfigMap with the contents of all +three files: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: quieting-giraf-configmap +data: + config1.toml: |- + message = Hello from config 1 + + config2.toml: |- + message = This is config 2 + + config3.toml: |- + message = Goodbye from config 3 +``` + +## 경로 헬퍼 + +When working with files, it can be very useful to perform some standard +operations on the file paths themselves. To help with this, Helm imports many of +the functions from Go's [path](https://golang.org/pkg/path/) package for your +use. They are all accessible with the same names as in the Go package, but with +a lowercase first letter. For example, `Base` becomes `base`, etc. + +The imported functions are: +- Base +- Dir +- Ext +- IsAbs +- Clean + +## 글롭(glob) 패턴 + +As your chart grows, you may find you have a greater need to organize your files +more, and so we provide a `Files.Glob(pattern string)` method to assist in +extracting certain files with all the flexibility of [glob +patterns](https://godoc.org/github.com/gobwas/glob). + +`.Glob` returns a `Files` type, so you may call any of the `Files` methods on +the returned object. + +For example, imagine the directory structure: + +``` +foo/: + foo.txt foo.yaml + +bar/: + bar.go bar.conf baz.yaml +``` + +You have multiple options with Globs: + + +```yaml +{{ $currentScope := .}} +{{ range $path, $_ := .Files.Glob "**.yaml" }} + {{- with $currentScope}} + {{ .Files.Get $path }} + {{- end }} +{{ end }} +``` + +Or + +```yaml +{{ range $path, $_ := .Files.Glob "**.yaml" }} + {{ $.Files.Get $path }} +{{ end }} +``` + +## 컨피그맵(ConfigMap)과 시크릿(Secret) 도구 함수 + +(Helm 2.0.2부터 사용가능) + +It is very common to want to place file content into both ConfigMaps and +Secrets, for mounting into your pods at run time. To help with this, we provide +a couple utility methods on the `Files` type. + +For further organization, it is especially useful to use these methods in +conjunction with the `Glob` method. + +Given the directory structure from the [글롭glob-패턴](#글롭glob-패턴) example above: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: conf +data: +{{ (.Files.Glob "foo/*").AsConfig | indent 2 }} +--- +apiVersion: v1 +kind: Secret +metadata: + name: very-secret +type: Opaque +data: +{{ (.Files.Glob "bar/*").AsSecrets | indent 2 }} +``` + +## 인코딩 + +You can import a file and have the template base-64 encode it to ensure +successful transmission: + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Release.Name }}-secret +type: Opaque +data: + token: |- + {{ .Files.Get "config1.toml" | b64enc }} +``` + +The above will take the same `config1.toml` file we used before and encode it: + +```yaml +# Source: mychart/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + name: lucky-turkey-secret +type: Opaque +data: + token: |- + bWVzc2FnZSA9IEhlbGxvIGZyb20gY29uZmlnIDEK +``` + +## Lines 메소드 + +Sometimes it is desirable to access each line of a file in your template. We +provide a convenient `Lines` method for this. + +You can loop through `Lines` using a `range` function: + +```yaml +data: + some-file.txt: {{ range .Files.Lines "foo/bar.txt" }} + {{ . }}{{ end }} +``` + +There is no way to pass files external to the chart during `helm +install`. So if you are asking users to supply data, it must be loaded using +`helm install -f` or `helm install --set`. + +This discussion wraps up our dive into the tools and techniques for writing Helm +templates. In the next section we will see how you can use one special file, +`templates/NOTES.txt`, to send post-installation instructions to the users of +your chart. diff --git a/content/ko/docs/chart_template_guide/builtin_objects.md b/content/ko/docs/chart_template_guide/builtin_objects.md new file mode 100644 index 0000000000..2c107756d1 --- /dev/null +++ b/content/ko/docs/chart_template_guide/builtin_objects.md @@ -0,0 +1,76 @@ +--- +title: "빌트인 객체" +description: "템플릿에서 사용가능한 빌트인 객체" +weight: 3 +--- + +객체는 템플릿 엔진에서 템플릿으로 전달된다. 그리고 사용자의 코드는 +객체를 전달할 수 있다. (`with` 와 `range` 문을 볼 때 +예제로 확인할 수 있다.) 이후에 보게 될 `tuple` 함수와 같이 +템플릿 내에서 새로운 객체를 만드는 몇 가지 방법이 있다. + +객체는 간단히 하나의 값만 가질 수도 있다. 또는 다른 +객체나 기능을 포함할 수 있다. 예를 들어, `Release` 객체는 +(`Release.Name` 과 같은) 여러 객체를 포함하며 `Files` 객체는 몇 가지 함수를 가지고 있다. + +이전 섹션에서는 템플릿에 릴리즈 이름을 삽입하기 위해 +`{{.Release.Name}}` 을 사용하였다. `Release` 는 내 템플릿에 +접근할 수 있는 최상위 객체 중 하나이다. + +- `Release`: 이 객체는 릴리스 자체를 서술한다. 여러 객체를 가지고 있다. + 그 내부: + - `Release.Name`: 릴리스 이름 + - `Release.Namespace`: 릴리스될 네임스페이스 (manifest에서 + 오버라이드하지 않은 경우) + - `Release.IsUpgrade`: 현재 작업이 업그레이드 또는 롤백인 + 경우 `true` 로 설정된다. + - `Release.IsInstall`: 현재 작업이 설치일 + 경우 `true` 로 설정. + - `Release.Revision`: 이 릴리스의 리비전 번호. 설치시에는 이 값이 + 1이며 업그레이드나 롤백을 수행할 때마다 증가한다. + - `Release.Service`: 현재 템플릿을 렌더링하는 서비스. Helm 에서는 + 항상 `Helm` 이다. +- `Values`: `values.yaml` 파일 및 사용자 제공 파일에서 템플릿으로 + 전달된 값. 기본적으로 `Values` 는 비어 있다. +- `Chart`: `Chart.yaml` 파일의 내용. `Chart.yaml` 안의 모든 데이터는 여기서 + 접근 가능하다. 예를 들어 `{{ .Chart.Name }}-{{ .Chart.Version }}` 은 + `mychart-0.1.0` 를 출력한다. + - 사용가능한 필드는 [차트 가이드]({{< ref path="/docs/topics/charts.md#the-chartyaml-file" lang="ko" >}}) + 에 나열되어 있다. +- `Files`: 차트 내의 모든 특수하지 않은(non-special) 파일에 대한 접근을 제공한다. + 템플릿에 접근하는 데에는 사용할 수 없지만, 차트 내의 다른 파일에 접근하는 데에는 사용할 수 있다. + 자세한 내용은 _Accessing Files_ 섹션을 참고하자. + - `Files.Get` 은 이름으로 파일을 가지고 오는 함수이다. (`.Files.Get + config.ini`) + - `Files.GetBytes` 는 파일의 내용을 문자열이 아닌 + 바이트 배열로 가져오는 함수이다. 이미지 같은 것을 + 다룰 때 유용하다. + - `Files.Glob` 는 이름이 주어진 shell glob 패턴과 + 매치되는 파일 목록을 반환하는 함수이다. + - `Files.Lines` 는 파일을 한 줄씩 읽는 함수이다. 이것은 + 파일 내의 각 행을 순회(iterate)하는데 유용하다. + - `Files.AsSecrets` 은 파일 본문을 Base64로 인코딩된 문자열로 반환하는 + 함수이다. + - `Files.AsConfig` 는 파일 본문을 YAML 맵으로 반환하는 함수이다. +- `Capabilities`: 쿠버네티스 클러스터가 지원하는 기능에 대한 + 정보를 제공한다. + - `Capabilities.APIVersions` 는 버전의 집합이다. + - `Capabilities.APIVersions.Has $version` 은 버전(예: + `batch/v1`) 이나 리소스(예: `apps/v1/Deployment`) 를 클러스터에서 사용할 수 있는지 + 여부를 나타낸다. + - `Capabilities.KubeVersion` 과 `Capabilities.KubeVersion.Version` 는 쿠버네티스 버전이다. + - `Capabilities.KubeVersion.Major` 는 쿠버네티스 메이저 버전이다. + - `Capabilities.KubeVersion.Minor` 는 쿠버네티스 마이너 버전이다. +- `Template`: 실행 중인 현재 템플릿에 대한 정보를 + 포함한다. + - `Name`: 현재 템플릿에 대한 네임스페이스 파일 경로 (예: + `mychart/templates/mytemplate.yaml`) + - `BasePath`: 현재 차트의 템플릿 디렉토리에 대한 네임스페이스 경로 + (예: `mychart/templates`). + +빌트인 값은 항상 대문자로 시작한다. 이것은 Go의 명명 규칙을 +따르고 있다. 사용자는 자신만의 이름의 만들때, 팀에 적합한 +규칙을 자유롭게 사용할 수 있다. [쿠버네티스 차트](https://github.com/helm/charts) +팀과 같은 일부 팀에서는 로컬 이름과 빌트인 이름을 구분하기 위해 +첫 글자로 소문자만 사용하도록 선택한다. 이 가이드에서는 +해당 규칙을 따른다. diff --git a/content/ko/docs/chart_template_guide/control_structures.md b/content/ko/docs/chart_template_guide/control_structures.md new file mode 100644 index 0000000000..f305eb1fac --- /dev/null +++ b/content/ko/docs/chart_template_guide/control_structures.md @@ -0,0 +1,425 @@ +--- +title: "흐름(flow) 제어" +description: "템플릿 내부의 흐름 구조에 대한 간단한 개요" +weight: 6 +--- + +Control structures (called "actions" in template parlance) provide you, the +template author, with the ability to control the flow of a template's +generation. Helm's template language provides the following control structures: + +- `if`/`else` - 조건부 블록 생성 +- `with` - 스코프 지정 +- `range` - "for each" 스타일 반복문 제공 + +In addition to these, it provides a few actions for declaring and using named +template segments: + +- `define` declares a new named template inside of your template +- `template` imports a named template +- `block` declares a special kind of fillable template area + +In this section, we'll talk about `if`, `with`, and `range`. The others are +covered in the "Named Templates" section later in this guide. + +## If/Else + +The first control structure we'll look at is for conditionally including blocks +of text in a template. This is the `if`/`else` block. + +The basic structure for a conditional looks like this: + +``` +{{ if PIPELINE }} + # Do something +{{ else if OTHER PIPELINE }} + # Do something else +{{ else }} + # Default case +{{ end }} +``` + +Notice that we're now talking about _pipelines_ instead of values. The reason +for this is to make it clear that control structures can execute an entire +pipeline, not just evaluate a value. + +A pipeline is evaluated as _false_ if the value is: + +- a boolean false +- a numeric zero +- an empty string +- a `nil` (empty or null) +- an empty collection (`map`, `slice`, `tuple`, `dict`, `array`) + +Under all other conditions, the condition is true. + +Let's add a simple conditional to our ConfigMap. We'll add another setting if +the drink is set to coffee: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + drink: {{ .Values.favorite.drink | default "tea" | quote }} + food: {{ .Values.favorite.food | upper | quote }} + {{ if eq .Values.favorite.drink "coffee" }}mug: true{{ end }} +``` + +Since we commented out `drink: coffee` in our last example, the output should +not include a `mug: true` flag. But if we add that line back into our +`values.yaml` file, the output should look like this: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: eyewitness-elk-configmap +data: + myvalue: "Hello World" + drink: "coffee" + food: "PIZZA" + mug: true +``` + +## 화이트스페이스 제어 + +While we're looking at conditionals, we should take a quick look at the way +whitespace is controlled in templates. Let's take the previous example and +format it to be a little easier to read: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + drink: {{ .Values.favorite.drink | default "tea" | quote }} + food: {{ .Values.favorite.food | upper | quote }} + {{ if eq .Values.favorite.drink "coffee" }} + mug: true + {{ end }} +``` + +Initially, this looks good. But if we run it through the template engine, we'll +get an unfortunate result: + +```console +$ helm install --dry-run --debug ./mychart +SERVER: "localhost:44134" +CHART PATH: /Users/mattbutcher/Code/Go/src/helm.sh/helm/_scratch/mychart +Error: YAML parse error on mychart/templates/configmap.yaml: error converting YAML to JSON: yaml: line 9: did not find expected key +``` + +What happened? We generated incorrect YAML because of the whitespacing above. + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: eyewitness-elk-configmap +data: + myvalue: "Hello World" + drink: "coffee" + food: "PIZZA" + mug: true +``` + +`mug` is incorrectly indented. Let's simply out-dent that one line, and re-run: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + drink: {{ .Values.favorite.drink | default "tea" | quote }} + food: {{ .Values.favorite.food | upper | quote }} + {{ if eq .Values.favorite.drink "coffee" }} + mug: true + {{ end }} +``` + +When we sent that, we'll get YAML that is valid, but still looks a little funny: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: telling-chimp-configmap +data: + myvalue: "Hello World" + drink: "coffee" + food: "PIZZA" + + mug: true + +``` + +Notice that we received a few empty lines in our YAML. Why? When the template +engine runs, it _removes_ the contents inside of `{{` end `}}`, but it leaves +the remaining whitespace exactly as is. + +YAML ascribes meaning to whitespace, so managing the whitespace becomes pretty +important. Fortunately, Helm templates have a few tools to help. + +First, the curly brace syntax of template declarations can be modified with +special characters to tell the template engine to chomp whitespace. `{{- ` (with +the dash and space added) indicates that whitespace should be chomped left, +while ` -}}` means whitespace to the right should be consumed. _Be careful! +Newlines are whitespace!_ + +> Make sure there is a space between the `-` and the rest of your directive. +> `{{- 3 }}` means "trim left whitespace and print 3" while `{{-3 }}` means +> "print -3". + +Using this syntax, we can modify our template to get rid of those new lines: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + drink: {{ .Values.favorite.drink | default "tea" | quote }} + food: {{ .Values.favorite.food | upper | quote }} + {{- if eq .Values.favorite.drink "coffee" }} + mug: true + {{- end }} +``` + +Just for the sake of making this point clear, let's adjust the above, and +substitute an `*` for each whitespace that will be deleted following this rule. +an `*` at the end of the line indicates a newline character that would be +removed + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + drink: {{ .Values.favorite.drink | default "tea" | quote }} + food: {{ .Values.favorite.food | upper | quote }}* +**{{- if eq .Values.favorite.drink "coffee" }} + mug: true* +**{{- end }} + +``` + +Keeping that in mind, we can run our template through Helm and see the result: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: clunky-cat-configmap +data: + myvalue: "Hello World" + drink: "coffee" + food: "PIZZA" + mug: true +``` + +Be careful with the chomping modifiers. It is easy to accidentally do things +like this: + +```yaml + food: {{ .Values.favorite.food | upper | quote }} + {{- if eq .Values.favorite.drink "coffee" -}} + mug: true + {{- end -}} + +``` + +That will produce `food: "PIZZA"mug:true` because it consumed newlines on both +sides. + +> For the details on whitespace control in templates, see the [Official Go +> template documentation](https://godoc.org/text/template) + +Finally, sometimes it's easier to tell the template system how to indent for you +instead of trying to master the spacing of template directives. For that reason, +you may sometimes find it useful to use the `indent` function (`{{ indent 2 +"mug:true" }}`). + +## `with`를 사용하여 스코프 조정 + +The next control structure to look at is the `with` action. This controls +variable scoping. Recall that `.` is a reference to _the current scope_. So +`.Values` tells the template to find the `Values` object in the current scope. + +The syntax for `with` is similar to a simple `if` statement: + +``` +{{ with PIPELINE }} + # restricted scope +{{ end }} +``` + +Scopes can be changed. `with` can allow you to set the current scope (`.`) to a +particular object. For example, we've been working with `.Values.favorites`. +Let's rewrite our ConfigMap to alter the `.` scope to point to +`.Values.favorites`: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + {{- with .Values.favorite }} + drink: {{ .drink | default "tea" | quote }} + food: {{ .food | upper | quote }} + {{- end }} +``` + +(Note that we removed the `if` conditional from the previous exercise) + +Notice that now we can reference `.drink` and `.food` without qualifying them. +That is because the `with` statement sets `.` to point to `.Values.favorite`. +The `.` is reset to its previous scope after `{{ end }}`. + +But here's a note of caution! Inside of the restricted scope, you will not be +able to access the other objects from the parent scope. This, for example, will +fail: + +```yaml + {{- with .Values.favorite }} + drink: {{ .drink | default "tea" | quote }} + food: {{ .food | upper | quote }} + release: {{ .Release.Name }} + {{- end }} +``` + +It will produce an error because `Release.Name` is not inside of the restricted +scope for `.`. However, if we swap the last two lines, all will work as expected +because the scope is reset after `{{ end }}`. + +```yaml + {{- with .Values.favorite }} + drink: {{ .drink | default "tea" | quote }} + food: {{ .food | upper | quote }} + {{- end }} + release: {{ .Release.Name }} +``` + +After looking at `range`, we will take a look at template variables, which offer +one solution to the scoping issue above. + +## `range` 액션으로 반복수행(looping) + +Many programming languages have support for looping using `for` loops, `foreach` +loops, or similar functional mechanisms. In Helm's template language, the way to +iterate through a collection is to use the `range` operator. + +To start, let's add a list of pizza toppings to our `values.yaml` file: + +```yaml +favorite: + drink: coffee + food: pizza +pizzaToppings: + - mushrooms + - cheese + - peppers + - onions +``` + +Now we have a list (called a `slice` in templates) of `pizzaToppings`. We can +modify our template to print this list into our ConfigMap: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + {{- with .Values.favorite }} + drink: {{ .drink | default "tea" | quote }} + food: {{ .food | upper | quote }} + {{- end }} + toppings: |- + {{- range .Values.pizzaToppings }} + - {{ . | title | quote }} + {{- end }} + +``` + +Let's take a closer look at the `toppings:` list. The `range` function will +"range over" (iterate through) the `pizzaToppings` list. But now something +interesting happens. Just like `with` sets the scope of `.`, so does a `range` +operator. Each time through the loop, `.` is set to the current pizza topping. +That is, the first time, `.` is set to `mushrooms`. The second iteration it is +set to `cheese`, and so on. + +We can send the value of `.` directly down a pipeline, so when we do `{{ . | +title | quote }}`, it sends `.` to `title` (title case function) and then to +`quote`. If we run this template, the output will be: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: edgy-dragonfly-configmap +data: + myvalue: "Hello World" + drink: "coffee" + food: "PIZZA" + toppings: |- + - "Mushrooms" + - "Cheese" + - "Peppers" + - "Onions" +``` + +Now, in this example we've done something tricky. The `toppings: |-` line is +declaring a multi-line string. So our list of toppings is actually not a YAML +list. It's a big string. Why would we do this? Because the data in ConfigMaps +`data` is composed of key/value pairs, where both the key and the value are +simple strings. To understand why this is the case, take a look at the +[Kubernetes ConfigMap docs](https://kubernetes.io/docs/user-guide/configmap/). +For us, though, this detail doesn't matter much. + +> The `|-` marker in YAML takes a multi-line string. This can be a useful +> technique for embedding big blocks of data inside of your manifests, as +> exemplified here. + +Sometimes it's useful to be able to quickly make a list inside of your template, +and then iterate over that list. Helm templates have a function to make this +easy: `tuple`. In computer science, a tuple is a list-like collection of fixed +size, but with arbitrary data types. This roughly conveys the way a `tuple` is +used. + +```yaml + sizes: |- + {{- range tuple "small" "medium" "large" }} + - {{ . }} + {{- end }} +``` + +The above will produce this: + +```yaml + sizes: |- + - small + - medium + - large +``` + +In addition to lists and tuples, `range` can be used to iterate over collections +that have a key and a value (like a `map` or `dict`). We'll see how to do that +in the next section when we introduce template variables. diff --git a/content/ko/docs/chart_template_guide/data_types.md b/content/ko/docs/chart_template_guide/data_types.md new file mode 100644 index 0000000000..2de53ce67c --- /dev/null +++ b/content/ko/docs/chart_template_guide/data_types.md @@ -0,0 +1,22 @@ +--- +title: "부록: Go 자료형과 템플릿" +description: "템플릿에서의 변수에 관한 간단한 개괄" +weight: 16 +--- + +헬름 템플릿 언어는 강한 타이핑(strongly typed)인 Go 프로그래밍 언어로 구현된다. +이러한 이유로, 템플릿에서의 변수는 _타이핑(typed)_된다. +대부분의 경우, 변수는 다음 자료형 중 하나로 노출된다. + +- string: 텍스트 문자열 +- bool: `true` 또는 `false` +- int: 정수 값 (8, 16, 32, 64 비트의 부호가 있거나(signed) 없는(unsinged) 다양한 자료형이 있다) +- float64: 64비트 부동 소수점 값 (8, 16, 32 비트의 다양한 자료형이 있다) +- byte slice(`[]byte`), 흔히 (잠재적으로) 바이너리 데이터를 담기 위해 사용된다. +- struct(구조체): 프로퍼티와 메소드를 가지는 객체 +- 위의 자료형 중 하나에 대한 슬라이스(인덱스 있는 리스트) +- 위의 자료형 중 하나에 대한 문자열-키 맵(`map[string]interface{}`) + +Go에는 다른 여러가지 자료형이 있는데, 템플릿에서는 때에 따라 자료형을 변환해야 할 수도 있다. +객체 자료형을 디버그하는 가장 쉬운 방법은 템플릿 내에서 자료형을 출력하는 `printf "%t"`에 전달하는 것이다. +또한 `typeOf`과 `kindOf` 함수도 살펴보자. diff --git a/content/ko/docs/chart_template_guide/debugging.md b/content/ko/docs/chart_template_guide/debugging.md new file mode 100644 index 0000000000..f660d53a10 --- /dev/null +++ b/content/ko/docs/chart_template_guide/debugging.md @@ -0,0 +1,40 @@ +--- +title: "템플릿 디버깅" +description: "배포에 실패한 차트의 트러블슈팅" +weight: 13 +--- + +렌더링된 템플릿이 쿠버네티스 API 서버로 전송될 때 문서 형식 +이외의 이유로 YAML 파일들이 거부될 수 있기 때문에, +템플릿 디버깅은 다소 까다로울 수 있다. + +디버깅에 도움이 되는 몇 가지 명령어들이 있다. + +- `helm lint` 는 내 차트가 모범 사례에 맞는지 검증하는 믿을만한 + 도구이다. +- `helm install --dry-run --debug` 혹은 `helm template --debug`: 앞에서 설명한 적이 있는 + 방법이다. 서버가 템플릿을 렌더링한 결과물을 매니페스트 파일로 돌려받아 볼 수 있는 + 매우 유용한 방법이다. +- `helm get manifest`: 서버에 어떤 템플릿들이 설치되어 있는지 알아 볼 수 있는 유용한 + 방법이다. + +내 YAML이 파싱에 실패했지만, 무엇이 생성되는지를 확인해보고 싶을 때, +템플릿에서 문제가 되는 섹션을 주석처리하고 `helm install --dry-run --debug` 를 다시 실행해보면 +YAML 을 쉽게 확인해 볼 수 있다. + +```yaml +apiVersion: v2 +# some: problem section +# {{ .Values.foo | quote }} +``` + +윗쪽 내용은 렌더링되고 주석은 그대로 반환된다. + +```yaml +apiVersion: v2 +# some: problem section +# "bar" +``` + +이렇게 하면 YAML 파싱 오류로 인한 차단 없이 생성되는 내용을 빠르게 +확인해 볼 수 있다. diff --git a/content/ko/docs/chart_template_guide/function_list.md b/content/ko/docs/chart_template_guide/function_list.md new file mode 100644 index 0000000000..729b877e78 --- /dev/null +++ b/content/ko/docs/chart_template_guide/function_list.md @@ -0,0 +1,2070 @@ +--- +title: "템플릿 함수 목록" +description: "헬름에서 사용가능한 템플릿 함수에 대한 목록" +weight: 6 +--- + +헬름에는 템플릿에서 활용할 수 있는 많은 템플릿 함수들이 포함되어 있다. +여기에 나열되며 다음 범주로 분류된다. + +* [암호화 및 보안](#암호화-및-보안-함수) +* [날짜](#날짜-함수) +* [사전](#사전-및-사전-함수) +* [인코딩](#인코딩-함수) +* [파일 경로](#파일-경로-함수) +* [쿠버네티스 및 차트](#쿠버네티스-및-차트-함수) +* [논리 및 흐름 제어](#논리-및-흐름-제어-함수) +* [목록](#목록-및-목록-함수) +* [수학](#수학-함수) +* [네트워크](#네트워크-함수) +* [리플렉션](#리플렉션-함수) +* [정규 표현식](#정규-표현식) +* [유의적 버전](#유의적-버전-함수) +* [문자열](#문자열-함수) +* [형 변환](#형-변환-함수) +* [URL](#url-함수) +* [UUID](#uuid-함수) + +## 논리 및 흐름 제어 함수 + +헬름은 +[and](#and), [coalesce](#coalesce), [default](#default), [empty](#empty), [eq](#eq), [fail](#fail), +[ge](#ge), [gt](#gt), [le](#le), [lt](#lt), [ne](#ne), [not](#not), [or](#or) 를 +포함한 수많은 논리 및 흐름 제어 기능이 포함되어 있다. + +### and + +두 인수의 불리언 and를 반환한다. + +``` +and .Arg1 .Arg2 +``` + +### or + +두 인수의 불리언 or를 반환한다. +비어 있지 않은 첫 번째 인수 또는 마지막 인수를 반환한다. + +``` +or .Arg1 .Arg2 +``` + +### not + +인수의 불리언 부정을 반환한다. + +``` +not .Arg +``` + +### eq + +인수들이 같은지 여부를 불리언으로 반환한다. (예: Arg1 == Arg2) + +``` +eq .Arg1 .Arg2 +``` + +### ne + +인수들이 같지 않은지 여부를 불리언으로 반환한다. (예: Arg1 != Arg2) + +``` +ne .Arg1 .Arg2 +``` + +### lt + +첫 번째 인수가 두 번째 인수보다 작으면 불리언 true를 반환한다. +그렇지 않으면 False가 반환된다 (예 : Arg1 < Arg2). + +``` +lt .Arg1 .Arg2 +``` + +### le + +첫 번째 인수가 두 번째 인수보다 작거나 같은 경우 불리언 true를 반환한다. +그렇지 않으면 False가 반환된다 (예 : Arg1 <= Arg2). + +``` +le .Arg1 .Arg2 +``` + +### gt + +첫 번째 인수가 두 번째 인수보다 크면 불리언 true를 반환한다. +그렇지 않으면 False가 반환된다 (예 : Arg1 > Arg2). + +``` +gt .Arg1 .Arg2 +``` + +### ge + +첫 번째 인수가 두 번째 인수보다 크거나 같은 경우 불리언 true를 반환한다. +그렇지 않으면 False가 반환된다 (예 : Arg1 >= Arg2). + +``` +ge .Arg1 .Arg2 +``` + +### default + +간단한 기본값을 설정하려면 `default`를 사용한다. + +``` +default "foo" .Bar +``` + +위에서 `.Bar` 가 비어 있지 않은 값으로 평가되면 사용된다. +하지만 비어 있으면 `foo` 가 대신 반환된다. + +"비어 있음"의 정의는 다음의 유형을 따른다. + +- 숫자: 0 +- 문자열: "" +- 리스트형: `[]` +- 딕셔너리형: `{}` +- 불리언: `false` +- `nil` 의 경우 항상 (null 이라고도 함) + +구조체의 경우 비어 있다는 정의가 없으므로, 구조체는 +기본값을 반환하지 않는다. + +### empty + +`empty` 함수는 주어진 값이 비어 있다고 간주되면 `true` 를 반환하고 +그렇지 않으면 `false` 를 반환한다. 빈 값은 `default` 섹션에 나열된다. + +``` +empty .Foo +``` + +Go 템플릿 조건부에서는 비어 있음이 자동으로 계산된다. +따라서 `if not empty .Foo` 는 거의 필요하지 않다. 대신 `if .Foo` 를 사용하도록 하자. + +### fail + +지정된 텍스트와 함께 빈 `문자열` 과 `오류` 를 무조건 반환한다. +이는 다른 조건에서 템플릿 렌더링이 실패해야 한다고 +결정한 시나리오에서 유용하다. + +``` +fail "Please accept the end user license agreement" +``` + +### coalesce + +`coalesce` 함수는 값 목록을 가져와 비어 있지 않은 +첫 번째 값을 반환한다. + +``` +coalesce 0 1 2 +``` + +위의 경우 `1` 을 반환한다. + +이 함수는 여러 변수 또는 값을 스캔하는데 유용하다. + +``` +coalesce .name .parent.name "Matt" +``` + +위 코드는 먼저 `.name` 이 비어 있는지 확인한다. +그렇지 않은 경우 해당 값을 반환한다. +비어있는 경우 `coalesce` 는 `.parent.name` 이 비어 있는지 평가한다. +마지막으로 `.name` 과 `.parent.name` 이 모두 비어 있으면 `Matt` 를 반환한다. + +### ternary + +`삼항(ternary)` 함수는 두 개의 값과 테스트 값을 취한다. +테스트 값이 참이면 첫 번째 값이 반환된다. +테스트 값이 비어 있으면 두 번째 값이 반환된다. 이것은 C 언어의 삼항 연산자와 유사하다. + +#### true 테스트 값 + +``` +ternary "foo" "bar" true +``` + +또는 + +``` +true | ternary "foo" "bar" +``` + +위의 결과는 `"foo"` 를 반환한다. + +#### false 테스트 값 + +``` +ternary "foo" "bar" false +``` + +또는 + +``` +false | ternary "foo" "bar" +``` + +위의 결과는 `"bar"` 를 반환한다. + +## 문자열 함수 + +헬름은 다음과 같은 문자열 함수들을 포함한다. +[abbrev](#abbrev),[abbrevboth](#abbrevboth), [camelcase](#camelcase), [cat](#cat), +[contains](#contains), [hasPrefix](#hasprefix-및-hassuffix), +[hasSuffix](#hasprefix-및-hassuffix), [indent](#indent), [initials](#initials), +[kebabcase](#kebabcase), [lower](#lower), [nindent](#nindent), +[nospace](#nospace), [plural](#plural), [print](#print), [printf](#printf), +[println](#println), [quote](#quote-및-squote), +[randAlpha](#randalphanum-randalpha-randnumeric-randascii), +[randAlphaNum](#randalphanum-randalpha-randnumeric-randascii), +[randAscii](#randalphanum-randalpha-randnumeric-randascii), +[randNumeric](#randalphanum-randalpha-randnumeric-randascii), +[repeat](#repeat), [replace](#replace), [shuffle](#shuffle), +[snakecase](#snakecase), [squote](#quote-및-squote), [substr](#substr), +[swapcase](#swapcase), [title](#title), [trim](#trim), [trimAll](#trimall), +[trimPrefix](#trimprefix), [trimSuffix](#trimsuffix), [trunc](#trunc), +[untitle](#untitle), [upper](#upper), [wrap](#wrap), [wrapWith](#wrapwith). + +### print + +일부의 조합에서 문자열을 반환한다. + +``` +print "Matt has " .Dogs " dogs" +``` + +문자열이 아닌 유형은 가능한 경우 문자열로 변환된다. + +서로 옆에 있는 두 인수가 문자열이 아닌 경우 그 사이에 +공백이 추가된다. + +### println + +[print](#print) 와 같은 방식으로 동작하지만, 끝에 새 줄을 추가한다. + +### printf + +형식화 문자열과 순서대로 전달할 인수를 기반으로 문자열을 +반환한다. + +``` +printf "%s has %d dogs." .Name .NumberDogs +``` + +사용할 자리 표시자는 전달되는 인수의 유형에 따라 다르다. +여기에는 다음이 포함된다. + +일반적인 목적: + +* `%v` 기본 형식의 값 + * 사전형 출력의 경우, 더하기 플래그(%+v) 는 필드 이름을 추가 +* `%%` 는 리터럴 퍼센트 기호로 값을 소비하지 않음 + +불리언: + +* `%t` 단어 true 또는 false + +정수: + +* `%b` 2진법 +* `%c` 해당 유니코드 포인트가 표현하는 문자 +* `%d` 10진법 +* `%o` 8진법 +* `%O` 접두사 0 이 있는 8진법 +* `%q` 홑따옴표로 묶인 문자는 안전하게 통과(escaped) +* `%x` a-f 의 소문자를 사용하는 16진법 +* `%X` A-F 의 대문자를 사용하는 16진법 +* `%U` 유니코드 형식: U+1234("U+%04X"와 동일) + +부동 소수점 및 복잡한 요소: + +* `%b` 지수가 2의 거듭제곱인, 십진수가 없는 과학적 표기법. 예를 들어, + -123456p-78 +* `%e` 과학적 표기법. 예: -1.234456e+78 +* `%E` 과학적 표기법. 예: -1.234456E+78 +* `%f` 지수가 없는 소수점. 예: 123.456 +* `%F` %f 와 동일 +* `%g` 지수가 클 경우 %e, 그렇지 않은 경우 %f. +* `%G` 지수가 클 경우 %E, 그렇지 않은 경우 %F. +* `%x` (두 지수의 10진수 거듭제곱 형태의) 16진수 표기법, 예를 들어, + -0x1.23abcp+20 +* `%X` 대문자 16진수 표기법. 예를 들어, -0X1.23ABCP+20 + +바이트의 문자열 또는 슬라이스(이러한 동사들과 동일하게 취급): + +* `%s` 문자열 또는 슬라이스의 해석되지 않은 바이트 +* `%q` 안전하게 이스케이프된 겹따옴표 문자열 +* `%x` 16진법, 소문자이며 바이트 당 2자 +* `%X` 16진법, 대문자이며 바이트 당 2자 + +슬라이스: + +* `%p` 0x로 시작하는, 16 진수 표기에서의 0번째 요소의 주소 + +### trim + +`trim` 함수는 문자열의 양쪽에서 공백을 제거한다. + +``` +trim " hello " +``` + +위 결과는 `hello` 이다. + +### trimAll + +문자열의 앞뒤에서 주어진 문자를 제거한다. + +``` +trimAll "$" "$5.00" +``` + +위 결과는 (문자열인) `5.00` 이다. + +### trimPrefix + +문자열에서 접두어만 제거한다. + +``` +trimPrefix "-" "-hello" +``` + +위 결과는 `hello` 를 반환한다. + +### trimSuffix + +문자열에서 접미어만 제거한다. + +``` +trimSuffix "-" "hello-" +``` + +위 결과는 `hello` 를 반환한다. + +### lower + +전체 문자열을 소문자로 변환한다. + +``` +lower "HELLO" +``` + +위 결과는 `hello` 를 반환한다. + +### upper + +전체 문자열을 대문자로 반환한다. + +``` +upper "hello" +``` + +위 결과는 `HELLO` 를 반환한다. + +### title + +제목의 형식으로 변환한다. + +``` +title "hello world" +``` + +위 결과는 `Hello World` 반환한다. + +### untitle + +제목의 형식을 제거한다. `untitle "Hello World"` 는 `hello world` 를 반환한다.. + +### repeat + +문자열을 여러 번 반복한다. + +``` +repeat 3 "hello" +``` + +위의 결과는 `hellohellohello` 를 반환한다. + +### substr + +문자열에서 부분문자열을 가져온다. 세가지 매개변수가 필요하다. + +- 시작 지점 (int) +- 끝 지점 (int) +- 원본 문자열 (string) + +``` +substr 0 5 "hello world" +``` + +위 결과는 `hello` 를 반환한다. + +### nospace + +문자열에서 모든 공백을 제거한다. + +``` +nospace "hello w o r l d" +``` + +위 결과는 `helloworld` 를 반환한다. + +### trunc + +문자열을 자른다. + +``` +trunc 5 "hello world" +``` + +위 결과는 `hello` 을 반환한다. + +``` +trunc -5 "hello world" +``` + +위 결과는 `world` 를 반환한다. + +### abbrev + +줄임표 (`...`) 로 문자열을 자른다. + +매개변수: + +- 최대 길이 +- 문자열 + +``` +abbrev 5 "hello world" +``` + +위 결과는 최대 길이에 대해 너비를 계산하므로, `he...` 를 +반환한다. + +### abbrevboth + +양쪽을 축약한다. + +``` +abbrevboth 5 10 "1234 5678 9123" +``` + +위 결과는 `...5678...` 를 반환한다. + +다음이 필요하다. + +- 왼쪽 오프셋 +- 최대 길이 +- 원본 문자열 + +### initials + +주어진 여러 단어에서, 각 단어의 첫 단어를 취하고 결합한다. + +``` +initials "First Try" +``` + +위 결과는 `FT` 를 반환한다. + +### randAlphaNum, randAlpha, randNumeric, randAscii + +이 네 가지 함수는 암호화적으로 안전한 (```crypto/rand``` 사용) 임의의 문자열을 생성하지만 +기본 문자 집합은 상이하다. + +- `randAlphaNum` 는 `0-9a-zA-Z` 를 사용한다 +- `randAlpha` 는 `a-zA-Z` 를 사용한다 +- `randNumeric` 는 `0-9` 를 사용한다 +- `randAscii` 는 출력가능한 모든 ASCII 문자를 사용한다 + +각각은 하나의 매개 변수, 즉 문자열의 정수 길이를 취한다. + +``` +randNumeric 3 +``` + +위 결과는 3자리 숫자로 된 임의의 문자열을 생성한다. + +### wrap + +주어진 열 개수로 텍스트를 래핑(wrap)한다. + +``` +wrap 80 $someText +``` + +위 결과는 80 번째 열에서 `$someText`의 문자열을 래핑한다. + +### wrapWith + +`wrapWith` 는 `wrap` 로 작동하지만, 래핑할 문자열을 지정할 수 있다. +(`wrap` 은 `\n` 을 사용) + +``` +wrapWith 5 "\t" "Hello World" +``` + +위는 `hello world` 를 생성한다. +(여기서 공백은 ASCII 탭 문자이다.) + +### contains + +한 문자열이 다른 문자열 안에 포함되어 있는지 테스트한다. + +``` +contains "cat" "catch" +``` + +위 결과는 `catch` 에 `cat` 이 포함되어 있으므로 `true` 를 반환한다. + +### hasPrefix 및 hasSuffix + +`hasPrefix` 및 `hasSuffix` 함수는 문자열에 주어진 접두어 또는 접미어가 있는지 +여부를 테스트한다. + +``` +hasPrefix "cat" "catch" +``` + +위 결과는 `catch` 에 접두사 `cat` 이 있으므로, `true` 를 반환한다. + +### quote 및 squote + +이 함수는 문자열을 겹따옴표("quote") 또는 홑따옴표(`quote`)로 +묶는다. + +### cat + +`cat` 함수는 여러 문자열을 하나로 결합하고 +공백으로 구분한다. + +``` +cat "hello" "beautiful" "world" +``` + +위 결과는 `hello beautiful world` 이다. + +### indent + +`indent` 함수는 주어진 문자열의 모든 줄을 지정된 들여쓰기 너비로 들여쓴다. +이것은 여러 줄 문자열을 정렬할 때 유용하다. + +``` +indent 4 $lots_of_text +``` + +위 결과는 모든 텍스트 줄을 4개의 공백 문자로 들여쓴다. + +### nindent + +`nindent` 함수는 indent 함수와 동일하지만 문자열 시작 부분에 +새 줄을 추가한다. + +``` +nindent 4 $lots_of_text +``` + +위 결과는 모든 텍스트 줄을 공백 문자 4개로 들여쓰기하고 시작 +부분에 새 줄을 추가한다. + +### replace + +간단한 문자열 교체를 수행한다. + +3가지 인수를 필요로 한다. + +- 대체할 문자열 +- 대체될 문자열 +- 원본 문자열 + +``` +"I Am Henry VIII" | replace " " "-" +``` + +위 결과는 `I-Am-Henry-VIII` 이다. + +### plural + +문자열을 복수(plural)화 한다. + +``` +len $fish | plural "one anchovy" "many anchovies" +``` + +위에서 문자열의 길이가 1이면 첫 번째 인수(`one anchovy`)가 출력된다. +그렇지 않으면 두 번째 인수(`many anchovies`)가 +출력된다. + +인수는 다음과 같다. + +- 단수 문자열 +- 복수 문자열 +- 길이 정수 + +참고: 헬름은 현재로서는 더 복잡한 복수화 규칙이 있는 언어를 지원하지 않는다. +그리고 `0` 은, 영어가 그렇게 취급하기 때문에, 복수형으로 +간주 된다. (`zero anchovies`) + +### snakecase + +camelCase에서 snake_case로 변환한다. + +``` +snakecase "FirstName" +``` + +위 결과는 `first_name` 이다. + +### camelcase + +snake_case에서 camelCase로 변환한다. + +``` +camelcase "http_server" +``` + +위 결과는 `HttpServer` 이다. + +### kebabcase + +camelCase에서 kebab-case로 변환한다. + +``` +kebabcase "FirstName" +``` + +위 결과는 `first-name` 이다. + +### swapcase + +단어 기반 알고리즘을 사용하여 문자열의 대소문자를 바꾼다. + +변환 알고리즘: + +- 대문자는 소문자로 변환한다 +- 제목 형식의 문자는 소문자로 변환한다 +- 공백 뒤 또는 시작시의 소문자는 제목 형식의 대소문자로 변환한다 +- 기타 소문자는 대문자로 변환한다 +- 화이트스페이스는 unicode.IsSpace(char)로 정의된다 + +``` +swapcase "This Is A.Test" +``` + +위 결과는 `tHIS iS a.tEST` 이다. + +### shuffle + +문자열을 섞는다. + +``` +shuffle "hello" +``` + +위 결과는 `hello` 의 문자를 무작위로 변경하여, `oelhl` 일 수도 있다. + +## 형 변환 함수 + +헬름에서 제공하는 형 변환 함수는 다음과 같다. + +- `atoi`: 문자열을 정수로 변환한다. +- `float64`: `float64` 로 변환한다. +- `int`: 시스템 기준의 `int` 로 변환한다. +- `int64`: `int64` 로 변환한다. +- `toDecimal`: 유닉스 8진수를 `int64` 로 변환한다. +- `toString`: 문자열로 변환한다. +- `toStrings`: 목록, 슬라이스 또는 배열을 문자열 목록으로 변환한다. +- `toJson` (`mustToJson`): 목록, 슬라이스, 배열, 사전형 또는 객체를 JSON 으로 변환한다. +- `toPrettyJson` (`mustToPrettyJson`): 목록, 슬라이스, 배열, 사전형 또는 객체를 들여쓰기 된 + JSON 으로 변환한다. +- `toRawJson` (`mustToRawJson`): 목록, 슬라이스, 배열, 사전형 또는 객체를 + HTML 문자가 이스케이프 되지 않은 JSON 으로 변환한다. + +`atoi` 함수는 입력이 특정 유형이어야 한다. +나머지는 모든 유형에서 대상 유형으로 변환을 시도한다. +예를 들어 `int64` 는 부동 소수점을 정수로 변환 할 수 있으며 문자열을 정수로 변환 할 수도 있다. + +### toStrings + +목록과 같은 컬렉션이 주어지면 문자열 슬라이스를 생성한다. + +``` +list 1 2 3 | toStrings +``` + +위는 결과는 `1` 을 `"1"` 로, `2` 를 `"2"` 로 변환한 다음 목록으로 +반환한다. + +### toDecimal + +주어진 유닉스 8진수 권한 값에 대하여, 10진수 값을 생성한다. + +``` +"0777" | toDecimal +``` + +위 코드는 `0777` 을 `511` 로 변환하고 값을 int64 형태로 변환한다. + +### toJson, mustToJson + +`toJson` 함수는 항목을 JSON 문자열로 인코딩한다. +항목을 JSON으로 변환 할 수 없는 경우 함수는 빈 문자열을 반환한다. +`mustToJson` 은 항목을 JSON으로 인코딩할 수 없는 경우 오류를 반환한다. + +``` +toJson .Item +``` + +위 결과는 `.Item` 의 JSON 문자열 표현을 반환한다. + +### toPrettyJson, mustToPrettyJson + +`toPrettyJson` 함수는 항목을 잘 정제된(들여쓰기) JSON 문자열로 +인코딩한다. + +``` +toPrettyJson .Item +``` + +위 결과는 `.Item` 의 들여쓰기된 JSON 문자열 표현을 반환한다. + +### toRawJson, mustToRawJson + +`toRawJson` 함수는 특정 항목을 HTML 문자가 이스케이프 되지 않은 JSON 문자열로 +인코딩한다. + +``` +toRawJson .Item +``` + +위는 `.Item` 의 이스케이프 처리되지 않은 JSON 문자열 표현을 반환합니다. + +## 정규 표현식 + +헬름에는 다음의 정규식 함수가 표현된다: [regexFind +(mustRegexFind)](#regexfindall-mustregexfindall), [regexFindAll +(mustRegexFindAll)](#regexfind-mustregexfind), [regexMatch +(mustRegexMatch)](#regexmatch-mustregexmatch), [regexReplaceAll +(mustRegexReplaceAll)](#regexreplaceall-mustregexreplaceall), +[regexReplaceAllLiteral +(mustRegexReplaceAllLiteral)](#regexreplaceallliteral-mustregexreplaceallliteral), +[regexSplit (mustRegexSplit)](#regexsplit-mustregexsplit). + +### regexMatch, mustRegexMatch + +입력 문자열에 정규식과 일치하는 항목이 있으면 true 를 반환한다. + +``` +regexMatch "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$" "test@acme.com" +``` + +위 결과는 `true` 이다. + +`regexMatch` 는 문제가 있는 경우 패닉이 발생하며, `mustRegexMatch` 는 문제가 있을 경우 +템플릿 엔진에 오류를 반환한다. + +### regexFindAll, mustRegexFindAll + +입력 문자열에서 정규식과 일치하는 모든 항목의 슬라이스를 반환한다. +마지막 매개 변수 n은 반환할 하위 문자열의 수를 결정한다. +여기서 -1은 모든 일치 항목을 반환함을 의미한다. + +``` +regexFindAll "[2,4,6,8]" "123456789" -1 +``` + +위 결과는 `[2 4 6 8]` 이다. + +`regexFindAll` 은 문제가 있으면 패닉이 발생하며 +`mustRegexFindAll` 은 문제가 있으면 템플릿 엔진에 오류를 반환한다. + +### regexFind, mustRegexFind + +입력 문자열에서 정규식의 첫 번째(가장 왼쪽) 일치 항목을 반환한다. + +``` +regexFind "[a-zA-Z][1-9]" "abcd1234" +``` + +위 결과는 `d1` 이다. + +`regexFind` 는 문제가 있으면 패닉이 발생하며 +`mustRegexFind` 는 문제가 있으면 템플릿 엔진에 오류를 반환한다. + +### regexReplaceAll, mustRegexReplaceAll + +입력 문자열의 복사본을 반환하여 정규 표현식의 일치 항목을 +교체 문자열로 바꾼다. 문자열 교체 내에서 $ 기호는 +확장된 차트에서와 같이 해석되므로, 예를 들어 +$1은 첫 번째 부분의 일치하는 텍스트를 나타낸다. + +``` +regexReplaceAll "a(x*)b" "-ab-axxb-" "${1}W" +``` + +위 결과는 `-W-xxW-` 이다. + +`regexReplaceAll` 은 문제가 있는 경우 패닉이 발생하며 +`mustRegexReplaceAll` 은 문제가 있는 경우 템플릿 엔진에 오류를 반환한다. + +### regexReplaceAllLiteral, mustRegexReplaceAllLiteral + +입력 문자열의 복사본을 반환하고 +정규 표현식의 일치 항목을 대체 문자열로 변경한다. +대체 문자열은 확장(Expand)를 사용하지 않고 직접 대체된다. + +``` +regexReplaceAllLiteral "a(x*)b" "-ab-axxb-" "${1}" +``` + +위 결과는 `-${1}-${1}-` 이다. + +`regexReplaceAllLiteral` 는 문제가 있으면 패닉이 발생하며, +`mustRegexReplaceAllLiteral` 는 문제가 있으면 템플릿 엔진에 오류를 +반환한다. + +### regexSplit, mustRegexSplit + +입력 문자열을 식으로 구분 된 하위 문자열로 분할하고 +해당 식 일치 사이의 하위 문자열 슬라이스를 반환한다. +마지막 매개 변수 `n` 은 반환 할 하위 문자열 수를 결정한다. +여기서 `-1` 은 모든 일치 항목을 반환 함을 의미한다. + +``` +regexSplit "z+" "pizza" -1 +``` + +위 결과는 `[pi a]` 이다. + +`regexSplit` 은 문제가 있는 경우 패닉이 발생하며 +`mustRegexSplit` 는 문제가 있는 경우 템플릿 엔진에 오류를 반환한다. + +## 암호화 및 보안 함수 + +헬름은 몇 가지 고급 암호화 함수를 제공한다. +[adler32sum](#adler32sum), [buildCustomCert](#buildcustomcert), +[decryptAES](#decryptaes), [derivePassword](#derivepassword), +[encryptAES](#encryptaes), [genCA](#genca), [genPrivateKey](#genprivatekey), +[genSelfSignedCert](#genselfsignedcert), [genSignedCert](#gensignedcert), +[htpasswd](#htpasswd), [sha1sum](#sha1sum), [sha256sum](#sha256sum). + +### sha1sum + +`sha1sum` 함수는 문자열을 수신하고 SHA1 다이제스트를 계산한다. + +``` +sha1sum "Hello world!" +``` + +### sha256sum + +`sha256sum` 함수는 문자열을 수신하고 SHA256 다이제스트 값을 계산한다. + +``` +sha256sum "Hello world!" +``` + +위 결과는 출력을 위해 안전한 "ASCII armored" 형식의 SHA256 합을 +계산한다. + +### adler32sum + +`adler32sum` 함수는 문자열을 수신하고 Adler-32 체크섬을 계산한다. + +``` +adler32sum "Hello world!" +``` + +### htpasswd + +`htpasswd` 함수는 `username` 과 `password` 를 +가져 와서 패스워드의 `bcrypt` 해시를 생성한다. +결과는 [아파치 HTTP 서버] (https://httpd.apache.org/docs/2.4/misc/password_encryptions.html#basic)에서 +기본 인증에 사용될 수 있다. + +``` +htpasswd "myUser" "myPassword" +``` + +템플릿에 직접 암호를 저장하는 것은 안전하지 않음을 유의하자. + +### derivePassword + +`derivePassword` 함수는 일부 공유되는 "마스터 패스워드" +제약 조건을 기반으로 특정 패스워드를 도출하는 데 사용할 수 있다. +이에 대한 알고리즘이 [잘 명세되어] (https://masterpassword.app/masterpassword-algorithm.pdf) 있다. + +``` +derivePassword 1 "long" "password" "user" "example.com" +``` + +일부를 템플릿에 직접 저장하는 것은 안전하지 않을 수 있다는 점에 유의하자. + +### genPrivateKey + +`genPrivateKey` 함수는 PEM 블록으로 인코딩된 새 개인키를 +생성한다. + +첫 번째 매개변수의 값 중 하나를 사용한다. + +- `ecdsa`: 타원 곡선 DSA 키 생성 (P256) +- `dsa`: DSA 키 생성 (L2048N256) +- `rsa`: RSA 4096 키 생성 + +### buildCustomCert + +`buildCustomCert` 함수를 사용하면 커스텀 인증서 설정이 가능하다. + +다음의 문자열 매개변수를 사용한다. + +- base64 인코딩된 PEM 형식의 인증서 +- base64 인코딩된 PEM 형식의 개인키 + +다음 속성을 가진 인증서 객체를 반환한다. + +- `Cert`: PEM 인코딩 인증서 +- `Key`: PEM 인코딩된 개인 키 + +예: + +``` +$ca := buildCustomCert "base64-encoded-ca-crt" "base64-encoded-ca-key" +``` + +반환된 객체는 `genSignedCert` 함수에 전달되어 이 CA를 사용하여 +인증서에 서명할 수 있다. + +### genCA + +`genCA` 함수는 자체 서명된 새로운 x509 인증기관을 생성한다. + +다음의 매개 변수를 사용한다. + +- 주체의 일반 이름 (common name. cn) +- 인증서의 유효 기간 (일) + +다음 속성을 가진 객체를 반환한다. + +- `Cert`: PEM 인코딩 인증서 +- `Key`: PEM 인코딩된 개인키 + +예: + +``` +$ca := genCA "foo-ca" 365 +``` + +반환 된 객체는 `genSignedCert` 함수에 전달되어 이 CA를 사용하여 +인증서에 서명 할 수 있습니다. + +### genSelfSignedCert + +`genSelfSignedCert` 함수는 자체 서명 된 새로운 x509 인증서를 생성한다. + +다음의 매개 변수를 사용한다. + +- 주체의 일반 이름 (cn) +- 선택적인 IP 목록으로 nil도 가능 +- 선택적인 대체 DNS 이름으로 nil 도 가능 +- 인증서 유효 기간 (일) + +다음 속성을 가진 객체를 반환한다. + +- `Cert`: PEM 인코딩 인증서 +- `Key`: PEM 인코딩된 개인키 + +예: + +``` +$cert := genSelfSignedCert "foo.com" (list "10.0.0.1" "10.0.0.2") (list "bar.com" "bat.com") 365 +``` + +### genSignedCert + +`genSignedCert` 함수는 지정된 CA에서 서명 한 새로운 x509 인증서를 +생성한다. + +다음의 매개 변수를 사용한다. + +- 주체의 일반 이름 (cn) +- 선택적인 IP 목록으로 nil도 가능 +- 선택적인 대체 DNS 이름으로 nil 도 가능 +- 인증서 유효 기간 (일) +- CA (`genCA` 를 참조) + +예: + +``` +$ca := genCA "foo-ca" 365 +$cert := genSignedCert "foo.com" (list "10.0.0.1" "10.0.0.2") (list "bar.com" "bat.com") 365 $ca +``` + +### encryptAES + +`encryptAES` 함수는 AES-256 CBC로 텍스트를 암호화하고 base64 인코딩된 문자열을 +반환한다. + +``` +encryptAES "secretkey" "plaintext" +``` + +### decryptAES + +`decryptAES` 함수는 AES-256 CBC 알고리즘으로 인코딩된 base64 문자열을 수신하고 디코딩된 +텍스트를 반환한다. + +``` +"30tEfhuJSVRhpG97XCuWgz2okj7L8vQ1s6V9zVUPeDQ=" | decryptAES "secretkey" +``` + +## 날짜 함수 + +헬름에는 템플릿에서 사용할 수 있는 다음의 날짜 함수들이 포함되어 있다. +[ago](#ago), [date](#date), [dateInZone](#dateinzone), [dateModify +(mustDateModify)](#datemodify-mustdatemodify), [duration](#duration), +[durationRound](#durationround), [htmlDate](#htmldate), +[htmlDateInZone](#htmldateinzone), [now](#now), [toDate +(mustToDate)](#todate-musttodate), [unixEpoch](#unixepoch). + +### now + +현재 날짜/시간으로, 다른 날짜 기능과 함께 사용한다. + +### ago + +`ago` 함수는 time.Now에서 초 단위로 기간을 반환한다. + +``` +ago .CreatedAt +``` + +`time.Duration` String() 형식을 반환한다. + +``` +2h34m7s +``` + +### date + +`date` 함수는 날짜 형식을 지정한다. + +날짜 형식을 YEAR-MONTH-DAY로 지정한다. + +``` +now | date "2006-01-02" +``` + +Go 에서의 날짜 형식은 +[조금 상이하다](https://pauladamsmith.com/blog/2011/05/go_time.html). + +간단히 말해서, 이것을 기준 날짜로 한다. + +``` +Mon Jan 2 15:04:05 MST 2006 +``` + +원하는 형식으로 작성하자. +위의 경우, `2006-01-02` 와 같은 날짜이지만, 우리가 원하는 형식으로 작성되었다. + +### dateInZone + +`date` 와 동일하지만, 시간대가 있다. + +``` +dateInZone "2006-01-02" (now) "UTC" +``` + +### duration + +주어진 시간(초)을 `time.Duration` 형식으로 지정한다. + +아래의 경우, 1분 35초를 반환한다. + +``` +duration 95 +``` + +### durationRound + +주어진 기간을 가장 중요한 단위로 반올림한다. +문자열과 `time.Duration` 은 기간으로 파싱되며, +`time.Time` 은 경과한 기간으로 계산된다. + +아래의 경우, 2h 를 반환한다. + +``` +durationRound "2h10m5s" +``` + +이 경우는 3mo를 반환한다. + +``` +durationRound "2400h10m5s" +``` + +### unixEpoch + +`time.Time` 에 대한 유닉스 시간(unix epoch)를 반환한다. + +``` +now | unixEpoch +``` + +### dateModify, mustDateModify + +`dateModify` 는 날짜를 가져와서 수정한 후에, 타임 스탬프를 반환한다. + +아래의 경우 현재 시간에서 1시간 30분을 뺀 시간을 반환한다. + +``` +now | date_modify "-1.5h" +``` + +수정 형식이 잘못된 경우 `dateModify` 는 수정되지 않은 날짜를 반환한다. +`mustDateModify` 는 수정 형식이 잘못된 경우 오류를 반환한다. + +### htmlDate + +`htmlDate` 함수는 HTML 날짜 선택기 입력 필드에 삽입할 날짜 형식을 +지정한다. + +``` +now | htmlDate +``` + +### htmlDateInZone + +htmlDate 와 동일하지만, 시간대가 추가된다. + +``` +htmlDateInZone (now) "UTC" +``` + +### toDate, mustToDate + +`toDate` 는 문자열을 날짜로 변환한다. 첫 번째 인수는 날짜 레이아웃이고 두 번째 인수는 날짜 문자열이다. +문자열을 변환할 수 없으면 0 값을 반환한다. +`mustToDate` 는 문자열을 변환할 수 없는 경우 오류를 반환한다. + +이는 문자열 날짜를 파이프를 사용하여 다른 형식으로 변환하려는 경우에 유용하다. +아래 예는 "2017-12-31" 을 "31/12/2017" 로 변환한다. + +``` +toDate "2006-01-02" "2017-12-31" | date "02/01/2006" +``` + +## 사전 및 사전 함수 + +헬름은 `dict` (파이썬에서의 "dictionary"의 약자) 라는 키/값 저장소 유형을 제공한다. +`dict` 는 _정렬되지 않는_ 유형이다. + +딕셔너리의 키는 **문자열이어야 한다.** 그러나 값은 모든 유형, 심지어 +다른 `dict` 또는 `list` 일 수도 있다. + +`list` 와 달리, `dict` 는 변경 불가능(immutable)하다. `set`과 `unset` 함수는 딕셔너리의 +내용을 변경한다. + +헬름은 딕셔너리에 대한 작업을 지원하기 위해 다음의 함수를 제공한다: [deepCopy +(mustDeepCopy)](#deepcopy-mustdeepcopy), [dict](#dict), [get](#get), +[hasKey](#haskey), [keys](#keys), [merge (mustMerge)](#merge-mustmerge), +[mergeOverwrite (mustMergeOverwrite)](#mergeoverwrite-mustmergeoverwrite), +[omit](#omit), [pick](#pick), [pluck](#pluck), [set](#set), [unset](#unset), +[values](#values). + +### dict +ㅣ +`dict` 함수를 호출하고 키/값들의 리스트를 전달함으로써 사전이 +생성된다. + +다음은 세 항목이 있는 사전을 만든다. + +``` +$myDict := dict "name1" "value1" "name2" "value2" "name3" "value 3" +``` + +### get + +주어진 맵과 그 키에 대하여, 맵으로부터 값을 가져온다. + +``` +get $myDict "key1" +``` + +위 결과는 `"value1"` 을 반환한다. + +키를 찾을 수 없는 경우 이 작업은 단순히 `""` 를 반환한다. +별도의 오류가 발생하지는 않는다. + +### set + +`set` 을 사용하여 새 키/값 쌍을 사전에 추가한다. + +``` +$_ := set $myDict "name4" "value4" +``` + +`set` 은 (Go 템플릿 함수의 요구 사항으로) _사전을 반환함으로_ +위와 같이 `$ _` 을 이용하여 값을 관리해야 +할 수도 있다. + +### unset + +주어진 맵과 그 키에 대하여, 맵에서 키와 값을 삭제한다. + +``` +$_ := unset $myDict "name4" +``` + +`set` 과 마찬가지로, 사전을 반환한다. + +키를 찾을 수 없는 경우, 이 작업은 단순하게 반환된다. +별도의 오류는 생성되지 않는다. + +### hasKey + +주어진 사전에 주어진 키가 포함되어 있으면, `hasKey` 함수는 `true` 를 반환한다. + +``` +hasKey $myDict "name1" +``` + +키를 찾을 수 없는 경우 `false` 를 반환한다. + +### pluck + +`pluck` 함수를 사용하면 하나의 키와 여러 맵을 제공하고 모든 일치 항목의 목록을 +가져올 수 있다. + +``` +pluck "name1" $myDict $myOtherDict +``` + +위는 발견된 모든 값 (`[value1 otherValue1]`)을 +포함하는 `list` 를 반환한다. + +지정된 키가 맵에서 발견되지 _않으면_ 해당 맵은 +목록에 항목이 없는 것이며 반환 된 목록의 길이는 `pluck` 호출의 +딕셔너리 수보다 적게 된다. + +만약 키가 _발견되었는데_ 그 값이 빈 값이면 해당 값이 +삽입된다. + +헬름 템플릿에서는 일반적으로, 사전 모음에서 첫 번째 일치하는 키를 가져오기 위해 +`pluck ... | first` 와 같이 사용한다. + +### merge, mustMerge + +둘 이상의 사전을 하나로 병합하여 대상 사전에 우선 순위를 +부여한다. + +``` +$newdict := merge $dest $source1 $source2 +``` + +이것은 전체 병합 작업이지만 전체 복사 작업은 아니다. +병합되어 중첩된 개체는 두 딕셔너리에서 동일한 인스턴스이다. +병합과 함께 깊은 복사(deep copy)를 원하면 병합하면서 `deepCopy` 기능을 사용하자. +예를 들면 + +``` +deepCopy $source | merge $dest +``` + +`mustMerge` 는 병합에 실패한 경우 오류를 반환한다. + +### mergeOverwrite, mustMergeOverwrite + +둘 이상의 사전을 하나로 병합하여 **오른쪽에서 왼쪽으로** 우선 순위를 지정하여 +대상 사전의 값을 효과적으로 덮어쓴다. + +아래의 경우 + +``` +dst: + default: default + overwrite: me + key: true + +src: + overwrite: overwritten + key: false +``` + +결과는 다음과 같다. + +``` +newdict: + default: default + overwrite: overwritten + key: false +``` + +``` +$newdict := mergeOverwrite $dest $source1 $source2 +``` + +이것은 전체 병합 작업이지만 전체 복사 작업은 아니다. +병합되어 중첩된(nested) 객체는 두 딕셔너리에서 동일한 인스턴스이다. +병합과 함께 깊은 복사(deep copy)를 원하면 병합할 때 `deepCopy` 기능을 사용하자. +예를 들면, + +``` +deepCopy $source | mergeOverwrite $dest +``` + +병합에 실패한 경우 `mustMergeOverwrite` 는 오류를 반환한다. + +### keys + +`keys` 함수는 하나 이상의 `dict` 유형에 있는 모든 키의 `list` 를 반환한다. +딕셔너리는 _정렬되어 있지 않으므로_ 키는 예측 가능한 순서가 아니다. +`sortAlpha` 로 정렬할 수 있다. + +``` +keys $myDict | sortAlpha +``` + +여러 딕셔너리를 제공할 때 키들은 결합된다(concatenated). `sortAlpha` 와 +함께 `uniq` 함수를 사용하여 정렬된 키 목록을 얻을 수 있다. + +``` +keys $myDict $myOtherDict | uniq | sortAlpha +``` + +### pick + +`pick` 함수는 사전에서 주어진 키만 선택하여 +새로운 `dict` 를 만든다. + +``` +$new := pick $myDict "name1" "name2" +``` + +위 결과는 `{name1 : value1, name2 : value2}` 를 반환한다. + +### omit + +`omit` 함수는 주어진 키와 일치하지 _않는_ 모든 키가 포함된 +새로운 `dict` 를 반환한다는 점을 제외하면 `pick` 과 유사하다. + +``` +$new := omit $myDict "name1" "name3" +``` + +위 결과는 `{name2: value2}` 를 반환한다. + +### values + +`values` 함수는 원본 `dict` 의 모든 값이 포함된 새로운 +`list` 를 반환한다는 점을 제외하면 `keys` 와 유사하다(오직 하나의 딕셔너리만 지원). + +``` +$vals := values $myDict +``` + +위 결과는 `list [ "value1", "value2", "value 3"]` 를 반환한다. +`values` 함수는 결과에 대한 순서를 보장하지 않는다. +필요시에는 `sortAlpha` 를 사용하자. + +### deepCopy, mustDeepCopy + +`deepCopy` 및 `mustDeepCopy` 함수는 값을 가져와 +값의 깊은 복사본(deep copy)을 만든다. 여기에는 딕셔너리 등 다른 구조가 포함된다. +문제가 있으면 `deepCopy` 의 경우 패닉이 발생하며, +`mustDeepCopy` 는 오류가 있을 때 템플릿 시스템에 오류를 반환한다. + +``` +dict "a" 1 "b" 2 | deepCopy +``` + +### Dict 내부에 대한 참고 사항 + +`dict` 는 Go에서 `map[string] interface{}` 으로 구현된다. +Go 개발자는 `map[string] interface{}` 값을 컨텍스트에 전달하여 +템플릿에서 `dict` 로 사용하도록 할 수 있다. + +## 인코딩 함수 + +헬름에는 다음과 같은 인코딩 및 디코딩 기능이 있다. + +- `b64enc`/`b64dec`: Base64로 인코딩 또는 디코딩 +- `b32enc`/`b32dec`: Base32로 인코딩 또는 디코딩 + +## 목록 및 목록 함수 + +헬름은 임의의 순차적 데이터 목록을 포함할 수 있는 간단한 `리스트` 형을 +제공한다. 이것은 배열 또는 슬라이스와 유사하지만 목록은 변경 불가능한 +데이터 유형으로 사용되도록 설계되었다. + +정수의 목록을 생성해보자. + +``` +$myList := list 1 2 3 4 5 +``` + +위 결과는 `[1 2 3 4 5]` 의 목록을 생성한다. + +헬름은 다음의 함수 목록을 제공한다. [append +(mustAppend)](#append-mustappend), [compact +(mustCompact)](#compact-mustcompact), [concat](#concat), [first +(mustFirst)](#first-mustfirst), [has (mustHas)](#has-musthas), [initial +(mustInitial)](#initial-mustinitial), [last (mustLast)](#last-mustlast), +[prepend (mustPrepend)](#prepend-mustprepend), [rest +(mustRest)](#rest-mustrest), [reverse (mustReverse)](#reverse-mustreverse), +[seq](#seq), [slice (mustSlice)](#slice-mustslice), [uniq +(mustUniq)](#uniq-mustuniq), [until](#until), [untilStep](#untilstep), +[without (mustWithout)](#without-mustwithout). + +### first, mustFirst + +목록에서 머리부분 항목을 얻어 오려면 `first` 를 사용하자. + +`first $myList` 는 `1` 를 반환한다. + +문제가 있으면 `first` 는 패닉이 발생하며, `mustFirst` 의 경우 문제가 있으면 +템플릿 엔진에 오류를 반환한다. + +### rest, mustRest + +목록의 꼬리부분(첫 번째 항목을 제외한 모든 항목)을 얻으려면 `rest` 를 사용하자. + +`rest $myList` 는 `[2 3 4 5]` 반환한다. + +문제가 있으면 `rest` 는 패닉이 발생하며, `mustRest` 는 +문제가 있으면 템플릿 엔진에 오류를 반환한다. + +### last, mustLast + +목록의 마지막 항목을 가져 오려면 `last` 를 사용하자. + +`last $myList` 는 `5` 를 반환한다. +이것은 목록을 뒤집은 다음 `first` 를 호출하는 것과 거의 유사하다. + +### initial, mustInitial + +이 함수는 마지막 요소를 _제외한_ 모든 요소를 반환함으로써 `last` 를 보완한다. +`initial $myList` 는 `[1 2 3 4]` 를 반환한다. + +문제가 있으면 `initial` 은 패닉이 발생하고 `mustInitial` 의 경우, +템플릿 엔진에 오류를 반환한다. + +### append, mustAppend + +기존 목록에 새 항목을 추가하여 새 목록을 만든다. + +``` +$new = append $myList 6 +``` + +위의 경우 `$new` 를 `[1 2 3 4 5 6]` 로 설정한다. `$myList` 는 변경되지 않는다. + +문제가 있으면 `append` 는 패닉이 발생하며 `mustAppend` 의 경우, +문제가 있으면 템플릿 엔진에 오류를 반환한다. + +### prepend, mustPrepend + +요소를 목록의 맨 앞으로 밀어 새 목록을 만든다. + +``` +prepend $myList 0 +``` + +위의 경우 `[0 1 2 3 4 5]` 가 생성된다. `$myList` 는 변경되지 않는다. + +문제가 있을 경우 `prepend` 는 패닉이 발생하며 `mustPrepend` 는 +문제가 있을 경우 템플릿 엔진에 오류를 반환한다. + +### concat + +임의의 수의 목록을 하나로 결합한다. + +``` +concat $myList ( list 6 7 ) ( list 8 ) +``` + +위의 경우 `[1 2 3 4 5 6 7 8]` 이 생성된다. `$myList` 는 변경되지 않는다. + +### reverse, mustReverse + +주어진 목록의 반전 된 요소로 새 목록을 생성한다. + +``` +reverse $myList +``` + +위의 경우 `[5 4 3 2 1]` 목록이 반환된다. + +`reverse` 는 문제가 있으면 패닉이 발생하고 +`mustReverse` 는 문제가 있으면 템플릿 엔진에 오류를 반환한다. + +### uniq, mustUniq + +모든 중복 항목이 제거 된 목록을 생성한다. + +``` +list 1 1 1 2 | uniq +``` + +위의 경우 `[1 2]` 가 생성된다. + +문제가 있으면 `uniq` 는 패닉이 발생하고 +`mustUniq` 는 문제가 있으면 템플릿 엔진에 오류를 반환한다. + +### without, mustWithout + +`without` 함수는 목록에서 항목을 필터링한다. + +``` +without $myList 3 +``` + +위의 경우`[1 2 4 5]` 가 생성된다. + +without 의 경우 하나 이상의 필터를 사용할 수도 있다. + +``` +without $myList 1 3 5 +``` + +그러면 `[2 4]` 가 생성된다. + +문제가 있으면 `without` 의 경우 패닉이 발생하고 +`mustWithout` 의 경우는 문제가 있으면 템플릿 엔진에 오류를 반환한다. + +### has, mustHas + +목록에 특정 요소가 있는지를 테스트한다. + +``` +has 4 $myList +``` + +위의 경우 `true` 를 반환하고 `has "hello" $myList` 는 false를 반환한다. + +문제가 있으면 `has` 는 패닉이 발생하고 `mustHas` 는 문제가 있으면 템플릿 엔진에 +오류를 반환한다. + +### compact, mustCompact + +목록을 승인하고 값이 비어있는 항목을 제거한다. + +``` +$list := list 1 "a" "foo" "" +$copy := compact $list +``` + +`compact` 는 비어 있는 항목(즉, "")이 제거된 새 목록을 반환한다. + +문제가 있는 경우 `compact` 는 패닉이 발생하고 +`mustCompact` 의 경우 템플릿 엔진에 오류를 반환한다. + +### slice, mustSlice + +목록의 일부 요소를 가져 오려면 `slice list [n] [m]` 을 사용하자. `list [n : m]` 과도 +동일하다. + +- `slice $myList` 는 `[1 2 3 4 5]` 을 반환한다. `myList[:]` 와 동일하다. +- `slice $myList 3` 는 `[4 5]` 을 반환한다. `myList[3:]` 와 동일하다. +- `slice $myList 1 3` 는 `[2 3]` 을 반환한다. `myList[1:3]` 와 동일하다. +- `slice $myList 0 3` 는 `[1 2 3]` 을 반환한다. `myList[:3]` 와 동일하다. + +문제가 있으면 `slice` 는 패닉이 발생하며, `mustSlice` 는 문제가 있으면 +템플릿 엔진에 오류를 반환한다. + +### until + +`until` 함수는 정수 범위를 만든다. + +``` +until 5 +``` + +위 결과로 `[0, 1, 2, 3, 4]` 목록을 생성한다. + +이것은 `range $i, $e := until 5` 로 반복할 때 유용하다. + +### untilStep + +`until` 과 마찬가지로 `untilStep` 은 지표로서의 정수 목록을 생성한다. +또한 시작 지표, 끝 지표 및 지표 증분을 정의 할 수 있다. + +``` +untilStep 3 6 2 +``` + +위의 코드는 3으로 시작하여 6보다 크거나 같을 때까지 2를 더하여 +`[3 5]` 를 생성한다. 이것은 파이썬의 `range` 함수와 유사하다. + +### seq + +bash 셸의 `seq` 명령어와 유사하게 작동한다. + +* 1 개의 매개 변수 (끝) - 1과 `끝` 사이의 + 모든 지표 정수를 생성. +* 2 개의 매개 변수 (시작, 끝) - `start` 와 `end` 사이에 1 씩 + 증가 또는 감소하는 모든 지표 정수를 생성. +* 3 개의 매개 변수 (시작, 증분, 끝) - `start` 와 `end` 사이의 모든 + 지표 정수 (`step` 단위 증가 또는 감소 포함)를 생성합니다. + +``` +seq 5 => 1 2 3 4 5 +seq -3 => 1 0 -1 -2 -3 +seq 0 2 => 0 1 2 +seq 2 -2 => 2 1 0 -1 -2 +seq 0 2 10 => 0 2 4 6 8 10 +seq 0 -2 -5 => 0 -2 -4 +``` + +## 수학 함수 + +모든 수학 함수는 달리 지정하지 않는 한 `int64` 값으로 작동한다. + +다음의 수학 함수를 사용할 수 있다: [add](#add), [add1](#add1), +[ceil](#ceil), [div](#div), [floor](#floor), [len](#len), [max](#max), +[min](#min), [mod](#mod), [mul](#mul), [round](#round), [sub](#sub). + +### add + +몇 개의 숫자를 더한다. 2개나 그 이상의 입력도 허용된다. + +``` +add 1 2 3 +``` + +### add1 + +1만큼 증가시키려면 `add1` 을 사용하자. + +### sub + +빼려면 `sub` 를 사용한다. + +### div + +`div` 로 정수 나누기를 수행한다. + +### mod + +`mod` 로 모듈로 연산을 수행한다. + +### mul + +`mul` 로 곱하기 연산을 수행한다. 2개 이상의 입력을 허용한다. + +``` +mul 1 2 3 +``` + +### max + +일련의 정수중 가장 큰 값을 반환한다. + +아래의 경우 `3` 을 반환한다. + +``` +max 1 2 3 +``` + +### min + +일련의 정수중 가장 작 값을 반환한다. + +아래의 경우 `1` 을 반환한다. + +### floor + +입력 값보다 작거나 같은 가장 큰 부동 소수점 값을 출력한다. + +`floor 123.9999` 의 경우 `123.0` 을 반환한다. + +### ceil + +입력 값보다 크거나 같은 가장 작은 부동 소수점 값을 출력한다. + +`ceil 123.001` 의 경우 `124.0` 을 반환한다. + +### round + +반올림하여, 주어진 소수점의 자리수를 갖는 부동 소수점 값을 +반환한다. + +`round 123.555555 3` 의 경우 `123.556` 을 반환한다. + +### len + +인수의 길이를 정수로 반환한다. + +``` +len .Arg +``` + +## 네트워크 함수 + +헬름에는 `getHostByName` 하나의 네트워크 함수가 있다. + +`getHostByName` 은 도메인 이름을 받고 IP 주소를 반환한다. + +``` +getHostByName "www.google.com" would return the corresponding ip address of www.google.com +``` + +## 파일 경로 함수 + +헬름 템플릿 함수는 파일 시스템에 대한 액세스 권한을 부여하지 않지만 +파일 경로 규칙을 따르는 문자열 작업을위한 함수 를 제공한다. +여기에는 [base] (# base), [clean] (# clean), +[dir] (# dir), [ext] (# ext) 및 [isAbs] (# isabs)가 포함된다. + +### base + +경로의 마지막 요소를 반환한다. + +``` +base "foo/bar/baz" +``` + +위 결과는 "baz" 를 반환한다. + +### dir + +경로의 마지막 부분을 제거하여 디렉토리를 반환한다. 따라서 `dir "foo/bar/baz"` +는 `foo/bar` 를 반환한다. + +### clean + +경로를 삭제한다. + +``` +clean "foo/bar/../baz" +``` + +위 결과는 `..` 을 찾아서 `foo/baz` 를 반환한다. + +### ext + +파일의 확장자를 반환한다. + +``` +ext "foo.bar" +``` + +위 결과는 `.bar` 를 반환한다. + +### isAbs + +파일 경로가 절대경로인지 확인하려는 경우 `isAbs` 를 사용한다. + +## 리플렉션 함수 + +헬름은 기초적인 리플렉션 도구를 제공한다. +이는 고급 템플릿 개발자가 특정 값에 대한 기본 Go 유형 정보를 이해하는 데 도움이 된다. +헬름은 Go로 작성되었으며 강타입 언어이다. 타입 시스템은 템플릿 내에서 +적용된다. + +Go 에는 `string`, `slice`, `int64`, `bool` 과 같은 몇 가지 기본(primitive) _유형(kind)_ 이 있다. + +Go 에는 개발자가 자신의 자료형을 만들 수 있는 개방형 _자료형_ 체계가 있다. + +헬름은 [유형 함수](#유형-함수) 및 [타입 함수](#타입-함수)을 통해 +각각에 대한 함수 집합을 제공한다. +값과 비교하기 위해 [deepEqual](#deepequal) 함수도 제공된다. + +### 유형 함수 + +유형 함수에는 두 가지가 있다. `kindOf` 는 객체의 유형을 반환한다. + +``` +kindOf "hello" +``` + +위는 `string` 을 반환한다. (`if` 블록과 같은) 간단한 테스트의 경우 +`isKind` 함수를 사용하면 값이 특정 유형인지 확인할 수 있다. + +``` +kindIs "int" 123 +``` + +위 결과는 `true` 를 반환한다. + +### 타입 함수 + +타입은 다루기가 약간 더 어렵기에, 타입 함수는 총 3가지가 있다. + +- `typeOf` 는 값의 기본 타입을 반환한다. 예) `typeOf $foo` +- `typeIs` 는 `kindIs` 와 비슷하지만, 타입에 대한 것이다. 예) `typeIs "*io.Buffer" $myVal` +- `typeIsLike` 는 포인터를 역참조한다는 점을 제외하면 `typeIs` 처럼 동작한다. + +**참고:** 이 중 어느 것도 주어진 인터페이스를 구현하는지 +여부를 테스트할 수는 없다. 그렇게 하려면 인터페이스를 미리 컴파일해야 +하기 때문이다. + +### deepEqual + +`deepEqual` 은 두 값이 +["깊은 같음"](https://golang.org/pkg/reflect/#DeepEqual)이면 true를 반환한다. + +비-기본(non-primitive) 타입에서도 동작한다. (내장된 `eq`와 비교된다.) + +``` +deepEqual (list 1 2 3) (list 1 2 3) +``` + +위 결과는 `true` 를 반환한다. + +## 유의적 버전 함수 + +일부 버전 체계는 쉽게 구문을 분석하고 비교할 수 있다. +헬름은 [유의적 버전 2] (http://semver.org) 버전 작업을 위한 기능을 제공한다. +여기에는 [semver](#semver) 및 [semverCompare](#semvercompare)가 포함된다. +아래에서 비교를 위해 범위를 사용하는 방법에 대한 세부 정보도 찾을 수 있다. + +### semver + +`semver` 함수는 문자열을 유의적 버전으로 구문 분석한다. + +``` +$version := semver "1.2.3-alpha.1+123" +``` + +_파서가 실패하면 템플릿 실행이 오류와 함께 중지된다._ + +이 시점에서 `$version` 은 다음 속성을 가진 `Version` 객체에 대한 +포인터이다. + +- `$version.Major` : 주 번호 (위의 `1`) +- `$version.Minor` : 부 번호 (위의 `2`) +- `$version.Patch` : 패치 번호 (위의 `3`) +- `$version.Prerelease` : 프리 릴리스 (위의 `alpha.1`) +- `$version.Metadata` : 빌드 메타 데이터 (위의 `123`) +- `$version.Original` : 문자열로 된 원본 버전 + +또한 `Compare` 함수를 사용하여 `버전` 을 다른 `버전` 과 비교할 수 +있다. + +``` +semver "1.4.3" | (semver "1.2.3").Compare +``` + +위 결과는 `-1` 을 반환한다. + +반환 값은 다음과 같다. + +- 주어진 유의적 버전이 `Compare` 메소드로 호출된 + 유의적 버전보다 큰 경우 `-1` +- `Compare` 함수로 호출 된 버전이 더 큰 경우 `1`. +- 동일한 버전인 경우 `0` + +(유의적 버전에서는 버전 비교 작업 중 `Metadata` 필드는 비교되지 않는 것에 +유의하자.) + +### semverCompare + +보다 강력한 비교 기능은 `semverCompare` 를 통해 제공된다. +이 버전은 버전의 범위를 지원한다. + +- `semverCompare "1.2.3" "1.2.3"` 은 정확히 일치하는지 확인합니다. +- `semverCompare "^ 1.2.0" "1.2.3"` 은 주 버전과 부 버전이 일치하는지, + 두 번째 버전의 패치 번호가 첫 번째 매개 변수보다 크거나 같은지 + 확인한다. + +SemVer 함수는 Sprig 제작자의 +[Masterminds semver 라이브러리] (https://github.com/Masterminds/semver)를 사용한다. + +### 기본 비교 + +비교에는 두 가지 요소가 있다. +첫째, 비교 문자열은 공백 또는 쉼표로 구분 된 AND 비교 목록이다. +그런 다음 || (OR) 비교로 구분된다. +예를 들어 `"> = 1.2 <3.0.0 ||> = 4.2.3"` 은 +1.2보다 크거나 같고 3.0.0보다 작거나 4.2.3보다 크거나 같은지를 비교한다. + +기본 비교는 다음과 같다. + +- `=` : 같음 (연산자 없음으로 별칭 지정) +- `! =` : 같지 않음 +- `>` : 보다 큼 +- `<` : 보다 작음 +- `> =` : 보다 크거나 같음 +- `<=` : 보다 작거나 같음 + +_참고로, 유의적 버전 사양에 따라 프리 릴리스는 +해당 릴리스의 대응하는 부분의 API를 준수하지 않을 수도 있다._ + +### 프리 릴리스 버전으로 작업하기 + +익숙하지 않은 사용자를 위해 프리-릴리스는, 안정된 릴리스 또는 일반적으로 +사용 가능한 릴리스 이전의 소프트웨어 릴리스에 사용된다. +프리-릴리스의 예로는 개발, 알파, 베타 및 릴리스 후보 릴리스가 있다. +프리 릴리스는 `1.2.3-beta.1` 와 같은 버전 일 수 있고 안정된 릴리스는 `1.2.3` 이 될 수 있다. +우선 순위에 따라 프리 릴리스가 관련 릴리스보다 먼저 나온다. +이 예에서는 `1.2.3-beta.1 <1.2.3` 이다. + +유의적 버전 사양에 따라 프리 릴리스는 +해당 릴리스의 대응하는 부분의 API를 준수하지 않을 수도 있다. + +> 프리-릴리스 버전은 버전이 불안정하고 +> 관련 일반 버전에 표시된대로 의도 된 호환성 요구 사항을 +> 충족하지 않을 수 있음을 나타낸다. + +프리-릴리스 버전을 비교하지 않고 제약 조건을 사용하는 유의적 버전의 비교는 프리-릴리스 버전을 건너 뛴다. +예를 들어 `>=1.2.3` 은 출시 목록을 볼 때 프리 릴리스를 건너 뛰고 +`>=1.2.3-0` 은 프리 릴리스를 평가하고 찾는다. + +비교의 예에서 `0` 이 출시 전 버전인 이유는 +사양에 따라 출시 전 버전에 ASCII 영문/숫자 및 하이픈 (`.` 구분 기호 포함)만 +포함할 수 있기 때문이다. +정렬은 사양에 따라 ASCII 정렬 순서로 발생한다. +가장 낮은 문자는 ASCII 정렬 순서로 `0` 이다([ASCII 테이블](http://www.asciitable.com/) 참조). + +ASCII 정렬 순서를 이해하는 것은 A-Z가 a-z 앞에 오기 때문에 중요하다. +즉, `>=1.2.3-BETA` 는 `1.2.3-alpha` 를 반환한다. +대소문자는 구분되지 않는다. +이것은 지정된 ASCII 정렬 순서 때문이다. + +### 하이픈 범위 비교 + +범위를 처리하는 방법은 여러 가지가 있으며, 첫 번째 방법은 하이픈 범위이다. +다음과 같다. + +- `1.2 - 1.4.5` 는 `>= 1.2 <= 1.4.5` 과 동일하다. +- `2.3.4 - 4.5` 는 `>= 2.3.4 <= 4.5` 과 동일하다. + +### 비교에서의 와일드카드 + +`x` , `X` , `*` 문자는 와일드 카드 문자로 사용할 수 있다. +이것은 모든 비교 연산자에 적용된다. +`=` 연산자에 사용하면 패치 수준의 비교로 돌아간다 (아래 물결표 참조). 예를 들면 + +- `1.2.x` 는 `>= 1.2.0, < 1.3.0` 과 동일하다. +- `>= 1.2.x` 는 `>= 1.2.0` 과 동일하다. +- `<= 2.x` 는 `< 3` 과 동일하다. +- `*` 는 `>= 0.0.0` 과 동일하다. + +### 물결표 범위 비교 (패치) + +물결표 (`~`) 비교 연산자는 부 버전이 지정되면 +패치 수준 범위에 사용되며 부 번호가 누락되면 주 수준이 변경된다. +예를 들면, + +- `~1.2.3` 는 `>= 1.2.3, < 1.3.0` 과 동일하다. +- `~1` 는 `>= 1, < 2` 과 동일하다. +- `~2.3` 는 `>= 2.3, < 2.4` 과 동일하다. +- `~1.2.x` 는 `>= 1.2.0, < 1.3.0` 과 동일하다. +- `~1.x` 는 `>= 1, < 2` 과 동일하다. + +### 캐럿 범위 비교 (주) + +캐럿 (`^`) 비교 연산자는 안정적인 (1.0.0) 릴리스가 발생했을 때 +주요 레벨 변경을 위한 것이다. +1.0.0 릴리스 이전에는 부 버전이 API 안정성 수준으로 작동한다. +API 버전을 비교할 때 주요 변경 사항이 API 중단일 때 유용하다. 예를 들면, + +- `^1.2.3` 는 `>= 1.2.3, < 2.0.0` 과 동일하다. +- `^1.2.x` 는 `>= 1.2.0, < 2.0.0` 과 동일하다. +- `^2.3` 는 `>= 2.3, < 3` 과 동일하다. +- `^2.x` 는 `>= 2.0.0, < 3` 과 동일하다. +- `^0.2.3` 는 `>=0.2.3 <0.3.0` 과 동일하다. +- `^0.2` 는 `>=0.2.0 <0.3.0` 과 동일하다. +- `^0.0.3` 는 `>=0.0.3 <0.0.4` 과 동일하다. +- `^0.0` 는 `>=0.0.0 <0.1.0` 과 동일하다. +- `^0` 는 `>=0.0.0 <1.0.0` 과 동일하다. + +## URL 함수 + +헬름에는 [urlParse](#urlparse), [urlJoin](#urljoin) 및 [urlquery](#urlquery) 함수가 +포함되어있어 URL 부분으로 작업 할 수 있다다. + +### urlParse + +URL에 대한 문자열을 구문 분석하고 URL 부분으로 딕셔너리를 생성한다. + +``` +urlParse "http://admin:secret@server.com:8080/api?list=false#anchor" +``` + +위는 URL 객체를 포함하는 딕셔너리를 반환한다. + +```yaml +scheme: 'http' +host: 'server.com:8080' +path: '/api' +query: 'list=false' +opaque: nil +fragment: 'anchor' +userinfo: 'admin:secret' +``` + +이것은 Go 표준 라이브러리의 URL 패키지를 사용하여 구현된다. +자세한 내용은 https://golang.org/pkg/net/url/#URL을 확인하자. + +### urlJoin + +(`urlParse`에서 생성된) 맵을 결합하여 URL 문자열을 생성한다. + +``` +urlJoin (dict "fragment" "fragment" "host" "host:80" "path" "/path" "query" "query" "scheme" "http") +``` + +위는 다음 문자열을 반환한다. +``` +http://host:80/path?query#fragment +``` + +### urlquery + +URL의 쿼리 부분에 포함하기에 적합하도록 인수로 전달된 값의 +이스케이프된 버전을 반환한다. + +``` +$var := urlquery "string for query" +``` + +## UUID 함수 + +헬름은 UUID v4 범용 고유 ID를 생성할 수 있다. + +``` +uuidv4 +``` + +위는 v4 (무작위 생성) 유형의 새 UUID를 반환한다. + +## 쿠버네티스 및 차트 함수 + +헬름에는 +[.Capabilities.APIVersions.Has](#capabilitiesapiversionshas), [Files](#파일-함수), [lookup](#lookup) 등 +쿠버네티스 작업을 위한 함수가 포함되어 있다. + +### lookup + +`lookup` 은 실행중인 클러스터에서 리소스를 조회하는 데 사용된다. +`helm template` 명령어와 함께 사용하면 항상 빈 응답을 반환한다. + +[조회 함수에 대한 문서](functions_and_pipelines.md/#lookup-함수-사용하기)에서 +자세한 내용을 확인할 수 있다. + +### .Capabilities.APIVersions.Has + +클러스터에서 API 버전 또는 리소스를 사용할 수 있는지에 대한 여부를 반환한다. + +``` +.Capabilities.APIVersions.Has "apps/v1" +.Capabilities.APIVersions.Has "apps/v1/Deployment" +``` + +더 많은 정보는 [내장 객체 문서](builtin_objects.md)에서 +확인할 수 있다. + +### 파일 함수 + +차트 내에서 비 특수 파일을 얻을 수 있는 함수가 몇 가지 있다. +예를 들면, 애플리케이션 구성 파일에 액세스하는 것이다. +이는 [템플릿 내 파일 액세스](accessing_files.md)에 설명되어 있다. + +_ 참고로, 이렇게 많은 함수들에 대한 문서화는 +[Sprig](https://github.com/Masterminds/sprig)로 이루어졌다. +Sprig은 Go 애플리케이션에서 사용할 수 있는 템플릿 함수 라이브러리이다._ diff --git a/content/ko/docs/chart_template_guide/functions_and_pipelines.md b/content/ko/docs/chart_template_guide/functions_and_pipelines.md new file mode 100644 index 0000000000..6ca9355b09 --- /dev/null +++ b/content/ko/docs/chart_template_guide/functions_and_pipelines.md @@ -0,0 +1,253 @@ +--- +title: "템플릿 함수와 파이프라인" +description: "템플릿에서 함수 사용하기" +weight: 5 +--- + +So far, we've seen how to place information into a template. But that +information is placed into the template unmodified. Sometimes we want to +transform the supplied data in a way that makes it more useable to us. + +Let's start with a best practice: When injecting strings from the `.Values` +object into the template, we ought to quote these strings. We can do that by +calling the `quote` function in the template directive: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + drink: {{ quote .Values.favorite.drink }} + food: {{ quote .Values.favorite.food }} +``` + +Template functions follow the syntax `functionName arg1 arg2...`. In the snippet +above, `quote .Values.favorite.drink` calls the `quote` function and passes it a +single argument. + +Helm has over 60 available functions. Some of them are defined by the [Go +template language](https://godoc.org/text/template) itself. Most of the others +are part of the [Sprig template +library](https://masterminds.github.io/sprig/). We'll see many of them +as we progress through the examples. + +> While we talk about the "Helm template language" as if it is Helm-specific, it +> is actually a combination of the Go template language, some extra functions, +> and a variety of wrappers to expose certain objects to the templates. Many +> resources on Go templates may be helpful as you learn about templating. + +## 파이프라인 + +One of the powerful features of the template language is its concept of +_pipelines_. Drawing on a concept from UNIX, pipelines are a tool for chaining +together a series of template commands to compactly express a series of +transformations. In other words, pipelines are an efficient way of getting +several things done in sequence. Let's rewrite the above example using a +pipeline. + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + drink: {{ .Values.favorite.drink | quote }} + food: {{ .Values.favorite.food | quote }} +``` + +In this example, instead of calling `quote ARGUMENT`, we inverted the order. We +"sent" the argument to the function using a pipeline (`|`): +`.Values.favorite.drink | quote`. Using pipelines, we can chain several +functions together: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + drink: {{ .Values.favorite.drink | quote }} + food: {{ .Values.favorite.food | upper | quote }} +``` + +> Inverting the order is a common practice in templates. You will see `.val | +> quote` more often than `quote .val`. Either practice is fine. + +When evaluated, that template will produce this: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: trendsetting-p-configmap +data: + myvalue: "Hello World" + drink: "coffee" + food: "PIZZA" +``` + +Note that our original `pizza` has now been transformed to `"PIZZA"`. + +When pipelining arguments like this, the result of the first evaluation +(`.Values.favorite.drink`) is sent as the _last argument to the function_. We +can modify the drink example above to illustrate with a function that takes two +arguments: `repeat COUNT STRING`: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + drink: {{ .Values.favorite.drink | repeat 5 | quote }} + food: {{ .Values.favorite.food | upper | quote }} +``` + +The `repeat` function will echo the given string the given number of times, so +we will get this for output: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: melting-porcup-configmap +data: + myvalue: "Hello World" + drink: "coffeecoffeecoffeecoffeecoffee" + food: "PIZZA" +``` + +## `default` 함수 사용하기 + +One function frequently used in templates is the `default` function: `default +DEFAULT_VALUE GIVEN_VALUE`. This function allows you to specify a default value +inside of the template, in case the value is omitted. Let's use it to modify the +drink example above: + +```yaml +drink: {{ .Values.favorite.drink | default "tea" | quote }} +``` + +If we run this as normal, we'll get our `coffee`: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: virtuous-mink-configmap +data: + myvalue: "Hello World" + drink: "coffee" + food: "PIZZA" +``` + +Now, we will remove the favorite drink setting from `values.yaml`: + +```yaml +favorite: + #drink: coffee + food: pizza +``` + +Now re-running `helm install --dry-run --debug fair-worm ./mychart` will produce this +YAML: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: fair-worm-configmap +data: + myvalue: "Hello World" + drink: "tea" + food: "PIZZA" +``` + +In an actual chart, all static default values should live in the `values.yaml`, +and should not be repeated using the `default` command (otherwise they would be +redundant). However, the `default` command is perfect for computed values, which +can not be declared inside `values.yaml`. For example: + +```yaml +drink: {{ .Values.favorite.drink | default (printf "%s-tea" (include "fullname" .)) }} +``` + +In some places, an `if` conditional guard may be better suited than `default`. +We'll see those in the next section. + +Template functions and pipelines are a powerful way to transform information and +then insert it into your YAML. But sometimes it's necessary to add some template +logic that is a little more sophisticated than just inserting a string. In the +next section we will look at the control structures provided by the template +language. + +## `lookup` 함수 사용하기 + +The `lookup` function can be used to _look up_ resources in a running cluster. The synopsis of the +lookup function is `lookup apiVersion, kind, namespace, name -> resource or resource list`. + +| 파라미터 | 자료형 | +|------------|--------| +| apiVersion | string | +| kind | string | +| namespace | string | +| name | string | + +Both `name` and `namespace` are optional and can be passed as an empty string (`""`). + +The following combination of parameters are possible: + +| Behavior | lookup 함수 | +|----------------------------------------|--------------------------------------------| +| `kubectl get pod mypod -n mynamespace` | `lookup "v1" "Pod" "mynamespace" "mypod"` | +| `kubectl get pods -n mynamespace` | `lookup "v1" "Pod" "mynamespace" ""` | +| `kubectl get pods --all-namespaces` | `lookup "v1" "Pod" "" ""` | +| `kubectl get namespace mynamespace` | `lookup "v1" "Namespace" "" "mynamespace"` | +| `kubectl get namespaces` | `lookup "v1" "Namespace" "" ""` | + +When `lookup` returns an object, it will return a dictionary. This dictionary can be further +navigated to extract specific values. + +The following example will return the annotations present for the `mynamespace` object: + +```go +(lookup "v1" "Namespace" "" "mynamespace").metadata.annotations +``` + +When `lookup` returns a list of objects, it is possible to access the object list via the `items` +field: + +```go +{{ range $index, $service := (lookup "v1" "Service" "mynamespace" "").items }} + {{/* do something with each service */}} +{{ end }} +``` + +When no object is found, an empty value is returned. This can be used to check for the existence of +an object. + +The `lookup` function uses Helm's existing Kubernetes connection configuration to query Kubernetes. +If any error is returned when interacting with calling the API server (for example due to lack of +permission to access a resource), helm's template processing will fail. + +Keep in mind that Helm is not supposed to contact the Kubernetes API Server during a `helm template` +or a `helm install|update|delete|rollback --dry-run`, so the `lookup` function will return `nil` in +such a case. + +## 연산자는 함수이다 + +For templates, the operators (`eq`, `ne`, `lt`, `gt`, `and`, `or` and so on) are +all implemented as functions. In pipelines, operations can be grouped with +parentheses (`(`, and `)`). + +Now we can turn from functions and pipelines to flow control with conditions, +loops, and scope modifiers. diff --git a/content/ko/docs/chart_template_guide/getting_started.md b/content/ko/docs/chart_template_guide/getting_started.md new file mode 100644 index 0000000000..676d1791df --- /dev/null +++ b/content/ko/docs/chart_template_guide/getting_started.md @@ -0,0 +1,264 @@ +--- +title: "시작하기" +weight: 2 +description: "차트 템플릿에 관한 빠른 가이드" + +--- + +이 섹션에서는 차트를 만든 다음 첫 번째 템플릿을 추가할 것이다. +우리가 여기서 만든 차트는 가이드의 나머지 부분에서 쭉 사용될 것이다. + +시작하기 위해 헬름 차트를 간단히 살펴보자. + +## 차트 + +[차트 가이드]({{< ref path="../topics/charts" lang="en" >}})에 설명된 대로, +헬름 차트는 다음과 같이 구성된다: + +``` +mychart/ + Chart.yaml + values.yaml + charts/ + templates/ + ... +``` + +`templates/` 디렉토리는 템플릿 파일을 위한 것이다. +헬름이 차트를 평가할 때, +`templates/` 디렉토리의 모든 파일을 템플릿 렌더링 엔진으로 전달한다. +그리고 나서 처리 결과를 모아 쿠버네티스로 보낸다. + +`values.yaml` 파일도 템플릿에 중요하다. +이 파일은 차트의 _기본값_ 을 포함한다. +이 값들은 `helm install` 또는 `helm upgrade` 하는 중에 사용자가 재정의할 수 있다. + +`Chart.yaml` 파일은 차트에 대한 설명을 포함한다. +템플릿 안에서 접근할 수 있다. +`charts/` 디렉토리는 다른 차트(_하위차트_ 라고 함)를 포함 _할 수도_ 있다. +본 가이드의 뒷부분에서 템플릿 렌더링과 관련하여 이러한 기능이 어떻게 작동하는지 알아볼 것이다. + +## 스타터 차트 + +본 가이드를 위해 `mychart` 라는 간단한 차트를 만든 다음, +차트 안에 템플릿을 만들 것이다. + +```console +$ helm create mychart +mychart 생성 +``` + +### `mychart/templates/` 훑어보기 + +`mychart/templates/` 를 보면 이미 몇 개의 파일이 있는 것을 알 수 있다. + +- `NOTES.txt` : 차트의 "도움말". 이것은 `helm install` 을 실행할 때 사용자에게 표시될 것이다. +- `deployment.yaml` : 쿠버네티스 + [디플로이먼트](https://kubernetes.io/ko/docs/concepts/workloads/controllers/deployment/)를 + 생성하기 위한 기본 매니페스트 +- `service.yaml` : 디플로이먼트의 [서비스 + 엔드포인트](https://kubernetes.io/ko/docs/concepts/services-networking/service/)를 + 생성하기 위한 기본 매니페스트 +- `_helpers.tpl` : 차트 전체에서 다시 사용할 수 있는 템플릿 헬퍼를 지정하는 공간 + +그리고 우리가 할 일은... _전부 제거하자!_ +그렇게 하면 우리는 튜토리얼의 맨 처음부터 끝까지 실행할 수 있다. +실제로 우리만의 `NOTES.txt` 와 `_helpers.tpl` 을 만들 것이다. + +```console +$ rm -rf mychart/templates/* +``` + +프로덕션용 차트를 작성할 때는 차트의 기본 버전을 사용하는 것이 매우 유용할 수 있다. +따라서 매일 차트를 작성할 때는 차트를 삭제하는 것을 원하지 않을 수도 있다. + +## 첫 번째 템플릿 + +우리가 만들 첫 번째 템플릿은 `ConfigMap` 이 될 것이다. +쿠버네티스에서 컨피그맵은 단순히 환경 설정 데이터를 저장하는 컨테이너일 뿐이다. +파드 같은 다른 것들은 컨피그맵의 데이터에 접근할 수 있다. + +컨피그맵은 기본 리소스이기 때문에 우리에게 좋은 출발점이 된다. + +먼저 `mychart/templates/configmap.yaml` 이라는 파일을 만들어 보자. + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: mychart-configmap +data: + myvalue: "Hello World" +``` + +템플릿 이름은 엄격한 명명 패턴을 따르지 않는다. +단, YAML 파일에는 접미사 `.yaml` 을, 헬퍼에는 `.tpl` 을 사용하는 것이 좋다. + +위의 YAML 파일은 최소한의 필수 필드를 가진 가장 기본적인 컨피그맵이다. +이 파일은 `mychart/template/` 디렉토리에 있기 때문에 템플릿 엔진으로 전달된다. + +`mychart/template/` 디렉토리에 이와 같이 평범한 YAML 파일을 넣는 것은 괜찮다. +헬름이 이 템플릿을 읽으면 쿠버네티스에게 그대로 보낼 뿐이다. + +이 간단한 템플릿으로 우리는 이제 설치 가능한 차트를 가지고 있다. +이렇게 설치하면 된다: + +```console +$ helm install full-coral ./mychart +NAME: full-coral +LAST DEPLOYED: Tue Nov 1 17:36:01 2016 +NAMESPACE: default +STATUS: DEPLOYED +REVISION: 1 +TEST SUITE: None +``` + +헬름을 사용하면 릴리스를 검색해 실제 전송된 템플릿을 볼 수 있다. + +```console +$ helm get manifest full-coral + +--- +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: mychart-configmap +data: + myvalue: "Hello World" +``` + +`helt get manifest` 명령은 릴리스 이름(`full-coral`)을 가지고 +서버에 업로드된 쿠버네티스 리소스를 모두 출력한다. +각 파일은 `---`로 시작하여 YAML 문서의 시작을 표시한 다음 +자동으로 생성된 주석이 나타나 이 YAML 문서를 생성한 템플릿 파일을 알려준다. + +여기서 이 YAML 데이터가 정확히 `configmap.yaml` 파일에 입력한 것임을 알 수 있다. + +이제 릴리스를 제거해도 된다: `helm uninstall full-coral`. + +### 단순한 템플릿 호출 추가하기 + +`name:` 을 리소스 안에 하드 코딩하는 것은 보통 좋지 못한 관행으로 간주된다. +이름은 릴리스에 고유해야 한다. +그래서 릴리스 이름을 삽입하여 이름 필드를 생성하기를 원할 수 있다. + +**TIP:** DNS 시스템에 대한 제한 때문에 `name:` 필드가 63자로 제한된다. +이 때문에 릴리스 이름은 53자로 제한한다. +쿠버네티스 1.3 이하에서는 단 24자(즉, 14자 이름)로 제한하였다. + +이에 따라 `configmap.yaml` 을 바꾸자. + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" +``` + +`name:` 필드의 값에서 `{{ .Release.Name }}-configmap` 이라고 큰 변화가 일어났다. + +> 템플릿 지시문은 `{{` 와 `}}` 으로 감싼다. + +템플릿 지시문 `{{ .Release.Name }}` 은 템플릿에 릴리스 이름을 주입한다. +템플릿으로 전달되는 값은 _네임스페이스 객체_ 로 생각할 수 있으며, +여기서 점(`.`)이 각 네임스페이스 요소를 구분한다. + +`Release` 앞의 점은 해당 스코프(조금 있으면 스코프에 대해 설명하겠다)의 +최상위 네임스페이스부터 시작한다는 것을 나타낸다. +그래서 우리는 `.Release.Name`을 +"최상위 네임스페이스에서부터 시작하여 `Release` 객체를 찾은 다음 +`Name`이라는 객체를 찾아보라"로 읽을 수 있다. + +`Release` 객체는 헬름의 내장 객체 중 하나이며, 이후에 좀 더 심층적으로 다룰 것이다. +현재로서는 헬름 라이브러리가 릴리스에 할당한 이름을 나타내는 것이라고 말해도 +손색이 없다. + +이제 리소스를 설치할 때 이 템플릿 지시어를 사용한 결과를 바로 볼 수 있다. + +```console +$ helm install clunky-serval ./mychart +NAME: clunky-serval +LAST DEPLOYED: Tue Nov 1 17:45:37 2016 +NAMESPACE: default +STATUS: DEPLOYED +REVISION: 1 +TEST SUITE: None +``` + +쿠버네티스 안에 컨피그맵은 이전의 `mychart-configmap` 이 아닌 +`clunky-serval-configmap` 이라는 점에 주목하자. + +`helm get manifest clunky-serval`을 실행하여 생성된 전체 YAML을 볼 수 있다. + +이때 템플릿은 가장 기본적인 것으로, `{{` 와 `}}` 에 내장된 템플릿 지시문을 가진 YAML 파일이다. +다음 단계에서는 템플릿에 대해 더 자세히 살펴보도록 하겠다. +그러나 다음 단계로 넘어가기 전에 템플릿을 더 빨리 만들 수 있는 한 가지 요령을 보자: +실제로 아무것도 설치하지 않지만 템플릿 렌더링을 테스트하고 싶다면 +`helm install --debug --dry-run goodly-guppy ./mychart` 를 사용할 수 있다. +이렇게 하면 템플릿이 렌더링된다. +그러나 차트를 설치하는 대신 렌더링 된 템플릿을 반환하여 이러한 출력을 볼 수 있다: + +```console +$ helm install --debug --dry-run goodly-guppy ./mychart +install.go:149: [debug] Original chart version: "" +install.go:166: [debug] CHART PATH: /Users/ninja/mychart + +NAME: goodly-guppy +LAST DEPLOYED: Thu Dec 26 17:24:13 2019 +NAMESPACE: default +STATUS: pending-install +REVISION: 1 +TEST SUITE: None +USER-SUPPLIED VALUES: +{} + +COMPUTED VALUES: +affinity: {} +fullnameOverride: "" +image: + pullPolicy: IfNotPresent + repository: nginx +imagePullSecrets: [] +ingress: + annotations: {} + enabled: false + hosts: + - host: chart-example.local + paths: [] + tls: [] +nameOverride: "" +nodeSelector: {} +podSecurityContext: {} +replicaCount: 1 +resources: {} +securityContext: {} +service: + port: 80 + type: ClusterIP +serviceAccount: + create: true + name: null +tolerations: [] + +HOOKS: +MANIFEST: +--- +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: goodly-guppy-configmap +data: + myvalue: "Hello World" + +``` + +`--dry-run` 을 사용하면 코드를 쉽게 테스트할 수 있지만, +쿠버네티스가 당신이 만든 템플릿을 받아들일지는 확신할 수 없을 것이다. +`--dry-run` 이 작동됐다는 이유로 차트가 설치될 것이라고 생각하지 않는 것이 가장 좋다. + +[차트 템플릿 가이드](_index.md)에서는 여기서 정의한 기본 차트를 가지고 헬름 템플릿 언어를 자세히 살펴본다. +그럼 내장 객체부터 시작하자. diff --git a/content/ko/docs/chart_template_guide/helm_ignore_file.md b/content/ko/docs/chart_template_guide/helm_ignore_file.md new file mode 100644 index 0000000000..2394fa13d1 --- /dev/null +++ b/content/ko/docs/chart_template_guide/helm_ignore_file.md @@ -0,0 +1,29 @@ +--- +title: ".helmignore 파일" +description: "`.helmignore` 파일은 헬름 차트에 포함시키고 싶지 않은 파일들을 지정하는 데 사용한다." +weight: 12 +--- + +`.helmignore` 파일은 헬름 차트에 포함시키고 싶지 않은 파일들을 지정하는 데 사용한다. + +이 파일이 있으면, `helm package` 명령어는 애플리케이션을 패키징할 때 `.helmignore`에서 지정한 패턴에 매칭되는 모든 파일들을 무시할 것이다. + +이를 통해 불필요하거나 민감한 파일 또는 디렉토리들이 헬름 차트에 추가되는 것을 막을 수 있다. + +`.helmignore` 파일 + +`.helmignore` 파일은 유닉스 쉘 글롭(glob) 매칭, 상대 경로 매칭, 부정(negation, 접두어 ! 사용)을 지원한다. +한 줄에는 하나의 패턴만 있다는 것으로 취급된다. + +`.helmignore` 파일 예시는 다음과 같다. + +``` +# comment +.git +*/temp* +*/*/temp* +temp? +``` + +이 문서를 개선하기 위해 **당신의 도움을 필요합니다.** +정보를 추가, 수정, 삭제하려면, [이슈를 제기](https://github.com/helm/helm-www/issues)하거나 풀 리퀘스트를 보내주세요. diff --git a/content/ko/docs/chart_template_guide/named_templates.md b/content/ko/docs/chart_template_guide/named_templates.md new file mode 100644 index 0000000000..9574edc8f1 --- /dev/null +++ b/content/ko/docs/chart_template_guide/named_templates.md @@ -0,0 +1,329 @@ +--- +title: "지명 템플릿" +description: "지명 템플릿을 정의하는 방법" +weight: 8 +--- + +It is time to move beyond one template, and begin to create others. In this +section, we will see how to define _named templates_ in one file, and then use +them elsewhere. A _named template_ (sometimes called a _partial_ or a +_subtemplate_) is simply a template defined inside of a file, and given a name. +We'll see two ways to create them, and a few different ways to use them. + +In the [Flow Control](../control_structures) section we introduced three actions +for declaring and managing templates: `define`, `template`, and `block`. In this +section, we'll cover those three actions, and also introduce a special-purpose +`include` function that works similarly to the `template` action. + +An important detail to keep in mind when naming templates: **template names are +global**. If you declare two templates with the same name, whichever one is +loaded last will be the one used. Because templates in subcharts are compiled +together with top-level templates, you should be careful to name your templates +with _chart-specific names_. + +One popular naming convention is to prefix each defined template with the name +of the chart: `{{ define "mychart.labels" }}`. By using the specific chart name +as a prefix we can avoid any conflicts that may arise due to two different +charts that implement templates of the same name. + +This behavior also applies to different versions of a chart. If you have +`mychart` version `1.0.0` that defines a template one way, and a `mychart` +version `2.0.0` that modifies the existing named template, it will use the one +that was loaded last. You can work around this issue by also adding a version +in the name of the chart: `{{ define "mychart.v1.labels" }}` and +`{{ define "mychart.v2.labels" }}`. + +## 단편(partial)과 `_` 파일 + +So far, we've used one file, and that one file has contained a single template. +But Helm's template language allows you to create named embedded templates, that +can be accessed by name elsewhere. + +Before we get to the nuts-and-bolts of writing those templates, there is file +naming convention that deserves mention: + +* Most files in `templates/` are treated as if they contain Kubernetes manifests +* The `NOTES.txt` is one exception +* But files whose name begins with an underscore (`_`) are assumed to _not_ have + a manifest inside. These files are not rendered to Kubernetes object + definitions, but are available everywhere within other chart templates for + use. + +These files are used to store partials and helpers. In fact, when we first +created `mychart`, we saw a file called `_helpers.tpl`. That file is the default +location for template partials. + +## `define`과 `template`으로 템플릿을 선언하고 사용하기 + +The `define` action allows us to create a named template inside of a template +file. Its syntax goes like this: + +```yaml +{{ define "MY.NAME" }} + # body of template here +{{ end }} +``` + +For example, we can define a template to encapsulate a Kubernetes block of +labels: + +```yaml +{{- define "mychart.labels" }} + labels: + generator: helm + date: {{ now | htmlDate }} +{{- end }} +``` + +Now we can embed this template inside of our existing ConfigMap, and then +include it with the `template` action: + +```yaml +{{- define "mychart.labels" }} + labels: + generator: helm + date: {{ now | htmlDate }} +{{- end }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap + {{- template "mychart.labels" }} +data: + myvalue: "Hello World" + {{- range $key, $val := .Values.favorite }} + {{ $key }}: {{ $val | quote }} + {{- end }} +``` + +When the template engine reads this file, it will store away the reference to +`mychart.labels` until `template "mychart.labels"` is called. Then it will +render that template inline. So the result will look like this: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: running-panda-configmap + labels: + generator: helm + date: 2016-11-02 +data: + myvalue: "Hello World" + drink: "coffee" + food: "pizza" +``` + +Conventionally, Helm charts put these templates inside of a partials file, +usually `_helpers.tpl`. Let's move this function there: + +```yaml +{{/* Generate basic labels */}} +{{- define "mychart.labels" }} + labels: + generator: helm + date: {{ now | htmlDate }} +{{- end }} +``` + +By convention, `define` functions should have a simple documentation block +(`{{/* ... */}}`) describing what they do. + +Even though this definition is in `_helpers.tpl`, it can still be accessed in +`configmap.yaml`: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap + {{- template "mychart.labels" }} +data: + myvalue: "Hello World" + {{- range $key, $val := .Values.favorite }} + {{ $key }}: {{ $val | quote }} + {{- end }} +``` + +As mentioned above, **template names are global**. As a result of this, if two +templates are declared with the same name the last occurrence will be the one +that is used. Since templates in subcharts are compiled together with top-level +templates, it is best to name your templates with _chart specific names_. A +popular naming convention is to prefix each defined template with the name of +the chart: `{{ define "mychart.labels" }}`. + +## 템플릿의 스코프(scope) 지정하기 + +In the template we defined above, we did not use any objects. We just used +functions. Let's modify our defined template to include the chart name and chart +version: + +```yaml +{{/* Generate basic labels */}} +{{- define "mychart.labels" }} + labels: + generator: helm + date: {{ now | htmlDate }} + chart: {{ .Chart.Name }} + version: {{ .Chart.Version }} +{{- end }} +``` + +If we render this, the result will not be what we expect: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: moldy-jaguar-configmap + labels: + generator: helm + date: 2016-11-02 + chart: + version: +``` + +What happened to the name and version? They weren't in the scope for our defined +template. When a named template (created with `define`) is rendered, it will +receive the scope passed in by the `template` call. In our example, we included +the template like this: + +```yaml +{{- template "mychart.labels" }} +``` + +No scope was passed in, so within the template we cannot access anything in `.`. +This is easy enough to fix, though. We simply pass a scope to the template: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap + {{- template "mychart.labels" . }} +``` + +Note that we pass `.` at the end of the `template` call. We could just as easily +pass `.Values` or `.Values.favorite` or whatever scope we want. But what we want +is the top-level scope. + +Now when we execute this template with `helm install --dry-run --debug plinking-anaco ./mychart`, we get this: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: plinking-anaco-configmap + labels: + generator: helm + date: 2016-11-02 + chart: mychart + version: 0.1.0 +``` + +Now `{{ .Chart.Name }}` resolves to `mychart`, and `{{ .Chart.Version }}` +resolves to `0.1.0`. + +## `include` 함수 + +Say we've defined a simple template that looks like this: + +```yaml +{{- define "mychart.app" -}} +app_name: {{ .Chart.Name }} +app_version: "{{ .Chart.Version }}" +{{- end -}} +``` + +Now say I want to insert this both into the `labels:` section of my template, +and also the `data:` section: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap + labels: + {{ template "mychart.app" . }} +data: + myvalue: "Hello World" + {{- range $key, $val := .Values.favorite }} + {{ $key }}: {{ $val | quote }} + {{- end }} +{{ template "mychart.app" . }} +``` + +The output will not be what we expect: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: measly-whippet-configmap + labels: + app_name: mychart +app_version: "0.1.0+1478129847" +data: + myvalue: "Hello World" + drink: "coffee" + food: "pizza" + app_name: mychart +app_version: "0.1.0+1478129847" +``` + +Note that the indentation on `app_version` is wrong in both places. Why? Because +the template that is substituted in has the text aligned to the right. Because +`template` is an action, and not a function, there is no way to pass the output +of a `template` call to other functions; the data is simply inserted inline. + +To work around this case, Helm provides an alternative to `template` that will +import the contents of a template into the present pipeline where it can be +passed along to other functions in the pipeline. + +Here's the example above, corrected to use `indent` to indent the `mychart_app` +template correctly: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap + labels: +{{ include "mychart.app" . | indent 4 }} +data: + myvalue: "Hello World" + {{- range $key, $val := .Values.favorite }} + {{ $key }}: {{ $val | quote }} + {{- end }} +{{ include "mychart.app" . | indent 2 }} +``` + +Now the produced YAML is correctly indented for each section: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: edgy-mole-configmap + labels: + app_name: mychart + app_version: "0.1.0+1478129987" +data: + myvalue: "Hello World" + drink: "coffee" + food: "pizza" + app_name: mychart + app_version: "0.1.0+1478129987" +``` + +> It is considered preferable to use `include` over `template` in Helm templates +> simply so that the output formatting can be handled better for YAML documents. + +Sometimes we want to import content, but not as templates. That is, we want to +import files verbatim. We can achieve this by accessing files through the +`.Files` object described in the next section. diff --git a/content/ko/docs/chart_template_guide/notes_files.md b/content/ko/docs/chart_template_guide/notes_files.md new file mode 100644 index 0000000000..cc4811ab12 --- /dev/null +++ b/content/ko/docs/chart_template_guide/notes_files.md @@ -0,0 +1,57 @@ +--- +title: "NOTES.txt 파일 작성하기" +description: "차트 사용자에게 설명서를 제공하는 방법" +weight: 10 +--- + +이 섹션에서는 차트 사용자에게 지침을 제공하는 헬름의 도구들을 살펴본다. +`helm install` 이나 `helm upgrade` 가 끝나면, +헬름은 사용자에게 유용한 정보들을 출력할 수 있다. +이 정보는 템플릿을 사용하여 많은 부분을 커스터마이징할 수 있다. + +차트에 설치 메모를 추가하기 위해, 간단하게 `templates/NOTES.txt` +파일을 생성한다. 이 파일은 평범한 텍스트이지만, 템플릿처럼 처리되며 +모든 일반 템플릿 기능과 객체를 사용할 수 있다. + +간단히 `NOTES.txt` 파일을 생성한다. + +``` +Thank you for installing {{ .Chart.Name }}. + +Your release is named {{ .Release.Name }}. + +To learn more about the release, try: + + $ helm status {{ .Release.Name }} + $ helm get all {{ .Release.Name }} + +``` + +이제 `helm install rude-cardinal ./mychart` 를 실행하면 하단에 이런 메세지가 +표시된다. + +``` +RESOURCES: +==> v1/Secret +NAME TYPE DATA AGE +rude-cardinal-secret Opaque 1 0s + +==> v1/ConfigMap +NAME DATA AGE +rude-cardinal-configmap 3 0s + + +NOTES: +Thank you for installing mychart. + +Your release is named rude-cardinal. + +To learn more about the release, try: + + $ helm status rude-cardinal + $ helm get all rude-cardinal +``` + +이러한 방식으로 `NOTES.txt` 를 사용하면 새로 설치된 차트를 +사용하는 방법에 대한 자세한 정보를 사용자에게 제공할 수 있다. 필수는 아니지만, +`NOTES.txt` 파일 생성을 강력히 추천한다. diff --git a/content/ko/docs/chart_template_guide/subcharts_and_globals.md b/content/ko/docs/chart_template_guide/subcharts_and_globals.md new file mode 100644 index 0000000000..620e264a58 --- /dev/null +++ b/content/ko/docs/chart_template_guide/subcharts_and_globals.md @@ -0,0 +1,245 @@ +--- +title: "서브차트와 글로벌 값" +description: "서브차트 및 글로벌 값 사용하기" +weight: 11 +--- + +To this point we have been working only with one chart. But charts can have +dependencies, called _subcharts_, that also have their own values and templates. +In this section we will create a subchart and see the different ways we can +access values from within templates. + +Before we dive into the code, there are a few important details to learn about +subcharts. + +1. A subchart is considered "stand-alone", which means a subchart can never + explicitly depend on its parent chart. +2. For that reason, a subchart cannot access the values of its parent. +3. A parent chart can override values for subcharts. +4. Helm has a concept of _global values_ that can be accessed by all charts. + +As we walk through the examples in this section, many of these concepts will +become clearer. + +## 서브차트 작성 + +For these exercises, we'll start with the `mychart/` chart we created at the +beginning of this guide, and we'll add a new chart inside of it. + +```console +$ cd mychart/charts +$ helm create mysubchart +Creating mysubchart +$ rm -rf mysubchart/templates/*.* +``` + +Notice that just as before, we deleted all of the base templates so that we can +start from scratch. In this guide, we are focused on how templates work, not on +managing dependencies. But the [Charts Guide]({{< ref path="../topics/charts.md" lang="en" >}}) has more information +on how subcharts work. + +## 서브차트에 값과 템플릿 추가하기 + +Next, let's create a simple template and values file for our `mysubchart` chart. +There should already be a `values.yaml` in `mychart/charts/mysubchart`. We'll +set it up like this: + +```yaml +dessert: cake +``` + +Next, we'll create a new ConfigMap template in +`mychart/charts/mysubchart/templates/configmap.yaml`: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-cfgmap2 +data: + dessert: {{ .Values.dessert }} +``` + +Because every subchart is a _stand-alone chart_, we can test `mysubchart` on its +own: + +```console +$ helm install --dry-run --debug mychart/charts/mysubchart +SERVER: "localhost:44134" +CHART PATH: /Users/mattbutcher/Code/Go/src/helm.sh/helm/_scratch/mychart/charts/mysubchart +NAME: newbie-elk +TARGET NAMESPACE: default +CHART: mysubchart 0.1.0 +MANIFEST: +--- +# Source: mysubchart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: newbie-elk-cfgmap2 +data: + dessert: cake +``` + +## 부모 차트에서 값 오버라이드하기 + +Our original chart, `mychart` is now the _parent_ chart of `mysubchart`. This +relationship is based entirely on the fact that `mysubchart` is within +`mychart/charts`. + +Because `mychart` is a parent, we can specify configuration in `mychart` and +have that configuration pushed into `mysubchart`. For example, we can modify +`mychart/values.yaml` like this: + +```yaml +favorite: + drink: coffee + food: pizza +pizzaToppings: + - mushrooms + - cheese + - peppers + - onions + +mysubchart: + dessert: ice cream +``` + +Note the last two lines. Any directives inside of the `mysubchart` section will +be sent to the `mysubchart` chart. So if we run `helm install --dry-run --debug +mychart`, one of the things we will see is the `mysubchart` ConfigMap: + +```yaml +# Source: mychart/charts/mysubchart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: unhinged-bee-cfgmap2 +data: + dessert: ice cream +``` + +The value at the top level has now overridden the value of the subchart. + +There's an important detail to notice here. We didn't change the template of +`mychart/charts/mysubchart/templates/configmap.yaml` to point to +`.Values.mysubchart.dessert`. From that template's perspective, the value is +still located at `.Values.dessert`. As the template engine passes values along, +it sets the scope. So for the `mysubchart` templates, only values specifically +for `mysubchart` will be available in `.Values`. + +Sometimes, though, you do want certain values to be available to all of the +templates. This is accomplished using global chart values. + +## 글로벌 차트 값 + +Global values are values that can be accessed from any chart or subchart by +exactly the same name. Globals require explicit declaration. You can't use an +existing non-global as if it were a global. + +The Values data type has a reserved section called `Values.global` where global +values can be set. Let's set one in our `mychart/values.yaml` file. + +```yaml +favorite: + drink: coffee + food: pizza +pizzaToppings: + - mushrooms + - cheese + - peppers + - onions + +mysubchart: + dessert: ice cream + +global: + salad: caesar +``` + +Because of the way globals work, both `mychart/templates/configmap.yaml` and +`mysubchart/templates/configmap.yaml` should be able to access that value as +`{{ .Values.global.salad }}`. + +`mychart/templates/configmap.yaml`: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + salad: {{ .Values.global.salad }} +``` + +`mysubchart/templates/configmap.yaml`: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-cfgmap2 +data: + dessert: {{ .Values.dessert }} + salad: {{ .Values.global.salad }} +``` + +Now if we run a dry run install, we'll see the same value in both outputs: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: silly-snake-configmap +data: + salad: caesar + +--- +# Source: mychart/charts/mysubchart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: silly-snake-cfgmap2 +data: + dessert: ice cream + salad: caesar +``` + +Globals are useful for passing information like this, though it does take some +planning to make sure the right templates are configured to use globals. + +## 템플릿과 서브차트 공유하기 + +Parent charts and subcharts can share templates. Any defined block in any chart +is available to other charts. + +For example, we can define a simple template like this: + +```yaml +{{- define "labels" }}from: mychart{{ end }} +``` + +Recall how the labels on templates are _globally shared_. Thus, the `labels` +chart can be included from any other chart. + +While chart developers have a choice between `include` and `template`, one +advantage of using `include` is that `include` can dynamically reference +templates: + +```yaml +{{ include $mytemplate }} +``` + +The above will dereference `$mytemplate`. The `template` function, in contrast, +will only accept a string literal. + +## 블록 사용 피하기 + +The Go template language provides a `block` keyword that allows developers to +provide a default implementation which is overridden later. In Helm charts, +blocks are not the best tool for overriding because it if multiple +implementations of the same block are provided, the one selected is +unpredictable. + +The suggestion is to instead use `include`. diff --git a/content/ko/docs/chart_template_guide/values_files.md b/content/ko/docs/chart_template_guide/values_files.md new file mode 100644 index 0000000000..666e1f354e --- /dev/null +++ b/content/ko/docs/chart_template_guide/values_files.md @@ -0,0 +1,162 @@ +--- +title: "Values 파일" +description: "--values 플래그 사용법 설명" +weight: 4 +--- + +이전 섹션에서 우리는 헬름 템플릿에서 제공하는 빌트인 객체를 살펴봤다. 기본 객체 중 하나는 `Values`이다. 이 객체는 차트로 전달된 값에 접근할 수 있게 해준다. 이 객체의 내용들은 여러 출처에서 나온다: + +- 본 차트에 포함된 `values.yaml` 파일 +- 서브 차트의 경우, 부모 차트의 `values.yaml` 파일 +- `-f` 플래그 (`helm install -f myvals.yaml ./mychart`)가 있는 `helm install` 또는 `helm upgrade`로 전달된 `values.yaml` 파일 +- `--set` (such as `helm install --set foo=bar ./mychart`)과 함께 전달된 개별 매개변수 + +위 목록은 적용될 값의 순서이다: 기본 값인 `values.yaml`은 부모 차트의 `values.yaml`에 의해 재정의될 수 있고, 사용자가 제공한 `values.yaml` 파일에 의해 재정의될 수 있으며, `--set` 매개변수에 의해 재정의될 수 있다. + +Values 파일은 일반 YAML 파일이다. `mychart/values.yaml` 파일을 편집한 후 ConfigMap 템플릿을 편집해보자. + +`values.yaml`의 기본값을 제거하고, 다음 하나의 매개변수만 설정하자: + +```yaml +favoriteDrink: coffee +``` + +이제 템플릿 내부에서 다음과 같이 사용할 수 있다: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + drink: {{ .Values.favoriteDrink }} +``` + +마지막 줄에서 `Values`의 속성으로 `favoriteDrink`를 사용했다: +`{{ .Values.favoriteDrink }}`. + +적용된 결과를 확인해보자. + +```console +$ helm install geared-marsupi ./mychart --dry-run --debug +install.go:158: [debug] Original chart version: "" +install.go:175: [debug] CHART PATH: /home/bagratte/src/playground/mychart + +NAME: geared-marsupi +LAST DEPLOYED: Wed Feb 19 23:21:13 2020 +NAMESPACE: default +STATUS: pending-install +REVISION: 1 +TEST SUITE: None +USER-SUPPLIED VALUES: +{} + +COMPUTED VALUES: +favoriteDrink: coffee + +HOOKS: +MANIFEST: +--- +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: geared-marsupi-configmap +data: + myvalue: "Hello World" + drink: coffee +``` + +`favoriteDrink`가 기본 `values.yaml` 파일에서 `coffee`로 설정했기 때문에, 그 값이 템플릿에 표시되었다. 우리는 `helm install` 사용 시 `--set` 플래그를 추가하여 해당 값을 쉽게 재정의할 수 있다: + +```console +$ helm install solid-vulture ./mychart --dry-run --debug --set favoriteDrink=slurm +install.go:158: [debug] Original chart version: "" +install.go:175: [debug] CHART PATH: /home/bagratte/src/playground/mychart + +NAME: solid-vulture +LAST DEPLOYED: Wed Feb 19 23:25:54 2020 +NAMESPACE: default +STATUS: pending-install +REVISION: 1 +TEST SUITE: None +USER-SUPPLIED VALUES: +favoriteDrink: slurm + +COMPUTED VALUES: +favoriteDrink: slurm + +HOOKS: +MANIFEST: +--- +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: solid-vulture-configmap +data: + myvalue: "Hello World" + drink: slurm +``` + +`--set` 플래그는 기본 `values.yaml` 파일보다 높은 우선순위를 가지고 있으므로, 템플릿의 값이 `drink: slurm`으로 재정의되었다. + +Values 파일에는 구조화된 값들을 더 추가할 수 있다. 예를 들어, `values.yaml` 파일에 `favorite` 섹션을 추가한 다음 몇 가지 키를 더 추가할 수 있다: + +```yaml +favorite: + drink: coffee + food: pizza +``` + +이를 적용하기 위해 템플릿을 약간 수정해보자: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + drink: {{ .Values.favorite.drink }} + food: {{ .Values.favorite.food }} +``` + +이런 방식으로 중첩된 값을 사용할 수 있지만, 평면화(flat)한 값을 사용하여 트리 구조를 얕게 유지하는 것을 권장한다. 서브 차트에 값을 할당할 때, 트리 구조를 사용하여 값을 지정하는 방법을 알아보자. + +## 기본 키 삭제하기 + +기본 값에서 키를 삭제하는 경우, 삭제할 키의 값을 `null`로 지정할 수 있다. 이 경우 헬름은 재정의된 키를 제거할 것이다. + +예를 들어, Drupal 차트는 사용자 정의 이미지 사용하는 경우 활성 프로브를 구성할 수 있다. 기본 값은 다음과 같다: + +```yaml +livenessProbe: + httpGet: + path: /user/login + port: http + initialDelaySeconds: 120 +``` + +만약 활성 프로브를 `httpGet` 대신에 `exec`를 사용하여 `--set livenessProbe.exec.command=[cat,docroot/CHANGELOG.txt]`로 대체하고 싶다면, Helm은 기본 키와 재정의된 키를 함께 병합하여 다음과 같은 YAML을 생성할 것이다: + +```yaml +livenessProbe: + httpGet: + path: /user/login + port: http + exec: + command: + - cat + - docroot/CHANGELOG.txt + initialDelaySeconds: 120 +``` + +하지만, Kubernetes는 둘 이상의 활성 프로브 핸들러를 정의할 수 없기 때문에 실행에 실패한다. 이 문제를 해결하려면, `livenessProbe.httpGet`을 null로 설정하여 해당 키를 삭제해야 한다: + +```sh +helm install stable/drupal --set image=my-registry/drupal:0.1.0 --set livenessProbe.exec.command=[cat,docroot/CHANGELOG.txt] --set livenessProbe.httpGet=null +``` + +몇 가지의 빌트인 객체를 이용하여 템플릿에 값을 전달했다. 이제 템플릿 엔진의 함수와 파이프라인에 대해 알아보자. diff --git a/content/ko/docs/chart_template_guide/variables.md b/content/ko/docs/chart_template_guide/variables.md new file mode 100644 index 0000000000..4f67c2b3f2 --- /dev/null +++ b/content/ko/docs/chart_template_guide/variables.md @@ -0,0 +1,156 @@ +--- +title: "변수" +description: "템플릿에서 변수 사용하기" +weight: 7 +--- + +With functions, pipelines, objects, and control structures under our belts, we +can turn to one of the more basic ideas in many programming languages: +variables. In templates, they are less frequently used. But we will see how to +use them to simplify code, and to make better use of `with` and `range`. + +In an earlier example, we saw that this code will fail: + +```yaml + {{- with .Values.favorite }} + drink: {{ .drink | default "tea" | quote }} + food: {{ .food | upper | quote }} + release: {{ .Release.Name }} + {{- end }} +``` + +`Release.Name` is not inside of the scope that's restricted in the `with` block. +One way to work around scoping issues is to assign objects to variables that can +be accessed without respect to the present scope. + +In Helm templates, a variable is a named reference to another object. It follows +the form `$name`. Variables are assigned with a special assignment operator: +`:=`. We can rewrite the above to use a variable for `Release.Name`. + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + {{- $relname := .Release.Name -}} + {{- with .Values.favorite }} + drink: {{ .drink | default "tea" | quote }} + food: {{ .food | upper | quote }} + release: {{ $relname }} + {{- end }} +``` + +Notice that before we start the `with` block, we assign `$relname := +.Release.Name`. Now inside of the `with` block, the `$relname` variable still +points to the release name. + +Running that will produce this: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: viable-badger-configmap +data: + myvalue: "Hello World" + drink: "coffee" + food: "PIZZA" + release: viable-badger +``` + +Variables are particularly useful in `range` loops. They can be used on +list-like objects to capture both the index and the value: + +```yaml + toppings: |- + {{- range $index, $topping := .Values.pizzaToppings }} + {{ $index }}: {{ $topping }} + {{- end }} + +``` + +Note that `range` comes first, then the variables, then the assignment operator, +then the list. This will assign the integer index (starting from zero) to +`$index` and the value to `$topping`. Running it will produce: + +```yaml + toppings: |- + 0: mushrooms + 1: cheese + 2: peppers + 3: onions +``` + +For data structures that have both a key and a value, we can use `range` to get +both. For example, we can loop through `.Values.favorite` like this: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + {{- range $key, $val := .Values.favorite }} + {{ $key }}: {{ $val | quote }} + {{- end }} +``` + +Now on the first iteration, `$key` will be `drink` and `$val` will be `coffee`, +and on the second, `$key` will be `food` and `$val` will be `pizza`. Running the +above will generate this: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: eager-rabbit-configmap +data: + myvalue: "Hello World" + drink: "coffee" + food: "pizza" +``` + +Variables are normally not "global". They are scoped to the block in which they +are declared. Earlier, we assigned `$relname` in the top level of the template. +That variable will be in scope for the entire template. But in our last example, +`$key` and `$val` will only be in scope inside of the `{{ range... }}{{ end }}` +block. + +However, there is one variable that is always global - `$` - this variable will +always point to the root context. This can be very useful when you are looping +in a range need to know the chart's release name. + +An example illustrating this: +```yaml +{{- range .Values.tlsSecrets }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ .name }} + labels: + # Many helm templates would use `.` below, but that will not work, + # however `$` will work here + app.kubernetes.io/name: {{ template "fullname" $ }} + # I cannot reference .Chart.Name, but I can do $.Chart.Name + helm.sh/chart: "{{ $.Chart.Name }}-{{ $.Chart.Version }}" + app.kubernetes.io/instance: "{{ $.Release.Name }}" + # Value from appVersion in Chart.yaml + app.kubernetes.io/version: "{{ $.Chart.AppVersion }}" + app.kubernetes.io/managed-by: "{{ $.Release.Service }}" +type: kubernetes.io/tls +data: + tls.crt: {{ .certificate }} + tls.key: {{ .key }} +--- +{{- end }} +``` + +So far we have looked at just one template declared in just one file. But one of +the powerful features of the Helm template language is its ability to declare +multiple templates and use them together. We'll turn to that in the next +section. diff --git a/content/ko/docs/chart_template_guide/wrapping_up.md b/content/ko/docs/chart_template_guide/wrapping_up.md new file mode 100644 index 0000000000..d86a5b0a23 --- /dev/null +++ b/content/ko/docs/chart_template_guide/wrapping_up.md @@ -0,0 +1,29 @@ +--- +title: "다음 단계" +description: "마무리 - 도움이 되는 다른 유용한 문서들" +weight: 14 +--- + +본 가이드는 차트 개발자에게 헬름의 템플릿 언어를 사용하는 방법을 깊이 이해시키기 위한 것이다. +템플릿 개발의 기술적 관점이 중심이 된다. + +그러나 이 가이드에서도 실제 차트 개발에 필요한 많은 것들을 모두 다루지는 못했다. +새로운 차트를 작성할 때 도움이 되는 다른 유용한 문서들은 다음과 같다. + +- [Helm Charts project](https://github.com/helm/charts) is an indispensable source of charts. That project is also sets the standard for best practices in chart development. +- The Kubernetes [Documentation](https://kubernetes.io/docs/home/) provides detailed examples of the various resource kinds that you can use, from ConfigMaps and Secrets to DaemonSets and Deployments. +- The Helm [Charts Guide]({{< ref path="../topics/charts" lang="en" >}}) explains the workflow of using charts. +- The Helm [Chart Hooks Guide]({{< ref path="../topics/charts_hooks/" lang="en" >}}) explains how to create lifecycle hooks. +- The Helm [Charts Tips and Tricks]({{< ref path="../howto/charts_tips_and_tricks" lang="en" >}}) article provides some useful tips for writing charts. +- The [Sprig documentation](https://github.com/Masterminds/sprig) documents more than sixty of the template functions. +- The [Go template docs](https://godoc.org/text/template) explain the template syntax in detail. +- The [Schelm tool](https://github.com/databus23/schelm) is a nice helper utility for debugging charts. + +Sometimes it's easier to ask a few questions and get answers from experienced developers. The best place to do this is in the [Kubernetes Slack](https://kubernetes.slack.com) Helm channels: + +- [#helm-users](https://kubernetes.slack.com/messages/helm-users) +- [#helm-dev](https://kubernetes.slack.com/messages/helm-dev) +- [#charts](https://kubernetes.slack.com/messages/charts) + +마지막으로, 이 문서에서 오류나 누락을 찾았거나, +새로운 컨텐츠를 제안하거나 기여하고자 한다면, [헬름 프로젝트](https://github.com/helm/helm-www)를 방문하자. diff --git a/content/ko/docs/chart_template_guide/yaml_techniques.md b/content/ko/docs/chart_template_guide/yaml_techniques.md new file mode 100644 index 0000000000..105580e4cc --- /dev/null +++ b/content/ko/docs/chart_template_guide/yaml_techniques.md @@ -0,0 +1,355 @@ +--- +title: "부록: YAML 기법" +description: "YAML 명세와 그것이 헬름에 어떻게 적용되는지 자세히 알아보기" +weight: 15 +--- + +Most of this guide has been focused on writing the template language. Here, +we'll look at the YAML format. YAML has some useful features that we, as +template authors, can use to make our templates less error prone and easier to +read. + +## 스칼라(scalar)와 콜렉션(collection) + +According to the [YAML spec](https://yaml.org/spec/1.2/spec.html), there are two +types of collections, and many scalar types. + +The two types of collections are maps and sequences: + +```yaml +map: + one: 1 + two: 2 + three: 3 + +sequence: + - one + - two + - three +``` + +Scalar values are individual values (as opposed to collections) + +### YAML에서의 스칼라 자료형 + +In Helm's dialect of YAML, the scalar data type of a value is determined by a +complex set of rules, including the Kubernetes schema for resource definitions. +But when inferring types, the following rules tend to hold true. + +If an integer or float is an unquoted bare word, it is typically treated as a +numeric type: + +```yaml +count: 1 +size: 2.34 +``` + +But if they are quoted, they are treated as strings: + +```yaml +count: "1" # <-- string, not int +size: '2.34' # <-- string, not float +``` + +The same is true of booleans: + +```yaml +isGood: true # bool +answer: "true" # string +``` + +The word for an empty value is `null` (not `nil`). + +Note that `port: "80"` is valid YAML, and will pass through both the template +engine and the YAML parser, but will fail if Kubernetes expects `port` to be an +integer. + +In some cases, you can force a particular type inference using YAML node tags: + +```yaml +coffee: "yes, please" +age: !!str 21 +port: !!int "80" +``` + +In the above, `!!str` tells the parser that `age` is a string, even if it looks +like an int. And `port` is treated as an int, even though it is quoted. + + +## YAML에서의 문자열 + +Much of the data that we place in YAML documents are strings. YAML has more than +one way to represent a string. This section explains the ways and demonstrates +how to use some of them. + +There are three "inline" ways of declaring a string: + +```yaml +way1: bare words +way2: "double-quoted strings" +way3: 'single-quoted strings' +``` + +All inline styles must be on one line. + +- Bare words are unquoted, and are not escaped. For this reason, you have to be + careful what characters you use. +- Double-quoted strings can have specific characters escaped with `\`. For + example `"\"Hello\", she said"`. You can escape line breaks with `\n`. +- Single-quoted strings are "literal" strings, and do not use the `\` to escape + characters. The only escape sequence is `''`, which is decoded as a single + `'`. + +In addition to the one-line strings, you can declare multi-line strings: + +```yaml +coffee: | + Latte + Cappuccino + Espresso +``` + +The above will treat the value of `coffee` as a single string equivalent to +`Latte\nCappuccino\nEspresso\n`. + +Note that the first line after the `|` must be correctly indented. So we could +break the example above by doing this: + +```yaml +coffee: | + Latte + Cappuccino + Espresso + +``` + +Because `Latte` is incorrectly indented, we'd get an error like this: + +``` +Error parsing file: error converting YAML to JSON: yaml: line 7: did not find expected key +``` + +In templates, it is sometimes safer to put a fake "first line" of content in a +multi-line document just for protection from the above error: + +```yaml +coffee: | + # Commented first line + Latte + Cappuccino + Espresso + +``` + +Note that whatever that first line is, it will be preserved in the output of the +string. So if you are, for example, using this technique to inject a file's +contents into a ConfigMap, the comment should be of the type expected by +whatever is reading that entry. + +### 멀티라인 문자열에서 스페이스 처리 + +In the example above, we used `|` to indicate a multi-line string. But notice +that the content of our string was followed with a trailing `\n`. If we want the +YAML processor to strip off the trailing newline, we can add a `-` after the +`|`: + +```yaml +coffee: |- + Latte + Cappuccino + Espresso +``` + +Now the `coffee` value will be: `Latte\nCappuccino\nEspresso` (with no trailing +`\n`). + +Other times, we might want all trailing whitespace to be preserved. We can do +this with the `|+` notation: + +```yaml +coffee: |+ + Latte + Cappuccino + Espresso + + +another: value +``` + +Now the value of `coffee` will be `Latte\nCappuccino\nEspresso\n\n\n`. + +Indentation inside of a text block is preserved, and results in the preservation +of line breaks, too: + +```yaml +coffee: |- + Latte + 12 oz + 16 oz + Cappuccino + Espresso +``` + +In the above case, `coffee` will be `Latte\n 12 oz\n 16 +oz\nCappuccino\nEspresso`. + +### 들여쓰기와 템플릿 + +When writing templates, you may find yourself wanting to inject the contents of +a file into the template. As we saw in previous chapters, there are two ways of +doing this: + +- Use `{{ .Files.Get "FILENAME" }}` to get the contents of a file in the chart. +- Use `{{ include "TEMPLATE" . }}` to render a template and then place its + contents into the chart. + +When inserting files into YAML, it's good to understand the multi-line rules +above. Often times, the easiest way to insert a static file is to do something +like this: + +```yaml +myfile: | +{{ .Files.Get "myfile.txt" | indent 2 }} +``` + +Note how we do the indentation above: `indent 2` tells the template engine to +indent every line in "myfile.txt" with two spaces. Note that we do not indent +that template line. That's because if we did, the file content of the first line +would be indented twice. + +### 접힌 멀티라인 문자열 + +Sometimes you want to represent a string in your YAML with multiple lines, but +want it to be treated as one long line when it is interpreted. This is called +"folding". To declare a folded block, use `>` instead of `|`: + +```yaml +coffee: > + Latte + Cappuccino + Espresso + + +``` + +The value of `coffee` above will be `Latte Cappuccino Espresso\n`. Note that all +but the last line feed will be converted to spaces. You can combine the +whitespace controls with the folded text marker, so `>-` will replace or trim +all newlines. + +Note that in the folded syntax, indenting text will cause lines to be preserved. + +```yaml +coffee: >- + Latte + 12 oz + 16 oz + Cappuccino + Espresso +``` + +The above will produce `Latte\n 12 oz\n 16 oz\nCappuccino Espresso`. Note that +both the spacing and the newlines are still there. + +## 하나의 파일에 여러 문서 넣기 + +It is possible to place more than one YAML documents into a single file. This is +done by prefixing a new document with `---` and ending the document with +`...` + +```yaml + +--- +document:1 +... +--- +document: 2 +... +``` + +In many cases, either the `---` or the `...` may be omitted. + +Some files in Helm cannot contain more than one doc. If, for example, more than +one document is provided inside of a `values.yaml` file, only the first will be +used. + +Template files, however, may have more than one document. When this happens, the +file (and all of its documents) is treated as one object during template +rendering. But then the resulting YAML is split into multiple documents before +it is fed to Kubernetes. + +We recommend only using multiple documents per file when it is absolutely +necessary. Having multiple documents in a file can be difficult to debug. + +## YAML은 JSON의 상위집합이다 + +Because YAML is a superset of JSON, any valid JSON document _should_ be valid +YAML. + +```json +{ + "coffee": "yes, please", + "coffees": [ + "Latte", "Cappuccino", "Espresso" + ] +} +``` + +The above is another way of representing this: + +```yaml +coffee: yes, please +coffees: +- Latte +- Cappuccino +- Espresso +``` + +And the two can be mixed (with care): + +```yaml +coffee: "yes, please" +coffees: [ "Latte", "Cappuccino", "Espresso"] +``` + +All three of these should parse into the same internal representation. + +While this means that files such as `values.yaml` may contain JSON data, Helm +does not treat the file extension `.json` as a valid suffix. + +## YAML 앵커(anchor) + +The YAML spec provides a way to store a reference to a value, and later refer to +that value by reference. YAML refers to this as "anchoring": + +```yaml +coffee: "yes, please" +favorite: &favoriteCoffee "Cappuccino" +coffees: + - Latte + - *favoriteCoffee + - Espresso +``` + +In the above, `&favoriteCoffee` sets a reference to `Cappuccino`. Later, that +reference is used as `*favoriteCoffee`. So `coffees` becomes `Latte, Cappuccino, +Espresso`. + +While there are a few cases where anchors are useful, there is one aspect of +them that can cause subtle bugs: The first time the YAML is consumed, the +reference is expanded and then discarded. + +So if we were to decode and then re-encode the example above, the resulting YAML +would be: + +```yaml +coffee: yes, please +favorite: Cappuccino +coffees: +- Latte +- Cappuccino +- Espresso +``` + +Because Helm and Kubernetes often read, modify, and then rewrite YAML files, the +anchors will be lost. diff --git a/content/ko/docs/community/_index.md b/content/ko/docs/community/_index.md new file mode 100644 index 0000000000..5556d27ecf --- /dev/null +++ b/content/ko/docs/community/_index.md @@ -0,0 +1,8 @@ +--- +title: "커뮤니티" +weight: 7 +--- + +# 커뮤니티 가이드 + +여기서 헬름 프로젝트 자체에 관한 개발 과정과 기여하는 방법을 알아보세요. diff --git a/content/ko/docs/community/developers.md b/content/ko/docs/community/developers.md new file mode 100644 index 0000000000..ac4ff1a78b --- /dev/null +++ b/content/ko/docs/community/developers.md @@ -0,0 +1,138 @@ +--- +title: "개발자 가이드" +description: "헬름을 개발하는 사용자의 환경을 구성하기 위한 지침" +weight: 1 +--- + +이 가이드에서는 헬름을 개발하기 위해 환경을 설정하는 방법을 설명한다. + +## 전제 조건 + +- Go 최신버전 +- kubectl 을 쓸 수 있는 쿠버네티스 클러스터 (선택사항) +- Git + +## 헬름 빌드하기 + +프로그램을 빌드하기 위해 Make를 사용한다. 시작하는 가장 간단한 방법은 다음과 같다. + +```console +$ make +``` + +유의사항: `$ GOPATH / src / helm.sh / helm` 경로에서 실행하지 않으면 실패하게 된다. +`helm.sh` 디렉토리는 심볼릭 링크가 아니어야 한다. +심볼릭 링크이면 `build`가 관련 패키지를 찾지 못한다. + +필요한 경우 먼저 의존성을 설치하고 `vendor/` 트리를 +다시 빌드하고 구성을 확인한다. 그런 다음 `helm` 을 컴파일하여 +`bin/helm` 로 옮긴다. + +(`vendor/` 에 대한 테스트는 실행하지 않고) 모든 테스트를 실행하려면 `make test` 를 실행한다. + +헬름을 로컬에서 실행하려면 `bin/helm` 을 실행한다. + +- 헬름은 맥OS 및 Alpine을 포함한 대부분의 리눅스 배포판에서 실행되는 것으로 알려져 있다. + +## 기여 가이드라인 + +우리는 기여를 환영한다. 이 프로젝트는 (a) 코드 품질이 높게 유지되고, +(b) 프로젝트가 일관되게 유지되고, (c) 기여가 오픈 소스 법적 요건을 +따르기 위해 몇 가지 지침을 설정했다. 우리의 의도는 기여자에게 +부담을 주는 것이 아니라 사용자가 혜택을 받을 수 있도록 우아하고 +고품질의 오픈 소스 코드를 만드는 것이다. + +가장 중심이라 할 수 있는 기여(CONTRIBUTING) 가이드를 읽고 숙지하자. + +https://github.com/helm/helm/blob/main/CONTRIBUTING.md + +### 코드의 구조 + +Helm 프로젝트의 코드는 다음과 같이 구성된다. + +- 개별 프로그램은 `cmd/`에 위치한다. + `cmd/` 내부의 코드는 라이브러리 재사용을 위해 설계되지는 않았다. +- 공유 라이브러리는 `pkg/` 에 저장된다. +- `scripts/` 디렉토리에는 여러 유틸리티 스크립트가 들어 있다. + 대부분 CI/CD 파이프라인에서 사용한다. + +Go 의존성 관리는 유동적이며 Helm의 수명주기 동안 +변경될 수 있다. 개발자는 의존성을 수동으로 관리하지 +_않기를_ 권장한다. 대신 프로젝트의 `Makefile` 에 +의존하여 이를 수행하는 것이 좋다. Helm 3에서는 +Go 버전 1.13 이상을 사용하는 것이 좋다. + +### 문서 작성하기 + +Helm 3 이후의 문서는 자체 저장소로 이동되었다. +새로운 기능을 작성할 때 함께 제공되는 문서를 작성하여 +[helm-www] (https://github.com/helm/helm-www) 레포지터리에 제출하자. + +### Git 관례 + +버전 제어 시스템으로는 Git을 사용한다. `main` 브랜치는 현재 개발 +예정 브랜치의 홈 브랜치이다. 릴리스는 태그가 지정되며. + +GitHub PR (Pull Requests)을 통한 코드 변경을 허용한다. +이를 위한 작업 흐름은 다음과 같다. + +1. `$GOPATH/src` 디렉토리로 이동한 후에, `mkdir helm.sh; cd helm.sh` 을 수행하고, + `git clone` 으로 `github.com/helm/helm` 레포지터리를 복제한다. +2. 해당 레포지터리를 GitHub 계정으로 포크한다. +3. 레포지터리를 `$GOPATH/src/helm.sh/helm` 에 대한 원격 레포지터리로 추가한다. +4. 새로운 작업 브랜치를 만들고(`git checkout -b feat/my-feature`) 해당 브랜치에서 + 작업을 수행한다. +5. 리뷰를 위한 준비가 되면 브랜치를 GitHub으로 푸시한 다음 + 새로운 풀 리퀘스트를 생성한다. + +Git 커밋 메세지의 경우, 우리는 [유의적 커밋 메세지](https://karma-runner.github.io/0.13/dev/git-commit-msg.html)를 +따른다. + +``` +fix(helm): add --foo flag to 'helm install' + +When 'helm install --foo bar' is run, this will print "foo" in the +output regardless of the outcome of the installation. + +Closes #1234 +``` + +일반적인 커밋 유형: + +- fix: 버그 또는 오류 수정 +- feat: 새로운 기능 추가 +- docs: 문서 변경 +- test: 테스트 개선 +- ref: 기존 코드 리팩터링 + +일반적인 범위: + +- helm: 헬름 CLI +- pkg/lint: 린트(lint) 패키지. 어떤 패키지든 유사한 관례에 따르자. +- `*`: 두 개 이상의 스코프 + +더 읽어보기: +- 이 섹션은 [Deis + 가이드라인](https://github.com/deis/workflow/blob/master/src/contributing/submitting-a-pull-request.md)에서 영감을 받아 작성되었다. +- Karma Runner는 유의적 커밋 메세지에 대한 아이디어를 + [정의](https://karma-runner.github.io/0.13/dev/git-commit-msg.html) + 한다. + +### Go 관례 + +우리는 Go 코딩 스타일 표준을 매우 밀접하게 따른다. 일반적으로 `go fmt` 를 실행하여 +사용자의 코드를 더욱 아름답게 만들수 있다. + +또한 일반적으로 `go lint` 및 `gometalinter` 에서 권장하는 규칙을 따른다. +스타일 적합성을 테스트하려는 경우 `make test-style` 을 실행하자. + +더 읽어보기: + +- Effective Go [포맷 + 소개](https://golang.org/doc/effective_go.html#formatting). +- Go 위키에서 볼 수 있는 훌륭한 + [포맷](https://github.com/golang/go/wiki/CodeReviewComments) 글 + +`make test` 타겟을 실행하면 단위 테스트뿐만 아니라 스타일 테스트도 실행된다. +`make test` 대상이 스타일 상의 이유로 실패하면 PR 은 병합할 준비가 +되지 않은 것으로 간주한다. diff --git a/content/ko/docs/community/history.md b/content/ko/docs/community/history.md new file mode 100644 index 0000000000..f1d7b968b8 --- /dev/null +++ b/content/ko/docs/community/history.md @@ -0,0 +1,24 @@ +--- +title: "프로젝트 연혁" +description: "프로젝트의 연혁에 대한 개요를 설명한다." +weight: 4 +--- + +헬름 3는 [인큐베이션(incubation) 최종단계](https://github.com/cncf/toc/blob/main/process/graduation_criteria.adoc)에 있는 [CNCF 프로젝트](https://www.cncf.io/projects/)이다. + +헬름은, 2015년에 시작되어 KubeCon에서 소개된 바 있는 [헬름 클래식](https://github.com/helm/helm-classic)이라 하는 멋진 프로젝트에서 시작되었다. + +2016년 1월, 프로젝트는 쿠버네티스 디플로이먼트 매니저라고 불리는 GCS 도구로 병합되며, [쿠버네티스](https://kubernetes.io) 산하로 옮겨갔다. +코드베이스 병합의 결과로, 그 이듬해 헬름 2.0이 릴리스되었다. +디플로이먼트 매니저(Deployment Manager)의 핵심기능은 헬름 2로 이어져, 최종 헬름 2.0 릴리스에서 틸러(Tiller)라고 명명된 서버측 컴포넌트가 되었다. + +2018년 6월에 헬름은 쿠버네티스의 서브프로젝트에서 본격적인 CNCF 프로젝트로 승격되었다. +헬름은 최상위 관리조직을 구성하고 헬름 프로젝트 산하로 여러 프로젝트들을 포괄하였는데, +모노큘러(Monocular), 헬름 차트 저장소(Helm Chart Repo), 차트 뮤지엄(Chart Museum), 나중에 헬름 허브(Helm Hub)를 포함하였다. + +헬름 3 개발 사이클이 시작되면서, 틸러(Tiller)가 제거되고, 클라이언트 도구로서의 본래의 지향점에 더 가까워졌다. +그러면서도 헬름 3는 쿠버네티스 클러스터 내부의 릴리스 추적을 계속하여, +팀에서 공동의 헬름 릴리스 세트를 함께 다룰 수 있게 해준다. + +헬름 3는 2019년 11월에 릴리스되었다. + diff --git a/content/ko/docs/community/localization.md b/content/ko/docs/community/localization.md new file mode 100644 index 0000000000..930ea89b42 --- /dev/null +++ b/content/ko/docs/community/localization.md @@ -0,0 +1,164 @@ +--- +title: "헬름 문서 현지화" +description: "헬름 문서 현지화를 위한 설명서" +weight: 5 +--- + +이 가이드에서는 헬름 문서를 현지화하는 방법에 대해 설명한다. + +## 시작하기 + +번역 기여는 문서 기여와 동일한 과정을 거친다. +번역본은 [풀 +리퀘스트](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests) +를 통해 [helm-www](https://github.com/helm/helm-www) 깃 저장소에 제공되며 풀 리퀘스트는 +웹사이트를 관리하는 팀이 검토한다. + +### 두 글자 언어 코드 + +문서는 언어 코드를 [ISO 639-1 +표준](https://www.loc.gov/standards/iso639-2/php/code_list.php)으로 구성한다. +예를 들어, 한국어의 두 글자 코드는 `ko` 이다. + +내용 및 설정에서 사용 중인 언어 코드를 찾을 수 있다. +세 가지 예: + +- `content` 디렉토리에 언어 코드가 하위 디렉토리로 있고 + 각 디렉토리마다 번역된 콘텐츠가 있는데, + 주로 `docs` 하위 디렉토리에 있다. +- `i18n` 디렉토리에는 웹사이트에서 사용하는 문구가 포함된 + 각 언어에 대한 설정 파일이 있다. + 파일 이름은 `[LANG].toml` 로 지정되며, 여기서 `[LANG]` 은 두 글자 언어 코드다. +- 프로젝트 최상위에 위치한 `config.toml` 파일에는 언어 코드별로 구성된 네비게이션 및 + 기타 세부 사항에 대한 설정 정보가 있다. + +언어 코드가 `en` 인 영어는, +번역을 위한 기본 언어이자 원본이다. + +### 포크, 브랜치, 변경, 풀 리퀘스트 + +번역본을 기여하려면 먼저 깃헙에 [helm-www 저장소](https://github.com/helm/helm-www)의 +[포크를 만드는 것](https://help.github.com/en/github/getting-started-with-github/fork-a-repo)부터 +시작한다. +사용자는 자신의 포크를 커밋함으로써 시작하게 된다. + +기본적으로 포크는 master라는 기본 브랜치에서 동작하도록 설정된다. +변경 사항을 개발하고 풀 리퀘스트를 생성하기 위해 브랜치를 사용하자. 브랜치가 익숙하지 않다면 +[깃헙 문서를 +읽어볼 수 있다](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-branches). + +브랜치가 있다면 번역을 추가하고 내용을 +현지화하자. + +참고로 헬름은 [원본 개발자 증명서](https://developercertificate.org/)를 사용한다. +모든 커밋은 서명이 필요하다. +커밋을 생성할 때, 깃에 설정된 이름과 이메일 주소로 서명하기 위해 +`-s` 또는 `--signoff` 플래그를 쓸 수 있다. +자세한 내용은 +[CONTRIBUTING.md](https://github.com/helm/helm-www/blob/main/CONTRIBUTING.md#sign-your-work)에서 +확인할 수 있다. + +준비되면 번역본과 함께 다시 helm-www 저장소로 [풀 +리퀘스트](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests)를 +생성하자. + +풀 리퀘스트를 생성하면 관리자 중 한 명이 검토할 것이다. +그 과정에 대한 세부사항은 +[CONTRIBUTING.md](https://github.com/helm/helm-www/blob/main/CONTRIBUTING.md)에 +있다. + +## 콘텐츠 번역하기 + +헬름의 모든 내용을 현지화하는 것은 상당한 작업이다. +작은 부분부터 시작해도 괜찮다. 이 후에 더 번역할 수 있다. + +### 새로운 언어 등록하기 + +새로운 언어를 등록할 때 필요한 최소 요건이 있다. 여기에는 다음이 포함된다: + +- `index.md` 파일이 들어 있는 `content/[LANG]/docs` 디렉토리 추가. + 이것은 최상위 문서 랜딩 페이지다. +- `i18n` 디렉토리에 `[LANG].toml` 파일 생성. + `en.toml` 파일을 복사해서 시작할 수 있다. +- 새로운 언어를 서비스하기 위해 `config.toml` 파일에 해당 언어 섹션 추가. + 기존 언어 섹션을 써서 등록할 수도 있다. + +### 번역하기 + +번역된 콘텐츠는 `content/[LANG]/docs` 디렉토리에 있어야 한다. 이것은 영어 원문과 동일한 URL을 +가져야 한다. 예를 들어, 소개 부분을 한국어로 번역하려면 다음과 같이 영어 원문을 복사하는 것이 +유용할 수 있다: + +```sh +mkdir -p content/ko/docs/intro +cp content/en/docs/intro/install.md content/ko/docs/intro/install.md +``` + +그러면 새 파일의 내용을 다른 언어로 번역할 수 있다. + +영문 파일의 번역되지 않은 사본을 `content/[LANG]/` 에 추가하지 않도록 한다. +사이트에 해당 언어가 존재하면 번역되지 않은 페이지는 자동으로 영문 페이지로 리다이렉션된다. +번역에는 시간이 필요하고, +사용자들은 오래된 버전의 포크가 아닌 최신 버전의 문서를 번역하길 원한다. + +헤더 섹션에서 `aliases` 행을 반드시 제거하자. +`aliases: ["/docs/using_helm/"]` 과 같은 행은 번역에 속하지 않는다. +이것은 새로운 페이지 링크로 인해 없어진 링크에 대한 리다이렉션이다. + +참고로 번역 도구는 이 과정에 도움을 줄 수 있다. +여기에는 번역기로 생성한 번역도 포함된다. +번역기로 생성한 번역은 내보내기 전에 +원어민이 문법과 의미를 편집하거나 검토해야 한다. + + +## 언어 변경 + +![Screen Shot 2020-05-11 at 11 24 22 +AM](https://user-images.githubusercontent.com/686194/81597103-035de600-937a-11ea-9834-cd9dcef4e914.png) + +사이트 전역 [config.toml](https://github.com/helm/helm-www/blob/main/config.toml#L83L89) +파일에서 언어 변경을 구성한다. + +새로운 언어를 추가하려면 위에서 정의한 [두 글자 +언어 코드](./localization/#두-글자-언어-코드)를 사용하여 새로운 매개 변수 집합을 +추가하자. 예: + +``` +# Korean +[languages.ko] +title = "Helm" +description = "Helm - The Kubernetes Package Manager." +contentDir = "content/ko" +languageName = "한국어 Korean" +weight = 1 +``` + +## 내부 링크 결정하기 + +번역된 콘텐츠는 간혹 번역되지 않은 페이지에 대한 링크를 포함한다. 이로 인해 사이트 [빌드 +오류](https://app.netlify.com/sites/helm-merge/deploys)가 발생할 수 있다. +예: + +``` +12:45:31 PM: htmltest started at 12:45:30 on app +12:45:31 PM: ======================================================================== +12:45:31 PM: ko/docs/chart_template_guide/accessing_files/index.html +12:45:31 PM: hash does not exist --- ko/docs/chart_template_guide/accessing_files/index.html --> #basic-example +12:45:31 PM: ✘✘✘ failed in 197.566561ms +12:45:31 PM: 1 error in 212 documents +``` + +이 문제를 해결하려면 콘텐츠에서 내부 링크를 확인해야 한다. + +* 앵커 링크는 번역된 `id` 값을 반영해야 한다. +* 내부 페이지 링크를 고쳐야 한다. + +존재하지 않는 _(혹은 아직 번역되지 않은)_ 내부 페이지가 있을 경우, +교정될 때까지 사이트가 빌드되지 않는다. +그 대신 URL은 다음과 같이 해당 콘텐츠가 _존재하는_ 다른 언어를 가리킬 수 있다. + +`< relref path="/docs/topics/library_charts.md" lang="en" >` + +자세한 내용은 [언어 간 상호 참조에 대한 휴고(Hugo) +문서](https://gohugo.io/content-management/cross-references/#link-to-another-language-version) +를 참조하자. diff --git a/content/ko/docs/community/related.md b/content/ko/docs/community/related.md new file mode 100644 index 0000000000..73bb9546ba --- /dev/null +++ b/content/ko/docs/community/related.md @@ -0,0 +1,92 @@ +--- +title: "관련 프로젝트와 문서" +description: "커뮤니티에서 제공하는 서드파티 도구, 플러그인 및 문서" +weight: 3 +--- + +헬름 커뮤니티는 헬름에 대한 많은 추가 도구, 플러그인 및 문서를 만들었습니다. 우리는 +이러한 프로젝트에 대해 듣고 싶습니다. + +이 목록에 추가하고 싶은 것이 있으면 +[이슈](https://github.com/helm/helm-www/issues)나 [풀 +리퀘스트(PR)](https://github.com/helm/helm-www/pulls) 할 수 있습니다. + +## 헬름 플러그인 + +- [Helm Diff](https://github.com/databus23/helm-diff) - 컬러 diff로 `helm upgrade` + 미리보기 +- [helm-gcs](https://github.com/hayorov/helm-gcs) - Google Cloud Storage에서 + 저장소를 관리하는 플러그인 +- [helm-monitor](https://github.com/ContainerSolutions/helm-monitor) - 프로메테우스/엘라스틱서치 쿼리를 기반으로 + 릴리스 및 롤백을 모니터링하는 플러그인 +- [helm-k8comp](https://github.com/cststack/k8comp) - k8comp 를 사용하여 hiera 에서 + 헬름 차트를 생성하는 플러그인 +- [helm-unittest](https://github.com/lrills/helm-unittest) - YAML로 + 로컬에서 차트를 단위 테스트하기 위한 플러그인 +- [hc-unit](https://github.com/xchapter7x/hcunit) - OPA (Open Policy Agent) 및 Rego로 + 로컬에서 차트를 단위 테스트하기 위한 플러그인 +- [helm-s3](https://github.com/hypnoglow/helm-s3) - [프라이빗] 차트 저장소로 AWS S3를 + 사용할 수 있게 해주는 헬름 플러그인 +- [helm-schema-gen](https://github.com/karuppiah7890/helm-schema-gen) - 헬름 3 차트에 대한 + 값(values) yaml 스키마를 생성하는 헬름 플러그인 +- [helm-secrets](https://github.com/jkroepke/helm-secrets) - 비밀정보를 안전하게 관리하고 + 보관하기 위한 플러그인 ([sops](https://github.com/mozilla/sops) 기반) + +GitHub 작성자가 플러그인 저장소에 +[helm-plugin](https://github.com/search?q=topic%3Ahelm-plugin&type=Repositories) 태그를 +사용할 것을 권장한다. + +## 추가적인 도구들 + +헬름의 상위 계층 도구들. + +- [Chartify](https://github.com/appscode/chartify) - 기존 쿠버네티스 리소스에서 + 헬름 차트를 생성 +- [VIM-Kubernetes](https://github.com/andrewstuart/vim-kubernetes) - 쿠버네티스 및 헬름용(用) + VIM 플러그인 +- [Landscaper](https://github.com/Eneco/landscaper/) - "Landscaper 는 값(원하는 상태)을 가진 + 헬름 차트 참조 집합을 가져와서 + 쿠버네티스 클러스터에서 실현한다." +- [Helmfile](https://github.com/helmfile/helmfile) - Helmfile은 헬름 차트 배포를 + 위한 선언적 사양이다 +- [Helmsman](https://github.com/Praqma/helmsman) - Helmsman은 + 버전 관리되는 원하는 상태 파일들(간단한 TOML 형식으로 기술됨)로부터 + 릴리스를 설치/업그레이드/보호/이동/삭제할 수 있는 + 코드로서의-헬름-차트(helm-charts-as-code) 도구이다 +- [Terraform Helm Provider](https://github.com/hashicorp/terraform-provider-helm) - HashiCorp + Terraform용 헬름 공급자(provider)는 선언적 코드형 인프라(infrastructure-as-code) 구문으로 + 헬름 차트의 수명주기를 관리할 수 있게 해준다. 헬름 공급자는 쿠버네티스 공급자처럼, + 모든 인프라 서비스에서 통용되는 워크플로를 만들기 위해, 다른 테라폼 공급자와 + 쌍을 이루는 경우가 많다. +- [Monocular](https://github.com/helm/monocular) - 헬름 차트 저장소를 + 위한 웹 UI +- [Armada](https://airshipit.readthedocs.io/projects/armada/en/latest/) - 여러 + 쿠버네티스 네임스페이스에 걸쳐 접두어가 붙은 릴리스들을 관리하며, + 복잡한 배포에서의 완료된 작업들을 제거한다 +- [ChartMuseum](https://github.com/helm/chartmuseum) - Amazon S3와 + Google Cloud Storage를 지원하는 헬름 차트 저장소 +- [Codefresh](https://codefresh.io) - 헬름 차트 및 릴리스를 관리하기 위한 + UI 대시보드가 있는 쿠버네티스 네이티브 CI/CD 및 관리 플랫폼 +- [Captain](https://github.com/alauda/captain) - HelmRequest 및 + 릴리스 CRD를 사용하는 Helm3 컨트롤러 +- [chart-registry](https://github.com/hangyan/chart-registry) - OCI 저장소 상의 + 헬름 차트 호스트 +- [avionix](https://github.com/zbrookle/avionix) - 상속과 코드중복 저감을 할 수 있는 + 헬름 차트와 쿠버네티스 yaml 을 생성하는 파이썬 인터페이스. + +## 헬름 지원 + +헬름 지원을 포함하는 플랫폼, 배포판 및 서비스. + +- [Kubernetic](https://kubernetic.com/) - 쿠버네티스 데스크탑 클라이언트 +- [Jenkins X](https://jenkins-x.io/) - GitOps 환경을 통해 애플리케이션을 + [프로모션(promotion)](https://jenkins-x.io/docs/getting-started/promotion/)하기 위해 + 헬름을 사용하는 쿠버네티스용 오픈소스 자동화 CI/CD + +## 기타 + +차트 작성자와 헬름 사용자에게 유용한 것 모음. + +- [Await](https://github.com/saltside/await) - 다른 조건들에 대해 "대기(await)"하는 + 도커 이미지--특히 초기화 컨테이너에 유용하다. [더 + 보기](https://blog.slashdeploy.com/2017/02/16/introducing-await/) diff --git a/content/ko/docs/community/release_checklist.md b/content/ko/docs/community/release_checklist.md new file mode 100644 index 0000000000..ae209a807a --- /dev/null +++ b/content/ko/docs/community/release_checklist.md @@ -0,0 +1,491 @@ +--- +title: "릴리스 체크리스트" +description: "다음 버전의 헬름을 출시할 때 유지관리자를 위한 체크리스트" +weight: 2 +--- + +# 헬름 릴리스에 대한 유지관리자 가이드 + +새로운 헬름을 출시할 시간이다! 릴리스를 끊는 헬름 유지관리자로서, +자신의 경험이 여기에 문서화된 내용과 다른 점이 있다면 +[이 릴리스 체크리스트를 업데이트](https://github.com/helm/helm-www/blob/main/content/ko/docs/community/release_checklist.md)하기에 +딱 맞는 사람이다. + +모든 릴리스는 vX.Y.Z 형식이다. +여기서 X는 주 버전 번호, Y는 부 버전 번호, Z는 패치 릴리스 번호이다. +이 프로젝트는 [유의적 버전 관리] (https://semver.org/)를 엄격히 따르므로 +이 단계를 따르는 것이 매우 중요하다. + +헬름은 다음 마이너 릴리스 날짜를 미리 발표한다. +발표된 날짜를 지키기 위해 최선을 다해야 한다. +또한 릴리스 프로세스를 시작할 때, 다음 릴리스 날짜를 선택해야 하며 +릴리스 프로세스의 일환이다. + +이 지침은 초기 구성에 이어 세 가지 +다른 종류의 릴리스에 대한 릴리스 절차를 다룬다. + +* 주 릴리스 - 상대적으로 낮은 빈도로 릴리스 - 주요 변경 사항이 있음 +* 부 릴리스 - 3~4개월마다 릴리스 - 주요 변경 사항 없음 +* 패치 릴리스 - 매월 릴리스 - 이 가이드의 모든 단계가 불필요 + +[초기 구성](#초기-구성) + +1. [릴리스 브랜치 생성](#1-릴리스-브랜치-생성) +2. [주 또는 부 릴리스: git에서 버전 번호 변경](#2-git에서-주-또는-부-버전-번호-변경) +3. [주/부 릴리스: 릴리스 브랜치 커밋 및 푸시](#3-주부-릴리스-릴리스-브랜치-커밋-및-푸시) +4. [주/부 릴리스: 릴리스 후보 생성](#4-주부-릴리스-릴리스-후보-생성) +5. [주/부 릴리스: 연속 릴리스 후보 개선](#5-주부-릴리스-연속-릴리스-후보-개선) +6. [릴리스 확정](#6-릴리스-확정) +7. [릴리스 노트 작성](#7-릴리스-노트-작성) +8. [다운로드에 PGP 서명](#8-다운로드에-pgp-서명) +9. [릴리스 출간](#9-릴리스-출간) +10. [문서 업데이트](#10-문서-업데이트) +11. [커뮤니티에 알리기](#11-커뮤니티에-알리기) + +## 초기 구성 + +### Git 원격 설정하기 + +이 문서에서는 저장소에서 에 해당하는 +Git 원격의 이름이 "upstream"이라고 가정한다는 점에 유의해야 한다. +그렇지 않은 경우(예: 이름을 "origin" 또는 이와 유사한 이름으로 선택한 경우) +그에 따라 로컬 환경에 맞게 나열된 스니핏(snippet)을 조정해야 한다. +업스트림 원격의 이름이 확실하지 않은 경우 `git remote -v` 와 +같은 명령을 사용하여 확인하자. + +[업스트림 원격](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/configuring-a-remote-for-a-fork)이 +없는 경우 +다음과 같이 추가할 수 있다. + +```shell +git remote add upstream git@github.com:helm/helm.git +``` + +### 환경 변수 설정하기 + +이 문서에서는 편의를 위해 설정할 수 있는 몇 가지 환경 변수를 +소개한다. 주/부 릴리스의 경우 +다음을 사용하자. + +```shell +export RELEASE_NAME=vX.Y.0 +export RELEASE_BRANCH_NAME="release-X.Y" +export RELEASE_CANDIDATE_NAME="$RELEASE_NAME-rc.1" +``` + +패치 릴리스를 만드는 경우 대신 다음을 사용하자. + +```shell +export PREVIOUS_PATCH_RELEASE=vX.Y.Z +export RELEASE_NAME=vX.Y.Z+1 +export RELEASE_BRANCH_NAME="release-X.Y" +``` + +### 서명 키 설정하기 + +또한 바이너리를 해싱하고 서명 파일을 제공하여 릴리스 +프로세스의 보안 및 검증을 추가한다. 이 작업은 +[GitHub 및 GPG] (https://help.github.com/en/articles/about-commit-signature-verification)를 +이용하여 수행한다. +GPG가 아직 설정되지 않은 경우, 다음 단계를 수행할 수 있다. + +1. [GPG 설치] (https://gnupg.org/index.html) +2. [GPG 키 + 생성] (https://help.github.com/en/articles/generating-a-new-gpg-key) +3. [GitHub 계정에 + 키 추가] (https://help.github.com/en/articles/adding-a-new-gpg-key-to-your-github-account) +4. [Git에서 서명 + 키 설정] (https://help.github.com/en/articles/telling-git-about-your-signing-key) + +서명 키가 있으면 저장소 루트에 있는 KEYS 파일에 추가해야 +한다. KEYS 파일에 추가하는 지시어는 그 파일 안에 있다. 아직 +공개 키를 키 서버 네트워크에 추가하지 않았다면 추가해야 한다. +GnuPG를 사용하는 경우 +[Debian에서 제공하는 지침] (https://debian-administration.org/article/451/Submitting_your_GPG_key_to_a_keyserver)을 따를 수 있다. + +## 1. 릴리스 브랜치 생성 + +### 주/부 릴리스 + +주요 릴리스는 *이전 호환성을 깨는* 새로운 기능의 추가 및 동작 +변경을 위한 것이다. 부 릴리스는 이전 버전과의 호환성을 깨지 않는 선에서 +새로운 기능 추가를 위한 것이다. 주 또는 부 릴리스를 생성하려면 +먼저 main에서 `release-X.Y` 브랜치를 생성한다. + +```shell +git fetch upstream +git checkout upstream/main +git checkout -b $RELEASE_BRANCH_NAME +``` + +이 새 브랜치는 릴리스의 기반이 되며, +이를 기반으로 하여 변경해 나갈 것이다. + +릴리스에 대한 +[헬름/헬름 마일스톤] (https://github.com/helm/helm/milestones)이 GitHub에 있는지 확인한다(필요한 경우 생성). +이 릴리스에 대한 PR 및 이슈가 이 마일스톤에 있는지 확인하자. + +주 또는 부 릴리스의 경우 2 단계로 이동한다. +[주 또는 부 릴리스: +git에서 버전 번호 변경](#2-git에서-주-또는-부-버전-번호-변경) + +### 패치 릴리스 + +패치 릴리스는 기존 릴리스에 대한 몇 가지 중요한 수정 사항이다. +`release-X.Y` 브랜치를 생성하여 시작한다. + +```shell +git fetch upstream +git checkout -b $RELEASE_BRANCH_NAME upstream/$RELEASE_BRANCH_NAME +``` + +여기에서 패치 릴리스로 가져올 커밋을 +선택할 수 있다. + +```shell +# 체리-픽(cherry-pick)하려는 커밋 ID 목록 조회 +git log --oneline +# 병합 커밋을 포함하지 않고 가장 오래된 커밋부터 골라서 선택 +git cherry-pick -x +``` + +커밋이 체리픽되면 릴리스 브랜치를 푸시해야 한다. + +```shell +git push upstream $RELEASE_BRANCH_NAME +``` + +분기를 푸시하면 테스트가 실행되며, 태그를 만들기 전에 통과해야 한다. +이 새로운 태그는 패치 릴리스의 기반이 된다. + +패치 릴리스의 경우 +[헬름/헬름 마일스톤] (https://github.com/helm/helm/milestones) +생성은 선택사항이다. + +계속 진행하기 전에 릴리스가 CI를 통과했는지 [CircleCI 에서의 헬름](https://circleci.com/gh/helm/helm)를 +확인하자. 패치 릴리스는 2-5 단계를 건너 뛰고 6 단계로 진행하여 +[릴리스 확정](#6-릴리스-확정)를 수행할 수 있다. + +## 2. git에서 주 또는 부 버전 번호 변경 + +주 또는 부 릴리스를 수행할 때 `internal/version/version.go` 를 +새 릴리스 버전으로 업데이트해야 한다. + +```shell +$ git diff internal/version/version.go +diff --git a/internal/version/version.go b/internal/version/version.go +index 712aae64..c1ed191e 100644 +--- a/internal/version/version.go ++++ b/internal/version/version.go +@@ -30,7 +30,7 @@ var ( + // Increment major number for new feature additions and behavioral changes. + // Increment minor number for bug fixes and performance enhancements. + // Increment patch number for critical fixes to existing releases. +- version = "v3.3" ++ version = "v3.4" + + // metadata is extra build time data + metadata = "" +``` + +`version.go` 파일에서 버전을 업데이트하는 것 외에도 +해당 버전 번호를 사용하는 해당 테스트도 업데이트해야 한다. + +* `cmd/helm/testdata/output/version.txt` +* `cmd/helm/testdata/output/version-client.txt` +* `cmd/helm/testdata/output/version-client-shorthand.txt` +* `cmd/helm/testdata/output/version-short.txt` +* `cmd/helm/testdata/output/version-template.txt` +* `pkg/chartutil/capabilities_test.go` + +```shell +git add . +git commit -m "bump version to $RELEASE_NAME" +``` + +이는 $RELEASE_BRANCH_NAME에 대해서만 업데이트된다. +[3.2에서 3.3으로의 +이 예제](https://github.com/helm/helm/pull/8411/files)에서와 +같이 다음 릴리스가 생성될 때 이 변경 사항을 마스터 브랜치로 +가져와야 하며, 다음 릴리스의 마일스톤에 추가해야 한다. + +```shell +# 버전을 올리기 위해 마지막 커밋을 획득 +git log --format="%H" -n 1 + +# 마스터에서 새 브랜치를 생성 +git checkout main +git checkout -b bump-version- + +# 첫 번째 명령으로부터 ID를 사용하여 커밋을 체리픽 +git cherry-pick -x + +# 변경 사항 커밋 +git push origin bump-version- +``` + +## 3. 주/부 릴리스: 릴리스 브랜치 커밋 및 푸시 + +다른 사람들이 테스트를 시작하기 위해 이제 릴리스 브랜치를 업스트림으로 푸시하고 +테스트 프로세스를 시작할 수 있다. + +```shell +git push upstream $RELEASE_BRANCH_NAME +``` + +계속 진행하기 전에 릴리스가 CI를 통과했는지 +[CircleCI 에서의 헬름] (https://circleci.com/gh/helm/helm)을 확인하자. + +사용 가능한 사람이 있는 경우 모든 적절한 변경 사항이 적용되고 +릴리스에 대한 모든 커밋이 있는지 계속 확인하기 전에 +다른 사용자와 브랜치에 대해 동료-평가를 진행하자. + +## 4. 주/부 릴리스: 릴리스 후보 생성 + +이제 릴리스 브랜치가 나왔고 준비되었으므로 +릴리스 후보를 만들고 반복할 차례이다. + +```shell +git tag --sign --annotate "${RELEASE_CANDIDATE_NAME}" --message "Helm release ${RELEASE_CANDIDATE_NAME}" +git push upstream $RELEASE_CANDIDATE_NAME +``` + +CircleCI는 테스트할 태그된 릴리스 이미지와 클라이언트 바이너리를 +자동으로 생성한다. + +테스터의 경우 CircleCI가 아티팩트 빌드를 완료한 후 +테스트를 시작하는 프로세스에는 다음과 같이 클라이언트를 받는 단계가 포함된다. + +리눅스/amd64 의 경우, /bin/bash 를 사용한다 + +```shell +wget https://get.helm.sh/helm-$RELEASE_CANDIDATE_NAME-linux-amd64.tar.gz +``` + +darwin/amd64 의 경우, Terminal.app 을 사용한다. + +```shell +wget https://get.helm.sh/helm-$RELEASE_CANDIDATE_NAME-darwin-amd64.tar.gz +``` + +윈도우/amd64, 파워셸(PowerShell)을 사용한다. + +```shell +PS C:\> Invoke-WebRequest -Uri "https://get.helm.sh/helm-$RELEASE_CANDIDATE_NAME-windows-amd64.tar.gz" -OutFile "helm-$ReleaseCandidateName-windows-amd64.tar.gz" +``` + +그런 다음 바이너리의 압축을 풀고 $PATH의 특정 장소로 이동하거나 +특정 장소로 이동하여 $PATH에 추가한다 +(예 : linux/macOS의 경우 /usr/local/bin/helm, Windows의 경우 C:\Program Files\helm\helm.exe). + +## 5. 주/부 릴리스: 연속 릴리스 후보 개선 + +릴리스와 관련된 모든 결과를 문서화하여 가능한 +모든 방법으로 헬름 테스트를 시도하고 중단하기 위해 +명시적으로 시간과 리소스를 투자하는 데 여러 시간을 보내게 된다. +이 시간은 릴리스가 다양한 기능 또는 업그레이드 환경에, +코딩이 아닌 문제를 유발할 수있는 방법을 테스트하고 찾는데 소비되어야 한다. +이 기간 동안 릴리스는 코드 동결 상태이며 추가 코드 변경 사항은 다음 릴리스로 푸시된다. + +이 단계에서 $RELEASE_BRANCH_NAME 브랜치는 +새로운 출시 후보를 생성함에 따라 계속 발전하게 된다. +새로운 후보의 빈도는 릴리스 관리자에게 달려 있다. +보고된 문제의 심각도, 테스터의 가용성 및 릴리스 기한을 고려하여 +최선의 판단을 내리자. 일반적인 경우, 손상된 릴리스를 전달하는 것보다는 +릴리스가 마감일을 넘기는게 차라리 더 좋다. + +새 릴리스 후보를 생성 할 때마다 마스터 브랜치에서 체리픽 하여 +브랜치에 커밋을 추가하는 것으로 시작한다. + +```shell +git cherry-pick -x +``` + +또한 분기를 GitHub으로 푸시하고 CI를 통과하는지도 확인해야 한다. + +그럼 다음 태그를 지정하고 사용자들에게 새 릴리스 후보에 대해 알린다. + +```shell +export RELEASE_CANDIDATE_NAME="$RELEASE_NAME-rc.2" +git tag --sign --annotate "${RELEASE_CANDIDATE_NAME}" --message "Helm release ${RELEASE_CANDIDATE_NAME}" +git push upstream $RELEASE_CANDIDATE_NAME +``` + +GitHub에 푸시되면 이 태그가 있는 브랜치가 CI에 빌드 되는지 확인한다. + +여기서부터는 이 프로세스를 반복하고 릴리스 후보에 만족할 때까지 지속적으로 테스트한다. +릴리스 후보의 경우 전체 노트를 작성하지는 않지만 일부 +[릴리스 노트](#7-릴리스-노트-작성)를 미리 작성(scaffold)할 수 있다. + +## 6. 릴리스 확정 + +최종적으로 릴리스 후보의 품질에 만족한다면 계속 진행하여 진짜를 +만들 수 있다. 마지막으로 한 번 더 확인하여 모든 것이 +정상인지 확인한 다음, 마지막으로 릴리스 태그를 푸시한다. + +```shell +git checkout $RELEASE_BRANCH_NAME +git tag --sign --annotate "${RELEASE_NAME}" --message "Helm release ${RELEASE_NAME}" +git push upstream $RELEASE_NAME +``` + +릴리스가 [CircleCI](https://circleci.com/gh/helm/helm)에서 +성공했는지 확인하자. 그렇지 않은 경우 릴리스를 수정하고 +릴리스를 다시 푸시해야 한다. + +CI 작업을 실행하는 데 약간의 시간이 걸리므로 완료될 때까지 +기다리는 동안 릴리스 정보 작성 단계로 넘어갈 수 있다. + +## 7. 릴리스 노트 작성 + +릴리스 주기 동안 발생한 커밋을 기반으로 변경 로그를 자동 생성하지만 +일반적으로 수동으로, 인간 생명체든/마케팅 팀이든/심지어 고양이라도 릴리스 노트는 손으로 작성한 경우가 +최종 사용자에게 더 유용하다. + +주/부 릴리스를 릴리스하는 경우 일반적으로 주목할만한 +사용자용 기능을 나열하는 것으로 충분하다. 패치 릴리스의 경우 +동일하게 하되 증상이나 영향을 받을 수 있는 사용자에 대해 기재하자. + +릴리스 정보에는 다음 릴리스의 버전과 계획된 날짜가 포함되어야 한다. + +부 릴리스에 대한 예제 릴리스 노트는 다음과 같다. + +```markdown +## vX.Y.Z + +Helm vX.Y.Z는 기능 릴리스이다. 이번 릴리스에서는 에 중점을 두었다. 사용자는 최상의 환경을 위해 업그레이드하는 것이 좋다. + +커뮤니티는 계속 성장하고 있으며, 함께하면 좋겠다! + +- [Kubernetes Slack] (https://kubernetes.slack.com)에서 토론에 참여해보자. + - 질문을 하려면 `#helm-users` + - PR, 코드, 버그를 논의하려면 `#helm-dev` +- 공개 개발자 전화 : 목요일 오전 9시 30 분 [Zoom]을 통해 행 아웃 (https://zoom.us/j/696660622) +- 차트 테스트, 디버그, 기여 : [GitHub/헬름/차트] (https://github.com/helm/charts) + +## 주목할 만한 변화 + +- Kubernetes 1.16은 이제 새 매니페스트 apiVersion도 지원한다. +- Spring은 2.22으로 업그레이드되었다. + +## 설치 및 업그레이드 + +헬름 X.Y 를 다운로드한다. 일반적인 플랫폼 바이너리는 다음과 같다. + +- [MacOS amd64](https://get.helm.sh/helm-vX.Y.Z-darwin-amd64.tar.gz) ([checksum](https://get.helm.sh/helm-vX.Y.Z-darwin-amd64.tar.gz.sha256sum) / CHECKSUM_VAL) +- [리눅스 amd64](https://get.helm.sh/helm-vX.Y.Z-linux-amd64.tar.gz) ([checksum](https://get.helm.sh/helm-vX.Y.Z-linux-amd64.tar.gz.sha256sum) / CHECKSUM_VAL) +- [리눅스 arm](https://get.helm.sh/helm-vX.Y.Z-linux-arm.tar.gz) ([checksum](https://get.helm.sh/helm-vX.Y.Z-linux-arm.tar.gz.sha256) / CHECKSUM_VAL) +- [리눅스 arm64](https://get.helm.sh/helm-vX.Y.Z-linux-arm64.tar.gz) ([checksum](https://get.helm.sh/helm-vX.Y.Z-linux-arm64.tar.gz.sha256sum) / CHECKSUM_VAL) +- [리눅스 i386](https://get.helm.sh/helm-vX.Y.Z-linux-386.tar.gz) ([checksum](https://get.helm.sh/helm-vX.Y.Z-linux-386.tar.gz.sha256) / CHECKSUM_VAL) +- [리눅스 ppc64le](https://get.helm.sh/helm-vX.Y.Z-linux-ppc64le.tar.gz) ([checksum](https://get.helm.sh/helm-vX.Y.Z-linux-ppc64le.tar.gz.sha256sum) / CHECKSUM_VAL) +- [리눅스 s390x](https://get.helm.sh/helm-vX.Y.Z-linux-s390x.tar.gz) ([checksum](https://get.helm.sh/helm-vX.Y.Z-linux-s390x.tar.gz.sha256sum) / CHECKSUM_VAL) +- [윈도우 amd64](https://get.helm.sh/helm-vX.Y.Z-windows-amd64.zip) ([checksum](https://get.helm.sh/helm-vX.Y.Z-windows-amd64.zip.sha256sum) / CHECKSUM_VAL) + +[빠른 시작 가이드](https://docs.helm.sh/using_helm/#quickstart-guide)를 참조하세요. **업그레이드 안내** 또는 자세한 설치 정보는 [설치 가이드](https://docs.helm.sh/using_helm/#installing-helm)를 확인하세요. `bash` 가 있는 모든 시스템에서 [설치할 스크립트] (https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3)를 사용할 수도 있다. + +## 향후 계획 + +- vX.Y.Z + 1 에는 버그 수정만 포함되며 <날짜 삽입>에 릴리스 예정이다. +- vX.Y + 1.0 은 다음 기능 릴리스이며 <날짜 삽입>에 릴리스 예정이다. 이 릴리스는 ... + +## 변경로그 + +- chore(*) v2.7.0 로 버전 업(bump) 08c1144f5eb3e3b636d9775617287cc26e53dba4 (Adam Reese) +- 태그를 작성하지 않는 버그 수정 f4f932fabd197f7e6d608c8672b33a483b4b76fa (Matthew Fisher) +``` + +변경 로그를 포함하여 부분적으로 완료된 릴리스 정보 +집합은 다음 명령을 실행하여 작성할 수 있다. + +```shell +export VERSION="$RELEASE_NAME" +export PREVIOUS_RELEASE=vX.Y.Z +make clean +make fetch-dist +make release-notes +``` + +이렇게하면 **주요 변경 사항** 및 **다음 단계** 섹션을 +작성하기만 하면 되는 훌륭한 기본 출시 노트 세트가 생성된다. + +릴리스 노트에 의견을 자유롭게 추가하도록 하자. +사람들이 볼 때, 우리가 로봇이라는 생각이 들지 않도록 하는 것이 좋다. + +또한 자동 생성된 릴리스 노트에서 URL과 +체크섬이 올바른지 다시 확인해야 한다. + +완료되면 GitHub에서 [헬름/헬름 릴리스](https://github.com/helm/helm/releases)로 +이동하고 여기에 작성된 메모로 태그가 지정된 +릴리스의 릴리스 노트를 편집한다. 대상 분기의 경우 +$RELEASE_BRANCH_NAME로 설정한다. + +이제는 릴리스가 게시되기 전에 다른 사람들에게 릴리스 정보를 보여주어 +검토 받을 필요가 있다. 검토를 받기 위해 +[#helm-dev](https://kubernetes.slack.com/messages/C51E88VDG)로 +요청을 보내자. 누구든 놓치는 부분이 있을 수 있기 때문에 항상 도움이 된다. + +## 8. 다운로드에 PGP 서명 + +해시는 다운로드 내용이 어떤 것으로 생성되었는지에 대한 서명을 +제공하지만, 서명된 패키지는 그 패키지가 어디서 왔는지 출처를 +추적할 수 있게 해준다. + +이렇게 하기 위하여 다음의 `make` 명령을 실행한다. + +```shell +export VERSION="$RELEASE_NAME" +make clean # if not already run +make fetch-dist # if not already run +make sign +``` + +이렇게 하면 CI가 푸시한 개별 파일에 대하여, ASCII 아머드 서명 파일을 +생성한다. + +모든 서명 파일(`*.asc`)을 GitHub의 릴리스에 업로드해야 +한다. (바이너리 첨부) + +## 9. 릴리스 출간 + +이제 출시를 공식화할 차례이다! + +릴리스 노트가 GitHub에 저장되고 CI 빌드가 완료되고 +릴리스에 서명 파일을 추가한 후 릴리스에서 "게시"를 누를 수 있다. +그러면 릴리스가 게시되고 "최신(latest)"으로 나열되며 +[helm/helm] (https://github.com/helm/helm) 저장소의 첫 페이지에 이 릴리스가 표시된다. + +## 10. 문서 업데이트 + +[헬름 웹 사이트 문서 섹션](https://helm.sh/docs)에는 +문서의 헬름 버전이 나열된다. 사이트에서 주, 부, 패치 버전을 +업데이트해야 한다. 다음 부 릴리스 날짜도 사이트에 +게시되며 업데이트해야 한다. +이를 위해 [helm-www 저장소] (https://github.com/helm/helm-www)에 +대한 pull 요청을 생성한다. +`config.toml` 파일에서 +적절한 `params.versions` 섹션을 찾고 [현재 버전 업데이트](https://github.com/helm/helm-www/pull/676/files)의 +예와 같이 헬름 버전을 업데이트한다. 동일한`config.toml` 파일에서 +`params.nextversion` 섹션을 업데이트한다. + +해당되는 경우 릴리스의 [helm/helm 마일스톤](https://github.com/helm/helm/milestones)을 +닫는다. + +주/부 릴리스의 +[버전 차이] (https://github.com/helm/helm-www/blob/main/content/en/docs/topics/version_skew.md)를 +업데이트한다. + +[여기](https://helm.sh/calendar/release)에서 릴리스 달력을 업데이트한다. +* 당일 오후 5시 GMT에 대한 알림과 함께 다음 마이너 릴리스에 대한 항목을 생성한다. +* 계획된 릴리스 전의 월요일에 다음 마이너 릴리스의 RC1 항목을 만들고 그날 오후 5시 GMT에 대한 알림을 생성한다. + +## 11. 커뮤니티에 알리기 + +축하한다! 모두 완료했다. $DRINK_OF_CHOICE 를 한모금 하자. +당신은 그럴만한 일을 했다. + +좋은 $DRINK_OF_CHOICE 를 즐긴 후, Slack과 Twitter에 +[GitHub 릴리스] (https://github.com/helm/helm/releases) 링크를 통해 +새 릴리스를 발표하자. + +선택적으로, 새 릴리스에 대한 블로그 게시물을 작성하고 그 곳에 몇 가지 새로운 기능을 +보여주도록 하자! diff --git a/content/ko/docs/faq/_index.md b/content/ko/docs/faq/_index.md new file mode 100644 index 0000000000..c5b62c2156 --- /dev/null +++ b/content/ko/docs/faq/_index.md @@ -0,0 +1,614 @@ +--- +title: "자주 묻는 질문" +weight: 8 +--- + +# 자주 묻는 질문 + +> 헬름 2와 헬름 3의 중요한 차이점은 무엇일까요? +> 이 페이지는 가장 자주 나오는 질문들에 대한 도움말을 제공합니다. + +이 문서를 개선시킬 수 있도록 **도와주시면 감사하겠습니다**. +정보를 추가, 수정, 삭제하려면 [이슈를 등록](https://github.com/helm/helm-www/issues)하거나 +풀 리퀘스트를 보내주세요. + +## 헬름 2 이후 변화 + +다음은 헬름 3에 도입된 주요 변경사항의 상세 목록입니다. + +### 틸러(tiller) 제거 + +헬름 2 개발 주기에 틸러를 도입했었습니다. +틸러는 공유 클러스터에서 작업하는 팀에게 중요한 역할을 했습니다. +서로 다른 운영자가 동일한 릴리스 집합과 상호 작용할 수 있도록 만들어 주었습니다. + +쿠버네티스 1.6에서 역할 기반 접근 제어(RBAC)가 기본적으로 활성화되면서, +운영 시나리오에서 틸러 접근제어를 관리하는 것이 더욱 어려워졌습니다. +수많은 보안 정책 때문에 +우리의 입장은 허용 가능한 기본 설정을 제공하는 것이었습니다. +이를 통해 헬름을 처음 접한 사용자는 처음부터 보안 제어를 깊이 알지 못해도 +헬름과 쿠버네티스를 시작해볼 수 있었습니다. 아쉽지만, +이러한 허용적(permissive) 설정은 의도치 않게 사용자에게 광범위한 권한을 부여할 수 있습니다. +데브옵스(DevOps)와 사이트 신뢰성 엔지니어(SRE)는 멀티 테넌트 클러스터에 틸러를 +설치할 때 추가적인 작업 단계를 알아야 했습니다. + +커뮤니티 구성원들이 특정 시나리오에서 헬름을 어떻게 사용하는지 들은 후, +틸러의 릴리스 관리 시스템은 +상태를 유지하거나 헬름 릴리스 정보의 중심 허브 역할을 하기 위해 +클러스터 내 운영자에게 의존할 필요가 없다는 것을 알게 되었습니다. +그 대신 쿠버네티스 API 서버에서 정보를 간단히 가져오고, +차트 클라이언트 측을 렌더링하며 쿠버네티스에 설치 기록을 보관할 수 있습니다. + +틸러의 주요 목표는 틸러 없이도 달성될 수 있습니다. +그래서 헬름 3와 관련하여 우리가 내린 첫 번째 결정 중 하나는 틸러를 완전히 제거하는 것입니다. + +틸러가 사라지면 헬름의 보안 모델이 획기적으로 간소화됩니다. +헬름 3는 이제 현대 쿠버네티스의 모든 현대적인 보안, 신원 확인 및 인가 기능을 지원합니다. 헬름의 권한은 +[kubeconfig 파일](https://kubernetes.io/ko/docs/concepts/configuration/organize-cluster-access-kubeconfig/)을 +사용하여 평가됩니다. +클러스터 관리자는 세세하게 사용자 권한을 제한할 수 있습니다. +릴리스는 여전히 클러스터 내에 기록되며, +헬름의 나머지 기능은 그대로 유지됩니다. + +### 업그레이드 전략 개선: 3 방향 전략적 병합 패치 + +헬름 2는 양방향 전략적 병합 패치를 사용했었습니다. 업그레이드할 때 +최근 차트의 매니페스트와 새로 제시된 차트의 매니페스트(`helm upgrade` 중에 제공된 것 중 +하나)를 비교했습니다. 쿠버네티스 리소스에 적용해야 할 변경 사항을 알아내기 위해 +두 차트 간의 차이를 비교했습니다. +클러스터 외부의 활동(예: `kubectl edit` 하는) 중에 변경 사항이 적용되었다면, +그러한 변경은 고려되지 않았습니다. 이로 인해 리소스가 이전 상태로 롤백할 수 없게 되었습니다. +헬름은 마지막으로 적용된 차트의 매니페스트만 현재 상태로 간주했기 때문에 +차트의 상태가 변경되지 않은 경우 +활성 상태는 변경되지 않은 상태로 그대로 유지됩니다. + +헬름 3는 현재 3 방향 전략적 병합 패치를 사용하고 있습니다. +헬름은 패치를 생성할 때 이전 매니페스트, 라이브 상태, 새 매니페스트를 고려합니다. + +#### 예시 + +이러한 변화가 어떤 영향을 미치는지 몇 가지 일반적인 예를 살펴보겠습니다. + +##### 라이브 상태 변경 시 롤백 + +당신의 팀은 방금 헬름을 사용하여 쿠버네티스 프로덕션 서버에 애플리케이션을 배포했습니다. +차트에는 레플리카 수가 3개로 설정된 디플로이먼트(Deployment) 오브젝트를 +포함합니다. + +```console +$ helm install myapp ./myapp +``` + +새로운 개발자가 팀에 합류합니다. +첫날에 프로덕션 클러스터를 살펴보다가, 키보드에 커피를 쏟는 끔찍한 사고가 발생하여 +`kubectl scale` 명령어로 프로덕션 디플로이먼트 +레플리카 수를 3개에서 0개로 축소시킵니다. + +```console +$ kubectl scale --replicas=0 deployment/myapp +``` + +팀의 다른 개발자는 프로덕션 사이트가 다운된 것을 확인하고 +릴리스를 이전 상태로 롤백하기로 합니다. + +```console +$ helm rollback myapp +``` + +어떻게 될까요? + +헬름 2에서는 이전 매니페스트를 새 매니페스트와 비교하여 패치를 생성합니다. +이것은 롤백이기 때문에 동일한 매니페스트입니다. +헬름에서는 이전 매니페스트와 새 매니페스트 간에 +차이가 없기 때문에 변경할 사항이 없다고 판단합니다. +레플리카 수는 계속 0입니다. 패닉은 계속됩니다. + +헬름 3에서 패치는 이전 매니페스트, 라이브 상태, 새 매니페스트를 사용하여 생성됩니다. +헬름은 기존 상태가 3이고 라이브 상태가 0에 있으며, +새 매니페스트는 그것을 다시 3으로 바꾸기를 원하기 때문에, +패치를 생성하여 상태를 다시 3으로 바꾸게 됩니다. + +##### 라이브 상태 변경 시 업그레이드 + +많은 서비스 메쉬 및 기타 컨트롤러 기반 애플리케이션은 데이터를 쿠버네티스 오브젝트에 주입합니다. +이것은 사이드카, 레이블 또는 다른 정보일 수 있습니다. +이전에 차트에서 렌더링된 매니페스트가 있다면 다음과 같습니다. + +```yaml +containers: +- name: server + image: nginx:2.0.0 +``` + +그리고 다른 애플리케이션이 라이브 상태를 다음과 같이 수정했습니다. + +```yaml +containers: +- name: server + image: nginx:2.0.0 +- name: my-injected-sidecar + image: my-cool-mesh:1.0.0 +``` + +이제 `nginx` 이미지 태그를 `2.1.0`으로 업그레이드하려고 합니다. +따라서 다음과 같은 매니페스트가 있는 차트로 업그레이드합니다. + +```yaml +containers: +- name: server + image: nginx:2.1.0 +``` + +어떻게 될까요? + +헬름 2에서 헬름은 기존 매니페스트와 새로운 매니페스트 사이에 +`containers` 오브젝트의 패치를 생성합니다. +패치 생성 중에는 클러스터의 라이브 상태가 고려되지 않습니다. + +클러스터의 라이브 상태가 다음과 같이 수정됩니다. + +```yaml +containers: +- name: server + image: nginx:2.1.0 +``` + +사이드카 파드가 라이브 상태에서 제거됩니다. 더 많은 공포가 뒤따릅니다. + +헬름 3에서 헬름은 기존 매니페스트, 라이브 상태, 새 매니페스트 사이에 +`container` 오브젝트의 패치를 생성합니다. 새로운 매니페스트가 이미지 태그를 +`2.1.0` 으로 바꾸지만 라이브 상태는 사이드카 컨테이너를 포함합니다. + +클러스터의 라이브 상태가 다음과 같이 수정됩니다. + +```yaml +containers: +- name: server + image: nginx:2.1.0 +- name: my-injected-sidecar + image: my-cool-mesh:1.0.0 +``` + +### 이제 릴리스 이름이 네임스페이스에 할당됩니다 + +틸러가 제거되면서 각 릴리스에 대한 정보는 어디론가 이동해야 했습니다. +헬름 2에서는 틸러와 동일한 네임스페이스에 저장되었습니다. +이는 실제로 릴리스에 이름이 사용되면 다른 네임스페이스에 배포되었더라도 +다른 릴리스에서는 동일한 이름을 사용할 수 없음을 의미합니다. + +헬름 3에서는 특정 릴리스에 대한 정보가 릴리스 자체와 동일한 네임스페이스에 +저장됩니다. 즉, 이제 사용자는 별도의 두 네임스페이스에서 +`helm install wordpress stable/wordpress`를 수행할 수 있으며, +현재 네임스페이스 컨텍스트를 변경하여 `helm list` 를 조회할 수 있습니다. +(예: `helm list --namespace foo`) + +이렇게 네이티브 클러스터 네임스페이스가 보다 개선되면서 +`helm list` 명령은 기본적으로 모든 릴리스를 나열하지 않습니다. +대신 현재 쿠버네티스 컨텍스트의 네임스페이스에 있는 릴리스만 +나열됩니다(즉, `kubectl config view --minify`를 실행할 때 표시되는 네임스페이스). +또한 헬름 2와 유사한 동작을 수행하려면 `helm list`에 +`--all-namespaces` 플래그를 주어야 합니다. + +### 기본 스토리지 드라이버로서의 시크릿(Secret) + +헬름 3에서 시크릿은 이제 [기본 스토리지 +드라이버](/docs/topics/advanced/#storage-backends)로 사용됩니다. 헬름 2는 +기본적으로 컨피그맵(ConfigMap)을 사용하여 릴리스 정보를 저장합니다. 헬름 2.7.0에서 +릴리스 정보를 저장하기 위해 시크릿을 사용하는 새로운 스토리지 백엔드가 구현되었으며 +헬름 3부터는 기본값이 되었습니다. + +헬름 3 기본값을 시크릿으로 변경하면 쿠버네티스의 +시크릿 암호화(Secret Encryption) 릴리스와 함께 +차트를 보호할 수 있습니다. + +[미사용 시크릿을 암호화하는 +것](https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/)은 +쿠버네티스 1.7에서 알파 기능으로 사용 가능하게 되었고 +쿠버네티스 1.13을 기점으로 안정화되었습니다. 이를 통해 사용자는 +미사용 헬름 릴리스 메타데이터를 암호화할 수 있으므로 +나중에 볼트(Vault)와 같은 용도로 확장할 수 있습니다. + +### Go import 경로 변경 + +헬름 3에서 헬름은 Go import 경로를 `k8s.io/helm`에서 +`helm.sh/helm/v3`으로 전환했습니다. 헬름 3 Go 클라이언트 라이브러리로 +업그레이드하려면 import 경로를 변경해야 합니다. + +### Capabilities + +렌더링 단계에서 사용 가능한 `.Capabilities` 빌트인 객체가 +간소화되었습니다. + +[빌트인 객체](/docs/chart_template_guide/builtin_objects/) + +### JSON 스키마로 차트 값 유효성 검사 + +이제 차트 값(values)에 JSON 스키마를 적용할 수 있습니다. +이렇게 하면 사용자가 입력한 값이 차트 관리자가 제공한 +스키마를 따르므로 사용자가 차트에 잘못된 값들을 입력할 때 +오류 보고 기능이 향상됩니다. + +다음 명령어 중 하나가 호출될 때 유효성 검사가 수행됩니다. + +* `helm install` +* `helm upgrade` +* `helm template` +* `helm lint` + +자세한 내용은 [스키마 파일](/ko/docs/topics/charts#스키마-파일) 문서를 +참조하십시오. + +### `requirements.yaml`이 `Chart.yaml` 로 통합 + +차트 의존성 관리 시스템이 requirements.yaml 와 requirements.lock에서 +Chart.yaml 와 Chart.lock으로 이동했습니다. 헬름 3에서 새로운 차트는 +새로운 형식을 사용하는 것이 권장됩니다. 그러나 헬름 3는 여전히 차트 API +버전 1(`v1`)을 이해하고 있으며 기존 `requirements.yaml` 파일을 로드합니다. + +헬름 2에서는 `requirements.yaml`이 이렇게 생겼습니다. + +```yaml +dependencies: +- name: mariadb + version: 5.x.x + repository: https://kubernetes-charts.storage.googleapis.com/ + condition: mariadb.enabled + tags: + - database +``` + +헬름 3에서는 의존성이 동일한 방식으로 표현되지만 +이제 `Chart.yaml`에서 표현됩니다. + +```yaml +dependencies: +- name: mariadb + version: 5.x.x + repository: https://kubernetes-charts.storage.googleapis.com/ + condition: mariadb.enabled + tags: + - database +``` + +차트는 여전히 `charts/` 디렉토리에 다운로드되므로 +`charts/` 디렉토리에 제공된 하위 차트는 +수정 없이 계속 동작합니다. + +### 설치 시 이름(또는 --generate-name)이 필요합니다 + +헬름 2에서 이름이 주어지지 않은 경우 자동으로 생성된 이름이 지정됩니다. 프로덕션에서 +이것은 유용한 기능이라기보다는 오히려 골칫거리로 판명되었습니다. 헬름 3에서 +`helm install`과 함께 이름이 주어지지 않으면 헬름이 오류를 던집니다. + +이름이 자동으로 생성되기를 원하는 사용자는 `--generate-name` 플래그를 +사용하여 자동으로 생성할 수 있습니다. + +### OCI 레지스트리로 차트 밀어내기 + +이것은 헬름 3에 도입된 실험적인(experimental) 기능입니다. +사용하려면 환경 변수 `HELM_EXPERIMENTAL_OCI=1`을 설정합니다. + +높은 수준에서 차트 저장소는 차트를 저장하고 공유할 수 있는 곳입니다. +헬름 클라이언트는 헬름 차트를 패키징하여 차트 저장소로 보냅니다. +간단히 말해 차트 저장소는 index.yaml 파일과 일부 패키지형 차트를 저장하는 +기본 HTTP 서버입니다. + +차트 저장소 API가 가장 기본적인 스토리지 요구 사항을 충족하면 몇 가지 이점이 있지만 +다음과 같은 몇 가지 문제점이 나타나기 시작했습니다. + +- 차트 저장소는 프로덕션 환경에 필요한 대부분의 보안 구현을 + 추상화하는 데 매우 어려움을 겪고 있습니다. 인증 및 인가를 + 위한 표준 API를 갖는 것은 프로덕션 시나리오에서 + 매우 중요합니다. +- 차트의 무결성과 원본을 표시 및 검증하는 데 사용되는 헬름의 차트 출처(provenance) + 도구는 차트 발행 프로세스의 선택 사항입니다. +- 멀티 테넌트 시나리오에서는 다른 테넌트에서 동일한 차트를 업로드할 수 있으므로 + 동일한 컨텐츠를 저장하는 데 드는 스토리지 비용이 두 배가 됩니다. + 보다 스마트한 차트 저장소는 이 문제를 처리하도록 설계되었지만 정식 사양에는 + 포함되지 않습니다. +- 검색, 메타데이터 정보, 차트 가져오기에 단일 인덱스 파일을 + 사용하면 안전한 멀티 테넌트 구현으로 설계하기가 어렵거나 + 복잡해졌습니다. + +도커의 분산 프로젝트(Distribution prject, 도커 레지스트리 v2라고도 함)는 +도커 레지스트리 프로젝트의 후속 작업입니다. 많은 주요 클라우드 벤더가 +분산 프로젝트를 제공하는 상품을 보유하고 있으며, 수많은 벤더가 동일한 제품을 +제공함에 따라 분산 프로젝트는 수년간의 개선, 보안 모범 사례, 실전 테스트의 +혜택을 받아 왔습니다. + +차트를 패키징하고 도커 레지스트리에 밀어내는 방법에 대한 자세한 내용은 +`helm help chart` 및 `helm help registry`를 참조하시기 바랍니다. + +자세한 내용은 [이 페이지](/docs/topics/registries/)를 참조하시기 바랍니다. + +### `helm serve` 제거 + +`helm serve`는 개발 목적으로 머신에서 로컬 차트 저장소를 +실행했습니다. 하지만 개발 도구로서 그다지 많은 관심을 받지 못했고 +설계에도 많은 문제가 있었습니다. 결국 우리는 이것을 제거하고 +플러그인으로 분리하기로 했습니다. + +`helm serve`와 유사한 경험을 위해서는 [차트뮤지엄 +(ChartMuseum)](https://chartmuseum.com/docs/#using-with-local-filesystem-storage)의 +로컬 파일 시스템 스토리지 옵션과 +[servecm 플러그인](https://github.com/jdolitsky/helm-servecm)에 대해 살펴보세요. + + +### 라이브러리 차트 지원 + +헬름 3는 "라이브러리 차트"라고 하는 차트의 클래스를 지원합니다. 다른 차트에서 +공유하지만 자체 릴리스 아티팩트는 생성하지 않는 차트입니다. 라이브러리 차트의 +템플릿은 `define` 요소만 선언할 수 있습니다. 전역 범위 `define`이 아닌 콘텐츠는 +무시됩니다. 이를 통해 사용자는 여러 차트에서 재사용할 수 있는 코드 조작(snippet)을 +재사용하고 공유할 수 있으므로 중복성을 방지하고 +차트 [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself)를 유지할 수 있습니다. + +라이브러리 차트는 Chart.yaml의 dependencies 지시어에 선언되며 +다른 차트처럼 설치 및 관리됩니다. + +```yaml +dependencies: + - name: mylib + version: 1.x.x + repository: quay.io +``` + +이 기능이 차트 개발자에게 제공되는 유즈 케이스와 +라이브러리 차트를 사용하면서 생긴 모범 사례을 보게 되어 +매우 기쁩니다. + +### Chart.yaml apiVersion 격상 + +라이브러리 차트 지원이 도입되고 requirements.yaml이 Chart.yaml로 +통합됨에 따라 헬름 2의 패키지 형식을 이해하고 있는 클라이언트는 +이러한 새로운 기능을 이해할 수 없게 되었습니다. 따라서 Chart.yaml의 +apiVersion을 v1에서 v2로 격상했습니다. + +`helm create`는 이제 이 새로운 형식을 사용하여 차트를 생성하므로 +기본 apiVersion도 격상했습니다. + +헬름 차트의 두 버전을 모두 지원하려는 클라이언트는 패키지 형식을 해석하는 +방법을 이해하기 위해 Chart.yaml의 `apiVersion` 필드를 검사하는 것이 좋습니다. + +### XDG 베이스 디렉토리 지원 + +[XDG 베이스 디렉토리 +사양](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html)은 +파일 시스템에 설정, 데이터, 캐시된 파일을 저장할 위치를 정의하는 +이식 가능한 표준입니다. + +헬름 2에서 헬름은 이 모든 정보를 `~/.helm`(정확히 `helm home`이라고 함)에 +저장했으며, `$HELM_HOME` 환경 변수를 설정하여 변경하거나, +전역 플래그 `--home` 을 사용하여 변경할 수 있습니다. + +헬름 3에서 헬름은 XDG 기본 디렉토리 사양에 따라 다음 환경 변수를 +고려합니다. + +- `$XDG_CACHE_HOME` +- `$XDG_CONFIG_HOME` +- `$XDG_DATA_HOME` + +헬름 플러그인은 `$HELM_HOME`을 스크래치패드 환경으로 +사용하려는 플러그인과의 하위 호환성을 위해 +`$XDG_DATA_HOME`의 별칭으로 `$HELM_HOME`을 여전히 전달됩니다. + +이러한 변화에 맞추기 위해 몇 가지 새로운 환경 변수도 +플러그인 환경에 전달됩니다. + +- `$HELM_PATH_CACHE` 로 캐시 경로 지정 +- `$HELM_PATH_CONFIG` 로 설정 경로 지정 +- `$HELM_PATH_DATA` 로 데이터 경로 지정 + +헬름 3를 지원하려는 헬름 플러그인은 이 새로운 환경 변수들을 +고려해야 합니다. + +### CLI 명령어 이름을 변경했습니다 + +다른 패키지 매니저의 용어와 잘 조화시키기 위해 `helm delete`를 `helm uninstall`로 +개명했습니다. `helm delete`은 여전히 `helm uninstall`의 별칭으로 유지되므로 +두 형식 중 하나를 사용할 수 있습니다. + +헬름 2에서는 릴리스 기록을 제거하기 위해 `--purge` 플래그를 써야 +했습니다. 이제 이 기능은 기본적으로 활성화됩니다. 예전 동작을 유지하려면 +`helm uninstall --keep-history`를 사용합시다. + +또한 동일한 규칙을 수용하기 위해 일부 다른 명령어들이 +개명되었습니다. + +- `helm inspect` -> `helm show` +- `helm fetch` -> `helm pull` + +이러한 명령어는 예전 동사도 별칭으로 유지하므로 +두 가지 형식에서 계속 사용할 수 있습니다. + +### 네임스페이스 자동 생성 + +존재하지 않는 네임스페이스에 릴리스를 생성할 때 헬름 2가 네임스페이스를 만들었습니다. +헬름 3는 다른 쿠버네티스 도구의 동작을 따르며 네임스페이스가 없는 경우 +오류를 반환합니다. `--create-namespace` 플래그를 명시적으로 지정하면 헬름 3가 +네임스페이스를 만듭니다. + +### .Chart.ApiVersion 은 없어졌나요? + +헬름은 머리글자를 대문자로 나타내는 일반적인 낙타 표기법(CamelCasing)을 +따릅니다. `.Capabilities.APIVersions.Has` 와 같은 모든 코드에서 해당 +표기법을 사용했습니다. 헬름 3에서는 이 패턴을 지키기 위해 `.Chart.ApiVersion` +을 `.Chart.APIVersion` 으로 변경했습니다. + +## 설치 + +### 페도라(Fedora) 등의 다른 리눅스 배포판을 위한 네이티브 헬름 패키지는 왜 없나요? + +헬름 프로젝트는 운영 체제 및 환경에 대한 패키지를 관리하지 않습니다. +헬름 커뮤니티는 네이티브 패키지를 제공할 수 있으며 헬름 프로젝트에서 +알게 되면 목록에 포함될 것입니다. 이렇게 해서 +홈브루 포뮬러(HomeBrew formula)가 시작되고 포함되었습니다. +패키지 관리에 관심이 있으시다면 감사하겠습니다. + +### 왜 `curl ...|bash` 스크립트를 제공하나요? + +저장소에 `curl ..|bash` 스크립트로 실행할 수 있는 스크립트(`scripts/get-helm-3`)가 +있습니다. 전송은 모두 HTTPS에 의해 보호되며 스크립트는 가져오는 패키지에 대해 일부 +감사를 수행합니다. 그러나 이 스크립트는 쉘 스크립트의 모든 일반적인 위험을 +가지고 있습니다. + +유용하기 때문에 제공하지만 사용자들이 먼저 대본을 주의 깊게 +읽어보는 것이 좋습니다. 우리가 정말 원하는 것은 더 나은 +패키지형 헬름 릴리스입니다. + +### 헬름 클라이언트 파일들을 기본값 말고 다른 곳에 두려면 어떻게 하나요? + +헬름은 파일을 보관할 때 XDG 구조를 사용합니다. +그 위치를 재정의(override)할 수 있는 환경변수를 사용할 수 있습니다. + +- `$XDG_CACHE_HOME`: 캐시 파일 보관 장소를 다른 곳으로 설정 +- `$XDG_CONFIG_HOME`: 헬름 설정 파일 보관 장소를 다른 곳으로 + 설정 +- `$XDG_DATA_HOME`: 헬름 데이터 보관 장소를 다른 곳으로 설정 + +기존 저장소가 있는 경우, `helm repo add...`를 사용하여 저장소를 다시 추가해야 +합니다. + + +## 삭제 + +### 로컬 헬름을 삭제하고 싶어요. 그 파일들은 모두 어디에 있나요? + +헬름은 `helm` 바이너리 파일과 함께 일부 파일을 다음 위치에 저장합니다. + +- $XDG_CACHE_HOME +- $XDG_CONFIG_HOME +- $XDG_DATA_HOME + +다음 표에서는 OS 별로 각 항목에 대한 기본 폴더를 제공합니다. + +| 운영 체제 | 캐시 경로 | 설정 경로 | 데이터 경로 | +|------------------|-----------------------------|----------------------------------|---------------------------| +| 리눅스 | `$HOME/.cache/helm ` | `$HOME/.config/helm ` | `$HOME/.local/share/helm` | +| 맥OS | `$HOME/Library/Caches/helm` | `$HOME/Library/Preferences/helm` | `$HOME/Library/helm ` | +| 윈도우 | `%TEMP%\helm ` | `%APPDATA%\helm ` | `%APPDATA%\helm` | + +## 트러블슈팅 + +### "Unable to get an update from the "stable" chart repository"라는 경고가 표시됩니다. + +`helm repo list` 를 실행합니다. `storage.googleapis.com` URL을 가리키고 있는 `stable` 저장소가 표시되면 해당 저장소를 업데이트해야 합니다. +2020년 11월 13일에 헬름 차트 저장소는 일년 간의 유예기간을 거친 후 [더 이상 지원되지 않습니다](https://github.com/helm/charts#deprecation-timeline). +아카이브를 `https://charts.helm.sh/stable` 에서 사용할 수 있지만 더 이상 업데이트를 받을 수 없습니다. + +다음 명령을 실행하여 저장소를 수정할 수 있습니다. + +```console +$ helm repo add stable https://charts.helm.sh/stable --force-update +``` + +https://charts.helm.sh/incubator 에서 사용할 수 있는 아카이브가 있는 `incubator` 저장소도 마찬가지입니다. +다음 명령을 실행하여 고칠 수 있습니다. + +```console +$ helm repo add incubator https://charts.helm.sh/incubator --force-update +``` + +### 'WARNING: "kubernetes-charts.storage.googleapis.com" is deprecated for "stable" and will be deleted Nov. 13, 2020.'라는 경고가 표시됩니다. + +기존의 구글 헬름 차트 저장소가 새로운 헬름 차트 저장소로 대체되었습니다. + +다음 명령을 실행하여 이 문제를 해결합니다. + +```console +$ helm repo add stable https://charts.helm.sh/stable --force-update +``` + +`incubator` 에 비슷한 오류가 발생한다면 다음 명령을 실행합니다. + +```console +$ helm repo add incubator https://charts.helm.sh/incubator --force-update +``` + +### 헬름 저장소를 추가하면 'Error: Repo "https://kubernetes-charts.storage.googleapis.com" is no longer available'라는 오류가 표시됩니다. + +헬름 차트 저장소는 [1년 동안의 유예기간](https://github.com/helm/charts#deprecation-timeline)이 지나면 더 이상 지원되지 않습니다. +해당 저장소의 아카이브는 `https://charts.helm.sh/stable` 및 `https://charts.helm.sh/incubator` 에서 사용할 수 있지만, 더 이상 업데이트되지 않습니다. +`--use-deprecated-repos` 를 지정하지 않으면 `helm repo add` 명령어로 기존 저장소의 URL을 추가할 수 없습니다. + +### GKE (구글 컨테이너 엔진)에서 "현재 열려 있는 SSH 터널이 없습니다"라고 나와요 + +``` +Error: Error forwarding ports: error upgrading connection: No SSH tunnels currently open. Were the targets able to accept an ssh-key for user "gke-[redacted]"? +``` + +오류 메시지의 또 다른 변형판은 다음과 같습니다. + + +``` +Unable to connect to the server: x509: certificate signed by unknown authority +``` + +해당 이슈는 로컬 쿠버네티스 설정 파일에 올바른 인증서가 있어야 한다는 +것입니다. + +GKE에 클러스터를 생성하면 SSL 인증서 및 인증 기관을 포함한 +인증서가 제공됩니다. 이러한 파일은 `kubectl`과 `helm`이 +접근할 수 있도록 쿠버네티스 설정 파일에 저장되어야 +합니다(기본값: `~/.kube/config`). + +### 헬름 2에서 마이그레이션한 후, `helm list`에는 릴리스들이 일부만 보여요(또는 안 보여요). + +헬름 3는 이제 클러스터 네임스페이스를 사용하여 릴리스들을 +구획한다는 사실을 깜빡하신 것 같습니다. +릴리스를 참조하는 모든 명령어는 다음 중 하나로 수행해야 합니다. + +* 활성 쿠버네티스 컨텍스트의 현재 네임스페이스에 의존합니다 + (`kubectl config view --minify` 명령어로 확인). +* `--namespace`/`-n` 플래그를 사용하여 올바른 네임스페이스를 지정합니다. +* `helm list` 명령어에 대해서는 `--all-namespaces`/`-A` 플래그를 지정합니다. + +이는 릴리스를 참조하는 `helm list`, `helm uninstall` 및 +기타 모든 `helm` 명령어에 적용됩니다. + + +### 맥OS에서는 `/etc/.mdns_debug` 파일에 접근합니다. 왜 그런가요? + +맥OS에서는 헬름이 `/etc/.mdns_debug`라는 파일에 접근하려고 +하는 것으로 알려져 있습니다. 파일이 있는 경우, 헬름은 파일이 실행되는 동안 +파일 핸들을 열어 둡니다. + +이 문제는 맥OS의 MDNS 라이브러리로 인해 발생합니다. +디버깅 설정을 읽기 위해 MDNS 라이브러리를 로드하려고 시도합니다(활성화된 경우). +파일 핸들을 열지 말아야 하며, 이 문제는 애플(Apple)에도 보고되었습니다. +다만, 이러한 동작을 일으키는 것은 헬름이 아닌 맥OS입니다. + +헬름이 이 파일을 로드하지 않도록 하려면 호스트 네트워크 스택을 사용하지 않는 +정적 라이브러리로서 헬름을 컴파일하면 됩니다. 이렇게 하면 헬름의 바이너리 크기가 +커지기는 하지만, 그 파일이 열리는 것은 막을 수 있습니다. + +이 문제는 원래 잠재적인 보안 문제로 분류되기도 했습니다. +그러나 이후 이 동작으로 인한 결함이나 취약점은 없는 것으로 판명되었습니다. + +### helm repo add가 동작한 후 실패합니다. + +헬름 3.3.1 및 이전 버전에서 이미 존재하는 저장소(repo)를 추가하려고 하면 +`helm repo add ` 명령어를 실행해도 출력되는 내용은 없습니다. +`--no-update` 플래그를 사용하면 저장소가 이미 등록되어 있는 경우 오류를 발생시킵니다. + +헬름 3.3.2 이상에서 기존 저장소를 추가하려고 하면 다음 오류가 발생합니다. + +`Error: repository name (reponame) already exists, please specify a different name` + +이제 기본 동작은 반대가 됩니다. `--no-update`는 이제 무시되며, +기존 저장소를 교체(덮어쓰기)하려면 `--force-update`를 사용할 수 있습니다. + +이는 [헬름 3.3.2 릴리스 노트](https://github.com/helm/helm/releases/tag/v3.3.2)에서 +설명된대로 보안 픽스에 따라 단절적 변경(breaking change)이 있었기 때문입니다. + +### 쿠버네티스 클라이언트 로깅 활성화 + +[klog](https://pkg.go.dev/k8s.io/klog) 플래그를 사용하여 쿠버네티스 클라이언트를 +디버깅하기 위한 로그 메시지를 출력할 수 있습니다. 대부분의 경우에는 `-v` 플래그를 +사용하여 자세한 수준(verbosity level)으로 설정하는 것만으로도 충분합니다. + +예시: + +``` +helm list -v 6 +``` \ No newline at end of file diff --git a/content/ko/docs/glossary/_index.md b/content/ko/docs/glossary/_index.md new file mode 100644 index 0000000000..e54e602e67 --- /dev/null +++ b/content/ko/docs/glossary/_index.md @@ -0,0 +1,157 @@ +--- +title: "용어집" +description: "헬름 아키텍처의 컴포넌트들을 기술하기 위해 사용된 용어." +weight: 9 +--- + +# 용어집 + +## 차트 + +쿠버네티스 클러스터 내에 리소스 세트를 설치하는 데 필요한 정보를 담고 있는 헬름 패키지 + +차트는 템플릿을 비롯하여 `Chart.yaml` 파일, 기본 값(`values.yaml`), 의존성(dependencies)을 포함한다. + +차트는 잘 정의된 디렉토리 구조 속에서 개발되며, _chart archive_라고 하는 아카이브 형식으로 패키징된다. + +## 차트 아카이브 + +_chart archive_는 tar와 gzip으로 (필요시 서명을 추가한) 묶인 차트이다. + +## 차트 의존성 (서브차트) + +차트는 다른 차트에 의존(depend)할 수 있다. 의존성을 일으키는 2가지 방법은 다음과 같다. + +- 약한 의존성: 클러스터에 다른 차트가 없으면 차트가 동작하지 않을 수 있다. + 헬름은 이런 경우에 필요한 도구를 제공하지 않으며, 별도로 의존성을 관리해야 한다. +- 강한 의존성: A chart may contain (inside of its `charts/` directory) + another chart upon which it depends. In this case, installing the chart will + install all of its dependencies. In this case, a chart and its dependencies + are managed as a collection. + +When a chart is packaged (via `helm package`) all of its hard dependencies are +bundled with it. + +## Chart Version + +Charts are versioned according to the [SemVer 2 spec](https://semver.org). A +version number is required on every chart. + +## Chart.yaml + +Information about a chart is stored in a special file called `Chart.yaml`. Every +chart must have this file. + +## Helm (and helm) + +Helm is the package manager for Kubernetes. As an operating system package +manager makes it easy to install tools on an OS, Helm makes it easy to install +applications and resources into Kubernetes clusters. + +While _Helm_ is the name of the project, the command line client is also named +`helm`. By convention, when speaking of the project, _Helm_ is capitalized. When +speaking of the client, _helm_ is in lowercase. + +## Helm Configuration Files (XDG) + +Helm stores its configuration files in XDG directories. These directories are +created the first time `helm` is run. + +## Kube Config (KUBECONFIG) + +The Helm client learns about Kubernetes clusters by using files in the _Kube +config_ file format. By default, Helm attempts to find this file in the place +where `kubectl` creates it (`$HOME/.kube/config`). + +## Lint (Linting) + +To _lint_ a chart is to validate that it follows the conventions and +requirements of the Helm chart standard. Helm provides tools to do this, notably +the `helm lint` command. + +## Provenance (Provenance file) + +Helm charts may be accompanied by a _provenance file_ which provides information +about where the chart came from and what it contains. + +Provenance files are one part of the Helm security story. A provenance contains +a cryptographic hash of the chart archive file, the Chart.yaml data, and a +signature block (an OpenPGP "clearsign" block). When coupled with a keychain, +this provides chart users with the ability to: + +- Validate that a chart was signed by a trusted party +- Validate that the chart file has not been tampered with +- Validate the contents of a chart metadata (`Chart.yaml`) +- Quickly match a chart to its provenance data + +Provenance files have the `.prov` extension, and can be served from a chart +repository server or any other HTTP server. + +## Release + +When a chart is installed, the Helm library creates a _release_ to track that +installation. + +A single chart may be installed many times into the same cluster, and create +many different releases. For example, one can install three PostgreSQL databases +by running `helm install` three times with a different release name. + +## Release Number (Release Version) + +A single release can be updated multiple times. A sequential counter is used to +track releases as they change. After a first `helm install`, a release will have +_release number_ 1. Each time a release is upgraded or rolled back, the release +number will be incremented. + +## Rollback + +A release can be upgraded to a newer chart or configuration. But since release +history is stored, a release can also be _rolled back_ to a previous release +number. This is done with the `helm rollback` command. + +Importantly, a rolled back release will receive a new release number. + +| Operation | Release Number | +|------------|------------------------------------------------------| +| install | release 1 | +| upgrade | release 2 | +| upgrade | release 3 | +| rollback 1 | release 4 (but running the same config as release 1) | + +The above table illustrates how release numbers increment across install, +upgrade, and rollback. + +## Helm Library (or SDK) + +The Helm Library (or SDK) refers to the Go code that interacts directly with the +Kubernetes API server to install, upgrade, query, and remove Kubernetes +resources. It can be imported into a project to use Helm as a client library +instead of a CLI. + +## Repository (Repo, Chart Repository) + +Helm charts may be stored on dedicated HTTP servers called _chart repositories_ +(_repositories_, or just _repos_). + +A chart repository server is a simple HTTP server that can serve an `index.yaml` +file that describes a batch of charts, and provides information on where each +chart can be downloaded from. (Many chart repositories serve the charts as well +as the `index.yaml` file.) + +A Helm client can point to zero or more chart repositories. By default, Helm +clients are not configured with any chart repositories. Chart repositories can +be added at any time using the `helm repo add` command. + +## Values (Values Files, values.yaml) + +Values provide a way to override template defaults with your own information. + +Helm Charts are "parameterized", which means the chart developer may expose +configuration that can be overridden at installation time. For example, a chart +may expose a `username` field that allows setting a user name for a service. + +These exposed variables are called _values_ in Helm parlance. + +Values can be set during `helm install` and `helm upgrade` operations, either by +passing them in directly, or by using a `values.yaml` file. + diff --git a/content/ko/docs/helm/_index.md b/content/ko/docs/helm/_index.md new file mode 100644 index 0000000000..544eaea03c --- /dev/null +++ b/content/ko/docs/helm/_index.md @@ -0,0 +1,10 @@ +--- +title: "헬름 명령어" +description: "헬름 CLI 명령어 전체 목록 문서" +weight: 6 +slug: helm +--- + +# 헬름 명령어 + +이곳에서 헬름 CLI 명령어 목록을 찾고, 그 사용법 정보를 얻을 수 있다. diff --git a/content/ko/docs/helm/helm.md b/content/ko/docs/helm/helm.md new file mode 100644 index 0000000000..0ee79b65db --- /dev/null +++ b/content/ko/docs/helm/helm.md @@ -0,0 +1,102 @@ +--- +title: "helm" +--- + +## helm + +쿠버네티스를 위한 헬름 패키지 매니저 + +### 개요 + +쿠버네티스 패키지 매니저 + +일반적으로 사용되는 헬름 작업: + +- helm search: 차트를 검색 +- helm pull: 확인하려는 로컬 디렉토리에 차트를 다운로드 +- helm install: 쿠버네티스에 차트 업로드 +- helm list: 차트 릴리스 리스트 표시 + +환경 변수: + +| Name | Description | +|------------------------------------|-----------------------------------------------------------------------------------| +| $HELM_CACHE_HOME | 캐시된 파일을 저장할 대체 위치를 지정 | +| $HELM_CONFIG_HOME | 헬름 설정을 저장할 대체 위치를 지정 | +| $HELM_DATA_HOME | 헬름 데이터를 저장할 대체 위치를 지정 | +| $HELM_DEBUG | 헬름이 디버그 모드에서 실행 중인지 여부 표시 | +| $HELM_DRIVER | 백엔드 스토리지 드라이버 설정. 값 : configmap, secret, memory, postgres | +| $HELM_DRIVER_SQL_CONNECTION_STRING | SQL 스토리지 드라이버가 사용해야 하는 연결 문자열 지정 | +| $HELM_MAX_HISTORY | 헬름 릴리스 내역의 최대 수 설정 | +| $HELM_NAMESPACE | 헬름 작업에 사용되는 네임스페이스 지정 | +| $HELM_NO_PLUGINS | 플러그인 비활성화. 비활성화 하기 위해 HELM_NO_PLUGINS=1 로 지정. | +| $HELM_PLUGINS | 플러그인 디렉토리에 대한 경로 설정 | +| $HELM_REGISTRY_CONFIG | 레지스트리 구성 파일의 경로를 설정 | +| $HELM_REPOSITORY_CACHE | 저장소 캐시 디렉토리에 대한 경로 설정 | +| $HELM_REPOSITORY_CONFIG | 레포지토리 파일의 경로 설정 | +| $KUBECONFIG | 대체 쿠버네티스 설정 파일 지정 (기본값 "~/.kube/config") | +| $HELM_KUBEAPISERVER | 인증을 위한 쿠버네티스 API 서버의 엔트포인트 설정 | +| $HELM_KUBEASGROUPS | 작업을 가장(impersonation)할 사용자 이름 설정 | +| $HELM_KUBEASUSER | 쉼표로 구분된 목록을 사용하여, 작업을 가장할 그룹 지정 | +| $HELM_KUBECONTEXT | kubeconfig 컨텍스트의 이름 설정 | +| $HELM_KUBETOKEN | 인증에 사용되는 베어러(Bearer) KubeToken 설정 | + +헬름은 다음 설정 순서를 기반으로 캐시, 설정 정보, 데이터를 저장한다: + +- HOME_*_HOME 환경변수가 설정된 경우 이 변수를 사용함 +- 그렇지 않으면, XDG 기반 디렉토리 사양을 지원하는 시스템에서 XDG 변수를 사용함 +- 다른 위치를 설정하지 않은 경우 운영 체제의 기본 위치를 사용함 + +기본적으로 기본 디렉토리는 운영체제에 따라 다르며, 기본 값은 아래와 같다. + +| 운영체제 | 캐시 파일 경로 | 설정 파일 경로 | 데이터 저장 경로 | +|------------------|---------------------------|--------------------------------|-------------------------| +| Linux | $HOME/.cache/helm | $HOME/.config/helm | $HOME/.local/share/helm | +| macOS | $HOME/Library/Caches/helm | $HOME/Library/Preferences/helm | $HOME/Library/helm | +| Windows | %TEMP%\helm | %APPDATA%\helm | %APPDATA%\helm | + + +### 옵션 + +``` + --debug 장황한(verbose) 출력 활성화 + -h, --help helm 명령어에 대한 도움말 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-as-group stringArray 작업에 관해 제시할 그룹. 플래그를 여러 번 사용하여 여러 그룹 지정 가능 + --kube-as-user string 작업에 관해 제시할 사용자명 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용될 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + -n, --namespace string 이 요청에 대한 네임스페이스 스코프 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL 을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") +``` + +### 참조 + +* [helm completion](/docs/helm/helm_completion) - 지정된 셸(bash 또는 zsh)에 대한 자동 완성 스크립트 생성 +* [helm create](/docs/helm/helm_create) - 주어진 이름으로 새 차트 생성 +* [helm dependency](/docs/helm/helm_dependency) - 차트의 종속성 관리 +* [helm env](/docs/helm/helm_env) - 헬름 클라이언트 환경 정보 +* [helm get](/docs/helm/helm_get) - 명명된 릴리스의 확장 정보 다운로드 +* [helm history](/docs/helm/helm_history) - 릴리스 기록 가져오기 +* [helm install](/docs/helm/helm_install) - 차트 설치 +* [helm lint](/docs/helm/helm_lint) - 차트에서 발생 가능한 이슈 검사 +* [helm list](/docs/helm/helm_list) - 릴리스 목록 +* [helm package](/docs/helm/helm_package) - 차트 디렉토리를 차트 아카이브로 패키징 +* [helm plugin](/docs/helm/helm_plugin) - Helm 플러그인 설치, 조회, 제거 +* [helm pull](/docs/helm/helm_pull) - 저장소에서 차트를 다운로드하고 (선택적으로) 로컬디렉터리에 압축 해제 +* [helm repo](/docs/helm/helm_repo) - 차트 저장소의 추가, 조회, 제거, 업데이트 및 색인 생성 +* [helm rollback](/docs/helm/helm_rollback) - 릴리스를 이전 버전으로 롤백 +* [helm search](/docs/helm/helm_search) - 차트에서 키워드 검색 +* [helm show](/docs/helm/helm_show) - 차트 정보 표시 +* [helm status](/docs/helm/helm_status) - 명명된 릴리스의 상태 표시 +* [helm template](/docs/helm/helm_template) - 로컬에서 템플릿 렌더링 +* [helm test](/docs/helm/helm_test) - 릴리스 테스트 수행 +* [helm uninstall](/docs/helm/helm_uninstall) - 릴리스 제거 +* [helm upgrade](/docs/helm/helm_upgrade) - 릴리스 업그레이드 +* [helm verify](/docs/helm/helm_verify) - 지정된 경로의 차트의 서명 여부 및 유효성 여부 검증 +* [helm version](/docs/helm/helm_version) - 클라이언트 버전 정보 표시 + +###### Auto generated by spf13/cobra on 11-May-2020 diff --git a/content/ko/docs/helm/helm_completion.md b/content/ko/docs/helm/helm_completion.md new file mode 100644 index 0000000000..5a1a3d71cd --- /dev/null +++ b/content/ko/docs/helm/helm_completion.md @@ -0,0 +1,44 @@ +--- +title: "Helm Completion" +--- + +## helm completion + +지정될 셸에 대한 자동 스크립트 생성 + +### 개요 + + +지정된 셸의 헬름에 대한 자동 완성 스크립트를 생성한다. + + +### 옵션 + +``` + -h, --help helm completion 명령어에 대한 도움말 +``` + +### 부모 명령어에 상속된 옵션 + +``` + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-as-group stringArray 작업할 그룹 지정. 플래그를 반복하여 여러 그룹 지정도 가능 + --kube-as-user string 작업할 사용자 이름 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용될 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + -n, --namespace string 요청에 대한 네임스페이스 지정 + --registry-config string 레지스트리 구성에 대한 파일 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시 된 저장소 색인이 포함된 파일 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") +``` + +### 함께 보기 + +* [helm](helm.md) - 쿠버네티스 용 헬름 패키지 관리자 +* [helm completion bash](helm_completion_bash.md) - bash 용 자동 완성 스크립트 생성 +* [helm completion fish](helm_completion_fish.md) - fish 용 자동 완성 스크립트 생성 +* [helm completion zsh](helm_completion_zsh.md) - zsh 용 자동 완성 스크립트 생성 + +###### Auto generated by spf13/cobra on 29-Oct-2020 diff --git a/content/ko/docs/helm/helm_completion_bash.md b/content/ko/docs/helm/helm_completion_bash.md new file mode 100644 index 0000000000..8f3b742c23 --- /dev/null +++ b/content/ko/docs/helm/helm_completion_bash.md @@ -0,0 +1,68 @@ +--- +title: "Helm Completion - bash" +--- + +## helm completion bash + +bash에 대한 자동 완성 스크립트 생성 + +### 개요 + + +bash 셸의 헬름에 대한 자동 완성 스크립트를 생성한다. + +현재 셸 세션에서 완성 기능을 로드하려면: + + source <(helm completion bash) + +새로운 세션마다 완성 기능을 로드하려면 다음 작업을 한 번 실행한다: +- Linux: + + helm completion bash > /etc/bash_completion.d/helm + +- MacOS: + + helm completion bash > /usr/local/etc/bash_completion.d/helm + + +``` +helm completion bash +``` + +### 옵션 + +``` + -h, --help helm completion bash 명령어에 대한 도움말 +``` + +### 부모 명령어에 상속된 옵션들 + +``` + --add-dir-header 이 값이 참이면, 헤더에 파일 디렉토리를 추가 + --alsologtostderr 파일처럼 표준 오류로도 로그 출력 + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용될 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + --log-backtrace-at traceLocation 로깅 시 N행에 걸친 스택 추적 내용을 표시 (기본값 :0) + --log-dir string 값을 지정하면, 지정한 디렉토리에 로그 파일 기록 + --log-file string 값을 지정하면, 지정한 로그 파일 사용 + --log-file-max-size uint 로그파일이 증가할 수 있는 최대 크기 지정. 단위는 메가바이트이다. 값이 0이면, 최대 파일크기는 무제한. (기본값 1800) + --logtostderr 로그를 파일 대신 표준 출력으로 표시 (기본값 true) + -n, --namespace string 요청에 대한 네임스페이스 지정 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.config/helm/repository") + --repository-config string 저장소 이름 및 URL을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") + --skip-headers 이 값이 참이면, 로그파일에서 헤더 접두어를 미사용 + --skip-log-headers 이 값이 참이면, 로그파일을 열 때 헤더 제외 + --stderrthreshold severity stderr로 로그가 변경될 수 있는 최저 임계점 (기본값 2) + -v, --v Level 로그 수준 상세 표시 레벨 + --vmodule moduleSpec 파일로 필터링된 로깅을 위한 패턴=N 설정의 쉼표로 구분된 리스트 +``` + +### 참조 + +* [helm completion](/docs/helm/helm_completion) - 지정된 셸에 대한 자동 완성 스크립트 생성 + +###### Auto generated by spf13/cobra on 14-Sep-2020 diff --git a/content/ko/docs/helm/helm_completion_fish.md b/content/ko/docs/helm/helm_completion_fish.md new file mode 100644 index 0000000000..b7efbd9c4f --- /dev/null +++ b/content/ko/docs/helm/helm_completion_fish.md @@ -0,0 +1,56 @@ +--- +title: "Helm Completion - fish" +--- + +## helm completion fish + +fish에 대한 자동 완성 스크립트 생성 + +### 개요 + + +fish 셸의 헬름에 대한 자동 완성 스크립트를 생성한다. + +현재 셸 세션에서 completion 기능을 로드하려면: + + helm completion fish | source + +모든 새 세션에서 completion 기능을 로드하려면 다음 작업을 한 번 실행한다: + + helm completion fish > ~/.config/fish/completions/helm.fish + +이 설정을 적용하려면 새 셸을 시작해야 한다. + + +``` +helm completion fish [flags] +``` + +### 옵션 + +``` + -h, --help helm completion fish 명령어에 대한 도움말 + --no-descriptions completion 세부 정보 비활성화 +``` + +### 부모 명령어에 상속된 옵션 + +``` + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-as-group stringArray 작업할 그룹 지정. 플래그를 반복하여 여러 그룹 지정도 가능 + --kube-as-user string 작업할 사용자 이름 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용될 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + -n, --namespace string 요청에 대한 네임스페이스 지정 + --registry-config string 레지스트리 구성에 대한 파일 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시 된 저장소 색인이 포함된 파일 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") +``` + +### 함께 보기 + +* [helm completion](helm_completion.md) - 지정된 셸에 대한 자동 완성 스크립트 생성 + +###### Auto generated by spf13/cobra on 29-Oct-2020 diff --git a/content/ko/docs/helm/helm_completion_zsh.md b/content/ko/docs/helm/helm_completion_zsh.md new file mode 100644 index 0000000000..df2ac1e8d1 --- /dev/null +++ b/content/ko/docs/helm/helm_completion_zsh.md @@ -0,0 +1,63 @@ +--- +title: "Helm Completion - zsh" +--- + +## helm completion zsh + +zsh에 대한 자동 완성 스크립트 생성 + +### 개요 + + +zsh 셸의 헬름에 대한 자동 완성 스크립트를 생성한다. + +현재 셸 세션에서 완성 기능을 로드하려면: + + source <(helm completion zsh) + +새로운 세션마다 완성 기능을 로드하려면 다음 작업을 한 번 실행한다: + + helm completion zsh > "${fpath[1]}/_helm" + + +``` +helm completion zsh [flags] +``` + +### 옵션 + +``` + -h, --help helm completion zsh 명령어에 대한 도움말 +``` + +### 부모 명령어에 상속된 옵션들 + +``` + --add-dir-header 이 값이 참이면, 헤더에 파일 디렉토리를 추가 + --alsologtostderr 파일처럼 표준 오류로도 로그 출력 + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용될 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + --log-backtrace-at traceLocation 로깅 시 N행에 걸친 스택 추적 내용을 표시 (기본값 :0) + --log-dir string 값을 지정하면, 지정한 디렉토리에 로그 파일 기록 + --log-file string 값을 지정하면, 지정한 로그 파일 사용 + --log-file-max-size uint 로그파일이 증가할 수 있는 최대 크기 지정. 단위는 메가바이트이다. 값이 0이면, 최대 파일크기는 무제한. (기본값 1800) + --logtostderr 로그를 파일 대신 표준 출력으로 표시 (기본값 true) + -n, --namespace string 요청에 대한 네임스페이스 지정 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.config/helm/repository") + --repository-config string 저장소 이름 및 URL을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") + --skip-headers 이 값이 참이면, 로그파일에서 헤더 접두어를 미사용 + --skip-log-headers 이 값이 참이면, 로그파일을 열 때 헤더 제외 + --stderrthreshold severity stderr로 로그가 변경될 수 있는 최저 임계점 (기본값 2) + -v, --v Level 로그 수준 상세 표시 레벨 + --vmodule moduleSpec 파일로 필터링된 로깅을 위한 패턴=N 설정의 쉼표로 구분된 리스트 +``` + +### 참조 + +* [helm completion](/docs/helm/helm_completion) - 지정된 셸에 대한 자동 완성 스크립트 생성 + +###### Auto generated by spf13/cobra on 14-Sep-2020 diff --git a/content/ko/docs/helm/helm_create.md b/content/ko/docs/helm/helm_create.md new file mode 100644 index 0000000000..f2c3d24ab3 --- /dev/null +++ b/content/ko/docs/helm/helm_create.md @@ -0,0 +1,73 @@ +--- +title: "Helm Create" +--- + +## helm create + +주어진 이름으로 새로운 차트를 생성 + +### 개요 + + +이 명령은 차트에 사용되는 공통 파일 및 디렉토리와 함께 +차트 디렉토리를 만든다. + +예를 들어, 'helm create foo' 는 다음과 같은 디렉토리 +구조를 생성한다: + + foo/ + ├── .helmignore # 헬름 차트를 패키징할 때 무시할 패턴 포함 + ├── Chart.yaml # 차트에 대한 정보 + ├── values.yaml # 템플릿의 기본값 + ├── charts/ # 이 차트가 의존하는 차트 + └── templates/ # 템플릿 파일 + └── tests/ # 테스트 파일 + +'helm create' 는 인수로 경로를 받는다. 지정된 경로에 디렉토리가 +존재하지 않으면 헬름은 디렉토리를 생성하려고 시도할 것이다. +지정된 대상이 있고 해당 디렉토리에 파일이 있으면 충돌하는 파일을 +덮어 쓰지만 다른 파일은 그대로 둔다. + + +``` +helm create NAME [flags] +``` + +### 옵션 + +``` + -h, --help create에 대한 도움말 + -p, --starter string 헬름 스타터 재료의 이름 또는 절대 경로 +``` + +### 부모 명령어에서 상속된 옵션들 + +``` + --add-dir-header 이 값이 참이면, 헤더에 파일 디렉토리를 추가 + --alsologtostderr 표준 오류를 로그 및 파일로 표시 + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용될 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + --log-backtrace-at traceLocation 로깅 시 N 행에 걸친 스택 추적 내용을 표시 (기본값 :0) + --log-dir string 값을 지정하면, 지정한 디렉토리에 로그 파일 기록 + --log-file string 값을 지정하면, 지정한 로그 파일 사용 + --log-file-max-size uint 로그파일이 증가할 수 있는 최대 크기 지정. 단위는 메가바이트이다. 값이 0이면, 최대 파일크기는 무제한. (기본값 1800) + --logtostderr 로그를 파일이 아닌 표준 출력으로 표시 (기본값 true) + -n, --namespace string 요청에 대한 네임스페이스 지정 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL 을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") + --skip-headers 이 값이 true이면, 로그파일에서 헤더 접두어를 미사용 + --skip-log-headers 이 값이 true이면, 로그파일을 열 때 헤더 제외 + --stderrthreshold severity stderr로 로그가 변경될 수 있는 최저 임계점 (기본값 2) + -v, --v Level 로그 수준 상세표시 레벨 + --vmodule moduleSpec 파일로 필터링된 로깅을 위한 패턴=N 설정의 쉼표로 구분된 리스트 +``` + +### 참조 + +* [helm](../helm) - 쿠버네티스에 대한 헬름 패키지 매니저. + +###### Auto generated by spf13/cobra on 11-May-2020 diff --git a/content/ko/docs/helm/helm_dependency.md b/content/ko/docs/helm/helm_dependency.md new file mode 100644 index 0000000000..d444ec301e --- /dev/null +++ b/content/ko/docs/helm/helm_dependency.md @@ -0,0 +1,88 @@ +--- +title: "Helm Dependency" +--- + +## helm dependency + +차트의 종속성을 관리 + +### 개요 + + +차트의 종속성을 관리한다. + +헬름 차트는 종속성을 'charts/' 에 저장한다. 차트 개발자의 경우 +모든 종속성을 선언하는 'Chart.yaml' 에서 종속성을 관리하는 것이 +더 쉬운 경우가 많다. + +종속성 명령은 해당 파일에서 작동하므로 원하는 종속성과 +'charts/' 디렉토리에 저장된 실제 종속성을 쉽게 +동기화 할 수 있다. + +예를 들어 이 Chart.yaml 은 두 가지 종속성을 선언한다. + + # Chart.yaml + dependencies: + - name: nginx + version: "1.2.3" + repository: "https://example.com/charts" + - name: memcached + version: "3.2.1" + repository: "https://another.example.com/charts" + + +'name' 은 차트의 이름이어야 한다. 여기서 해당 이름은 해당 차트의 +'Chart.yaml' 파일에 있는 이름과 일치해야 한다. + +'version' 필드에는 의미론적 버전 또는 버전 범위가 포함되어야 한다. + +'repository' URL은 차트 레포지터리를 가리켜야한다. 헬름은 URL 에 +'/index.yaml' 을 추가하여 차트 저장소의 색인을 검색할 수 있어야 한다고 예상한다. +참고: 'repository' 는 별칭이 될 수도 있다. 별칭은 +'alias:' 나 '@'로 시작해야 한다. + +2.2.0 부터는 저장소는 로컬에 저장된 종속성 차트의 디렉토리 경로로 정의할 +수 있다. 경로는 "file://" 접두사로 시작해야 한다. +예를 들면, + + # Chart.yaml + dependencies: + - name: nginx + version: "1.2.3" + repository: "file://../dependency_chart/nginx" + +종속성 차트가 로컬로 검색되는 경우 "helm add repo" 를 통해 +저장소를 헬름에 추가할 필요가 없다. 이 경우 버전 일치 +또한 지원된다. + + +### 옵션 + +``` + -h, --help helm dependency 명령어의 도움말 +``` + +### 부모 명령어에서 상속된 옵션들 + +``` + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-as-group stringArray 작업에 관해 제시할 그룹. 플래그를 여러 번 사용하여 여러 그룹 지정 가능 + --kube-as-user string 작업에 관해 제시할 사용자명 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용될 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + -n, --namespace string 이 요청에 대한 네임스페이스 스코프 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL 을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") +``` + +### 함께 보기 + +* [helm](helm.md) - 쿠버네티스에 대한 헬름 패키지 매니저. +* [helm dependency build](helm_dependency_build.md) - Chart.lock 파일을 기반으로 charts/ 디렉토리를 다시 빌드 +* [helm dependency list](helm_dependency_list.md) - 주어진 차트에 대한 종속성 나열 +* [helm dependency update](helm_dependency_update.md) - Chart.yaml 의 내용에 따라 charts/ 업데이트 + +###### Auto generated by spf13/cobra on 29-Oct-2020 diff --git a/content/ko/docs/helm/helm_dependency_build.md b/content/ko/docs/helm/helm_dependency_build.md new file mode 100644 index 0000000000..a7e14a5683 --- /dev/null +++ b/content/ko/docs/helm/helm_dependency_build.md @@ -0,0 +1,55 @@ +--- +title: "Helm Dependency Build" +--- + +## helm dependency build + +Chart.lock 파일을 기반으로 charts/ 디렉토리를 다시 빌드 + +### 개요 + + +Chart.lock 파일에서 charts/ 디렉토리를 빌드한다. + +빌드는 잠금파일에 지정된 상태에 대한 차트의 종속성을 재구성하는데 +사용된다. 이것은 'helm dependency update' 처럼 +종속성을 다시 재협상하지 않는다. + +잠금 파일이 없으면 'helm dependency build'는 +'helm dependency update'의 동작을 미러링합니다. + + + +``` +helm dependency build CHART [flags] +``` + +### 옵션 + +``` + -h, --help helm dependency build 명령어에 대한 도움말 + --keyring string 공개 키를 포함하는 키링 (기본값 "~/.gnupg/pubring.gpg") + --verify 서명과 비교하여 패키지 확인 +``` + +### 부모 명령어에서 상속된 옵션들 + +``` + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-as-group stringArray 작업에 관해 제시할 그룹. 플래그를 여러 번 사용하여 여러 그룹 지정 가능 + --kube-as-user string 작업에 관해 제시할 사용자명 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용될 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + -n, --namespace string 이 요청에 대한 네임스페이스 스코프 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL 을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") +``` + +### 함께 보기 + +* [helm dependency](helm_dependency.md) - 차트의 종속성을 관리 + +###### Auto generated by spf13/cobra on 29-Oct-2020 diff --git a/content/ko/docs/helm/helm_dependency_list.md b/content/ko/docs/helm/helm_dependency_list.md new file mode 100644 index 0000000000..78eba0a080 --- /dev/null +++ b/content/ko/docs/helm/helm_dependency_list.md @@ -0,0 +1,50 @@ +--- +title: "Helm Dependency List" +--- + +## helm dependency list + +주어진 차트에 대한 종속성을 나열 + +### 개요 + + +차트에 선언된 모든 종속성을 나열한다. + +이것은 차트 아카이브 및 차트 디렉토리를 입력으로 사용할수 있다. +차트의 내용은 변경되지 않는다. + +차트를 로드할 수 없는 경우 오류가 발생한다. + + +``` +helm dependency list CHART [flags] +``` + +### 옵션 + +``` + -h, --help helm dependency list 명령어에 대한 도움말 +``` + +### 부모 명령어에서 상속된 옵션들 + +``` + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-as-group stringArray 작업에 관해 제시할 그룹. 플래그를 여러 번 사용하여 여러 그룹 지정 가능 + --kube-as-user string 작업에 관해 제시할 사용자명 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용될 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + -n, --namespace string 이 요청에 대한 네임스페이스 스코프 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL 을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") +``` + +### 함께 보기 + +* [helm dependency](helm_dependency.md) - 차트의 종속성을 관리 + +###### Auto generated by spf13/cobra on 29-Oct-2020 diff --git a/content/ko/docs/helm/helm_dependency_update.md b/content/ko/docs/helm/helm_dependency_update.md new file mode 100644 index 0000000000..39d1d55629 --- /dev/null +++ b/content/ko/docs/helm/helm_dependency_update.md @@ -0,0 +1,59 @@ +--- +title: "Helm Dependency Update" +--- + +## helm dependency update + +Chart.yaml 의 내용에 따라 charts/ 업데이트 + +### 개요 + + +Chart.yaml 을 미러링하도록 온-디스크 종속성을 업데이트한다. + +이 명령은 'Chart.yaml' 에 표현된 필수 차트가 'charts/' 에 +있고 허용 가능한 버전인지를 확인한다. 종속성을 충족하는 최신 차트를 +풀다운(pull down)하고 이전 종속성을 정리한다. + +업데이트가 성공하면 종속성을 정확한 버전으로 다시 +빌드하는데 사용할 수 있는 잠금파일이 생성된다. + +종속성은 'Chart.yaml' 에 표시할 필요가 없다. 따라서 업데이트 명령은 +차트가 (a)Chart.yaml 파일에 있지만, (b)잘못된 버전이 아니면 +차트를 제거하지 않는다. + + +``` +helm dependency update CHART [flags] +``` + +### 옵션 + +``` + -h, --help helm dependency update 명령어에 대한 도움말 + --keyring string 공개키를 포함하는 키링 (기본값 "~/.gnupg/pubring.gpg") + --skip-refresh 로컬 저장소 캐시를 새로 고치지 않음 + --verify 서명과 비교하여 패키지를 확인 +``` + +### 부모 명령어에서 상속된 옵션들 + +``` + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-as-group stringArray 작업에 관해 제시할 그룹. 플래그를 여러 번 사용하여 여러 그룹 지정 가능 + --kube-as-user string 작업에 관해 제시할 사용자명 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용될 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + -n, --namespace string 이 요청에 대한 네임스페이스 스코프 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL 을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") +``` + +### 함께 보기 + +* [helm dependency](helm_dependency.md) - 차트의 종속성을 관리 + +###### Auto generated by spf13/cobra on 29-Oct-2020 diff --git a/content/ko/docs/helm/helm_env.md b/content/ko/docs/helm/helm_env.md new file mode 100644 index 0000000000..e000ed67e9 --- /dev/null +++ b/content/ko/docs/helm/helm_env.md @@ -0,0 +1,55 @@ +--- +title: "Helm Env" +--- + +## helm env + +헬름 클라이언트 환경변수 정보 + +### 개요 + + +Env 는 헬름에서 사용 중인 모든 환경변수 정보를 출력한다. + + +``` +helm env [flags] +``` + +### 옵션 + +``` + -h, --help env 에 대한 도움말 +``` + +### 부모 명령어에서 상속된 옵션들 + +``` + --add-dir-header 이 값이 참이면, 헤더에 파일 디렉토리를 추가 + --alsologtostderr 표준 오류를 로그 및 파일로 표시 + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용될 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + --log-backtrace-at traceLocation 로깅 시 N 행에 걸친 스택 추적 내용을 표시 (기본값 :0) + --log-dir string 값을 지정하면, 지정한 디렉토리에 로그 파일 기록 + --log-file string 값을 지정하면, 지정한 로그 파일 사용 + --log-file-max-size uint 로그파일이 증가할 수 있는 최대 크기 지정. 단위는 메가바이트이다. 값이 0이면, 최대 파일크기는 무제한. (기본값 1800) + --logtostderr 로그를 파일이 아닌 표준 출력으로 표시 (기본값 true) + -n, --namespace string 요청에 대한 네임스페이스 지정 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL 을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") + --skip-headers 이 값이 true이면, 로그파일에서 헤더 접두어를 미사용 + --skip-log-headers 이 값이 true이면, 로그파일을 열 때 헤더 제외 + --stderrthreshold severity stderr로 로그가 변경될 수 있는 최저 임계점 (기본값 2) + -v, --v Level 로그 수준 상세표시 레벨 + --vmodule moduleSpec 파일로 필터링된 로깅을 위한 패턴=N 설정의 쉼표로 구분된 리스트 +``` + +### 참조 + +* [helm](../helm) - 쿠버네티스에 대한 헬름 패키지 매니저. + +###### Auto generated by spf13/cobra on 11-May-2020 diff --git a/content/ko/docs/helm/helm_get.md b/content/ko/docs/helm/helm_get.md new file mode 100644 index 0000000000..01f73255bc --- /dev/null +++ b/content/ko/docs/helm/helm_get.md @@ -0,0 +1,62 @@ +--- +title: "Helm Get" +--- + +## helm get + +명명된 릴리스의 확장 정보 다운로드 + +### 개요 + + +이 명령은 다음을 포함하여 릴리스에 대한 확장 정보를 가져오는 데 사용할 수 있는 +여러가지 하위 명령으로 구성된다. + +- 릴리스 생성에 사용되는 값 +- 생성된 매니페스트 파일 +- 릴리스 차트에서 제공하는 노트 +- 릴리스와 관련된 훅(hooks) + + +### 옵션 + +``` + -h, --help get 에 대한 도움말 +``` + +### 부모 명령어에서 상속된 옵션들 + +``` + --add-dir-header 이 값이 true이면, 헤더에 파일 디렉토리를 추가한다 + --alsologtostderr 파일처럼 표준오류(stderr)로도 로그 출력 + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용할 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + --log-backtrace-at traceLocation 로깅 시 N 행에 걸친 스택 추적 내용을 표시 (기본값 :0) + --log-dir string 값을 지정하면, 지정한 디렉토리에 로그 파일 기록 + --log-file string 값을 지정하면, 지정한 로그 파일 사용 + --log-file-max-size uint 로그파일이 증가할 수 있는 최대 크기 지정. 단위는 메가바이트이다. 값이 0이면, 최대 파일크기는 무제한. (기본값 1800) + --logtostderr 로그를 파일이 아닌 표준 출력으로 표시 (기본값 true) + -n, --namespace string 요청에 대한 네임스페이스 지정 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") + --skip-headers 이 값이 true이면, 로그파일에서 헤더 접두어를 미사용 + --skip-log-headers 이 값이 true이면, 로그파일을 열 때 헤더 제외 + --stderrthreshold severity 이 기준점 이상일 때 표준오류(stderr)로 로그가 출력된다 (기본값 2) + -v, --v Level 로그 상세표시 레벨 + --vmodule moduleSpec 파일로 필터링된 로깅을 위한 패턴=N 설정의 쉼표로 구분된 리스트 +``` + +### 참조 + +* [helm](../helm) - 쿠버네티스에 대한 헬름 패키지 매니저. +* [helm get all](helm_get_all.md) - 명명된 릴리스에 대한 모든 정보 다운로드 +* [helm get hooks](helm_get_hooks.md) - 명명된 릴리스에 대한 모든 훅 다운로드 +* [helm get manifest](helm_get_manifest.md) - 명명된 릴리스에 대한 매니페스트 다운로드 +* [helm get notes](helm_get_notes.md) - 명명된 릴리스에 대한 노트 다운로드 +* [helm get values](helm_get_values.md) - 명명된 릴리스에 대한 값 파일 다운로드 + +###### Auto generated by spf13/cobra on 11-May-2020 diff --git a/content/ko/docs/helm/helm_get_all.md b/content/ko/docs/helm/helm_get_all.md new file mode 100644 index 0000000000..b25aadcf45 --- /dev/null +++ b/content/ko/docs/helm/helm_get_all.md @@ -0,0 +1,58 @@ +--- +title: "Helm Get All" +--- + +## helm get all + +명명된 릴리스에 대한 모든 정보 다운로드 + +### 개요 + + +이 명령어는 지정한 릴리스에서 노트, 훅, 제공된 값 및 생성된 +매니페스트 파일에 대한 정보를 사람이 읽을 수 있는 콜렉션으로 출력한다. + + +``` +helm get all RELEASE_NAME [flags] +``` + +### 옵션 + +``` + -h, --help all 에 대한 도움말 + --revision int 리비전으로 명명된 릴리스 가져오기 + --template string 출력 형식 지정을 위한 go 템플릿. 예: {{.Release.Name}} +``` + +### 부모 명령어에서 상속된 옵션들 + +``` + --add-dir-header 이 값이 true이면, 헤더에 파일 디렉토리를 추가한다 + --alsologtostderr 파일처럼 표준오류(stderr)로도 로그 출력 + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용할 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + --log-backtrace-at traceLocation 로깅 시 N 행에 걸친 스택 추적 내용을 표시 (기본값 :0) + --log-dir string 값을 지정하면, 지정한 디렉토리에 로그 파일 기록 + --log-file string 값을 지정하면, 지정한 로그 파일 사용 + --log-file-max-size uint 로그파일이 증가할 수 있는 최대 크기 지정. 단위는 메가바이트이다. 값이 0이면, 최대 파일크기는 무제한. (기본값 1800) + --logtostderr 로그를 파일이 아닌 표준 출력으로 표시 (기본값 true) + -n, --namespace string 요청에 대한 네임스페이스 지정 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") + --skip-headers 이 값이 true이면, 로그파일에서 헤더 접두어를 미사용 + --skip-log-headers 이 값이 true이면, 로그파일을 열 때 헤더 제외 + --stderrthreshold severity 이 기준점 이상일 때 표준오류(stderr)로 로그가 출력된다 (기본값 2) + -v, --v Level 로그 상세표시 레벨 + --vmodule moduleSpec 파일로 필터링된 로깅을 위한 패턴=N 설정의 쉼표로 구분된 리스트 +``` + +### 참조 + +* [helm get](helm_get.md) - 명명된 릴리스의 확장 정보 다운로드 + +###### Auto generated by spf13/cobra on 11-May-2020 diff --git a/content/ko/docs/helm/helm_get_hooks.md b/content/ko/docs/helm/helm_get_hooks.md new file mode 100644 index 0000000000..a17e8ae3ad --- /dev/null +++ b/content/ko/docs/helm/helm_get_hooks.md @@ -0,0 +1,58 @@ +--- +title: "Helm Get Hooks" +--- + +## helm get hooks + +명명된 릴리스에 대한 모든 훅 다운로드 + +### 개요 + + +이 명령어는 지정한 릴리스에 대한 훅을 다운로드한다. + +훅은 YAML로 형식이며 YAML '---\n' 구분자로 구분된다. + + +``` +helm get hooks RELEASE_NAME [flags] +``` + +### 옵션 + +``` + -h, --help hooks 에 대한 도움말 + --revision int 리비전으로 명명된 릴리스 가져오기 +``` + +### 부모 명령어에서 상속된 옵션들 + +``` + --add-dir-header 이 값이 true이면, 헤더에 파일 디렉토리를 추가한다 + --alsologtostderr 파일처럼 표준오류(stderr)로도 로그 출력 + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용할 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + --log-backtrace-at traceLocation 로깅 시 N 행에 걸친 스택 추적 내용을 표시 (기본값 :0) + --log-dir string 값을 지정하면, 지정한 디렉토리에 로그 파일 기록 + --log-file string 값을 지정하면, 지정한 로그 파일 사용 + --log-file-max-size uint 로그파일이 증가할 수 있는 최대 크기 지정. 단위는 메가바이트이다. 값이 0이면, 최대 파일크기는 무제한. (기본값 1800) + --logtostderr 로그를 파일이 아닌 표준 출력으로 표시 (기본값 true) + -n, --namespace string 요청에 대한 네임스페이스 지정 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") + --skip-headers 이 값이 true이면, 로그파일에서 헤더 접두어를 미사용 + --skip-log-headers 이 값이 true이면, 로그파일을 열 때 헤더 제외 + --stderrthreshold severity 이 기준점 이상일 때 표준오류(stderr)로 로그가 출력된다 (기본값 2) + -v, --v Level 로그 상세표시 레벨 + --vmodule moduleSpec 파일로 필터링된 로깅을 위한 패턴=N 설정의 쉼표로 구분된 리스트 +``` + +### 참조 + +* [helm get](helm_get.md) - 명명된 릴리스의 확장 정보 다운로드 + +###### Auto generated by spf13/cobra on 11-May-2020 diff --git a/content/ko/docs/helm/helm_get_manifest.md b/content/ko/docs/helm/helm_get_manifest.md new file mode 100644 index 0000000000..cdac01dda7 --- /dev/null +++ b/content/ko/docs/helm/helm_get_manifest.md @@ -0,0 +1,60 @@ +--- +title: "Helm Get Manifest" +--- + +## helm get manifest + +명명된 릴리스에 대한 매니페스트 다운로드 + +### 개요 + + +이 명령어는 지정한 릴리스에 대해 생성된 매니페스트를 가져온다. + +매니페스트는 이 릴리스의 차트에서 생성된 쿠버네티스 +리소스를 YAML 로 인코딩한 표현이다. 차트가 다른 +차트에 종속된 경우 해당 리소스도 매니페스트에 포함된다. + + +``` +helm get manifest RELEASE_NAME [flags] +``` + +### 옵션 + +``` + -h, --help manifest 에 대한 도움말 + --revision int 리비전으로 명명된 릴리스 가져오기 +``` + +### 부모 명령어에서 상속된 옵션들 + +``` + --add-dir-header 이 값이 true이면, 헤더에 파일 디렉토리를 추가한다 + --alsologtostderr 파일처럼 표준오류(stderr)로도 로그 출력 + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용할 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + --log-backtrace-at traceLocation 로깅 시 N 행에 걸친 스택 추적 내용을 표시 (기본값 :0) + --log-dir string 값을 지정하면, 지정한 디렉토리에 로그 파일 기록 + --log-file string 값을 지정하면, 지정한 로그 파일 사용 + --log-file-max-size uint 로그파일이 증가할 수 있는 최대 크기 지정. 단위는 메가바이트이다. 값이 0이면, 최대 파일크기는 무제한. (기본값 1800) + --logtostderr 로그를 파일이 아닌 표준 출력으로 표시 (기본값 true) + -n, --namespace string 요청에 대한 네임스페이스 지정 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") + --skip-headers 이 값이 true이면, 로그파일에서 헤더 접두어를 미사용 + --skip-log-headers 이 값이 true이면, 로그파일을 열 때 헤더 제외 + --stderrthreshold severity 이 기준점 이상일 때 표준오류(stderr)로 로그가 출력된다 (기본값 2) + -v, --v Level 로그 상세표시 레벨 + --vmodule moduleSpec 파일로 필터링된 로깅을 위한 패턴=N 설정의 쉼표로 구분된 리스트 +``` + +### 참조 + +* [helm get](helm_get.md) - 명명된 릴리스의 확장 정보 다운로드 + +###### Auto generated by spf13/cobra on 11-May-2020 diff --git a/content/ko/docs/helm/helm_get_notes.md b/content/ko/docs/helm/helm_get_notes.md new file mode 100644 index 0000000000..4e6da5f016 --- /dev/null +++ b/content/ko/docs/helm/helm_get_notes.md @@ -0,0 +1,56 @@ +--- +title: "Helm Get Notes" +--- + +## helm get notes + +명명된 릴리스에 대한 노트 다운로드 + +### 개요 + + +이 명령어는 명명된 릴리스의 차트에서 제공하는 노트를 보여준다. + + +``` +helm get notes RELEASE_NAME [flags] +``` + +### 옵션 + +``` + -h, --help notes 에 대한 도움말 + --revision int 리비전으로 명명된 릴리스 가져오기 +``` + +### 부모 명령어에서 상속된 옵션들 + +``` + --add-dir-header 이 값이 true이면, 헤더에 파일 디렉토리를 추가한다 + --alsologtostderr 파일처럼 표준오류(stderr)로도 로그 출력 + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용할 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + --log-backtrace-at traceLocation 로깅 시 N 행에 걸친 스택 추적 내용을 표시 (기본값 :0) + --log-dir string 값을 지정하면, 지정한 디렉토리에 로그 파일 기록 + --log-file string 값을 지정하면, 지정한 로그 파일 사용 + --log-file-max-size uint 로그파일이 증가할 수 있는 최대 크기 지정. 단위는 메가바이트이다. 값이 0이면, 최대 파일크기는 무제한. (기본값 1800) + --logtostderr 로그를 파일이 아닌 표준 출력으로 표시 (기본값 true) + -n, --namespace string 요청에 대한 네임스페이스 지정 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") + --skip-headers 이 값이 true이면, 로그파일에서 헤더 접두어를 미사용 + --skip-log-headers 이 값이 true이면, 로그파일을 열 때 헤더 제외 + --stderrthreshold severity 이 기준점 이상일 때 표준오류(stderr)로 로그가 출력된다 (기본값 2) + -v, --v Level 로그 상세표시 레벨 + --vmodule moduleSpec 파일로 필터링된 로깅을 위한 패턴=N 설정의 쉼표로 구분된 리스트 +``` + +### 참조 + +* [helm get](helm_get.md) - 명명된 릴리스의 확장 정보 다운로드 + +###### Auto generated by spf13/cobra on 11-May-2020 diff --git a/content/ko/docs/helm/helm_get_values.md b/content/ko/docs/helm/helm_get_values.md new file mode 100644 index 0000000000..9379d6d6f5 --- /dev/null +++ b/content/ko/docs/helm/helm_get_values.md @@ -0,0 +1,58 @@ +--- +title: "Helm Get Values" +--- + +## helm get values + +명명된 릴리스에 대한 값 파일 다운로드 + +### 개요 + + +이 명령어는 주어진 릴리스에 대한 값 파일을 다운로드한다. + + +``` +helm get values RELEASE_NAME [flags] +``` + +### 옵션 + +``` + -a, --all 모든 (계산 된) 값 덤프 + -h, --help values 에 대한 도움말 + -o, --output format 지정한 형식으로 출력을 표시. 허용되는 값: table, json, yaml (기본값 table) + --revision int 리비전으로 명명된 릴리스 가져오기 +``` + +### 부모 명령어에서 상속된 옵션들 + +``` + --add-dir-header 이 값이 true이면, 헤더에 파일 디렉토리를 추가한다 + --alsologtostderr 파일처럼 표준오류(stderr)로도 로그 출력 + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용할 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + --log-backtrace-at traceLocation 로깅 시 N 행에 걸친 스택 추적 내용을 표시 (기본값 :0) + --log-dir string 값을 지정하면, 지정한 디렉토리에 로그 파일 기록 + --log-file string 값을 지정하면, 지정한 로그 파일 사용 + --log-file-max-size uint 로그파일이 증가할 수 있는 최대 크기 지정. 단위는 메가바이트이다. 값이 0이면, 최대 파일크기는 무제한. (기본값 1800) + --logtostderr 로그를 파일이 아닌 표준 출력으로 표시 (기본값 true) + -n, --namespace string 요청에 대한 네임스페이스 지정 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") + --skip-headers 이 값이 true이면, 로그파일에서 헤더 접두어를 미사용 + --skip-log-headers 이 값이 true이면, 로그파일을 열 때 헤더 제외 + --stderrthreshold severity 이 기준점 이상일 때 표준오류(stderr)로 로그가 출력된다 (기본값 2) + -v, --v Level 로그 상세표시 레벨 + --vmodule moduleSpec 파일로 필터링된 로깅을 위한 패턴=N 설정의 쉼표로 구분된 리스트 +``` + +### 참조 + +* [helm get](helm_get.md) - 명명된 릴리스의 확장 정보 다운로드 + +###### Auto generated by spf13/cobra on 11-May-2020 diff --git a/content/ko/docs/helm/helm_history.md b/content/ko/docs/helm/helm_history.md new file mode 100644 index 0000000000..c6cb9e029c --- /dev/null +++ b/content/ko/docs/helm/helm_history.md @@ -0,0 +1,59 @@ +--- +title: "Helm History" +--- + +## helm history + +릴리스 히스토리를 가져온다. + +### 개요 + + +History 명령어는 주어진 릴리즈에 대한 리비젼 기록을 출력한다. + +기본 최대 256개 리비전이 반환된다. '--max' 설정은 반환되는 +리비젼 목록의 최대 길이를 지정한다. + +릴리스 기록은 형식이 지정된 테이블의 형태로 출력된다. 예: + + $ helm history angry-bird + REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION + 1 Mon Oct 3 10:15:13 2016 superseded alpine-0.1.0 1.0 Initial install + 2 Mon Oct 3 10:15:13 2016 superseded alpine-0.1.0 1.0 Upgraded successfully + 3 Mon Oct 3 10:15:13 2016 superseded alpine-0.1.0 1.0 Rolled back to 2 + 4 Mon Oct 3 10:15:13 2016 deployed alpine-0.1.0 1.0 Upgraded successfully + + +``` +helm history RELEASE_NAME [flags] +``` + +### 옵션 + +``` + -h, --help history 명령어에 대한 도움말 + --max int 기록에 포함할 최대 리비젼 수 (기본값 256개) + -o, --output format 지정된 형식으로 출력. 허용되는 값: table, json, yaml (기본값 table) +``` + +### 부모 명령어에서 상속된 옵션들 + +``` + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-as-group stringArray 작업에 관해 제시할 그룹. 플래그를 여러 번 사용하여 여러 그룹 지정 가능 + --kube-as-user string 작업에 관해 제시할 사용자명 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용될 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + -n, --namespace string 이 요청에 대한 네임스페이스 스코프 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL 을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm](../helm) - 쿠버네티스에 대한 헬름 패키지 매니저. + +###### Auto generated by spf13/cobra on 29-Oct-2020 diff --git a/content/ko/docs/helm/helm_install.md b/content/ko/docs/helm/helm_install.md new file mode 100644 index 0000000000..383d5224bf --- /dev/null +++ b/content/ko/docs/helm/helm_install.md @@ -0,0 +1,139 @@ +--- +title: "Helm Install" +--- + +## helm install + +차트를 설치한다. + +### 개요 + + +이 명령은 차트 아카이브를 설치한다. + +install 인수는 차트 참조, 패키지 된 차트 경로, +압축 해제 된 차트 디렉토리 경로 또는 URL 이어야한다. + +차트의 값을 재정의하려면 '--values' 플래그를 사용하고 파일을 전달하거나 +'--set' 플래그를 사용하고 명령 줄에서 구성을 전달하고 +문자열 값에 '--set-string' 을 사용한다. +값이 커서 '--values' 도 '--set' 도 사용하지 않으려면 +'--set-file' 을 사용하여 파일에서 하나의 큰 값을 읽도록 하자. + + $ helm install -f myvalues.yaml myredis ./redis + +또는 + + $ helm install --set name=prod myredis ./redis + +또는 + + $ helm install --set-string long_int=1234567890 myredis ./redis + +또는 + + $ helm install --set-file my_script=dothings.sh myredis ./redis + +'--values'/'-f' 플래그를 여러 번 지정할 수 있다. 지정된 마지막 (가장 오른쪽) 파일에 우선 순위가 부여된다. +예를 들어 myvalues.yaml 과 override.yaml 에 'Test' 라는 키가 포함 된 경우 +override.yaml에 설정된 값이 우선한다. + + $ helm install -f myvalues.yaml -f override.yaml myredis ./redis + +'--set' 플래그를 여러 번 지정할 수 있다. 지정된 마지막 (가장 오른쪽) 세트에 우선 순위가 부여된다. +예를 들어 'foo' 라는 키에 대해 'bar' 및 'newbar' 값이 모두 설정된 경우 +'newbar' 값이 우선한다. + + $ helm install --set foo=bar --set foo=newbar myredis ./redis + + +차트를 설치하지 않고 생성 된 릴리스의 매니페스트를 확인하려면 +'--debug' 및 '--dry-run' 플래그를 결합 할 수 있다. + +--verify가 설정된 경우 차트에는 출처 파일이 반드시 있어야하며 +출처 파일은 모든 확인 단계를 반드시 통과해야한다. + +설치할 차트를 표현할 수 있는 다섯가지 방법이 있다. + +1. 차트 참조 : helm install mymaria example/mariadb +2. 패키지 차트 경로 : helm install mynginx ./nginx-1.2.3.tgz +3. 압축을 푼 차트 디렉토리 경로 : helm install mynginx ./nginx +4. 절대 URL : helm install mynginx https://example.com/charts/nginx-1.2.3.tgz +5. 차트 참조 및 저장소 URL : helm install --repo https://example.com/charts/ mynginx nginx + +차트 참조(CHART REFERENCES) + +차트 참조는 차트 저장소에서 차트를 참조하는 편리한 방법이다. + +repo 접두사가 있는 차트 참조 ('example/mariadb')를 사용하면 +헬름은 로컬 구성에서 'example' 이라는 차트 저장소를 찾은 뒤 +이름이 'mariadb' 인 해당 저장소에서 차트를 찾는다. 개발 버전(알파, 베타 및 릴리스 후보 릴리스)도 +포함하도록 '--devel' 플래그를 지정하거나 '--version' 플래그와 +함께 버전 번호를 제공하지 않는 한, 해당 차트의 최신 안정 버전을 설치한다. + +차트 저장소 목록을 보려면 'helm repo list' 를 사용하자. +저장소에서 차트를 검색하려면 'helm search' 를 사용하자. + + +``` +helm install [NAME] [CHART] [flags] +``` + +### 옵션 + +``` + --atomic 설정된 경우 설치 프로세스는 실패시 설치를 삭제. --atomic 을 사용할 경우 --wait 플래그도 자동으로 설정. + --ca-file string 이 CA 번들을 사용하여 HTTPS 사용 서버의 인증서 확인 + --cert-file string 이 SSL 인증서 파일을 사용하여 HTTPS 클라이언트 식별 + --create-namespace 릴리스 네임스페이스가 없는 경우 생성 + --dependency-update 차트를 설치하기 전에 헬름 종속성 업데이트 실행 + --description string 사용자 정의 설명 추가 + --devel 개발 버전도 사용. 버전 '>0.0.0-0' 과 동일하며, --version 이 설정되어 있을 경우 무시 + --disable-openapi-validation 설정된 경우, 설치 프로세스는 쿠버네티스 OpenAPI 스키마에 대해 렌더링 된 템플릿의 유효성 검사 미수행 + --dry-run 모의 설치 + -g, --generate-name 이름을 생성 (그리고 NAME 매개 변수 생략) + -h, --help helm install 명령어에 대한 도움말 + --insecure-skip-tls-verify 차트 다운로드를 위한 TLS 인증서 검사 미수행 + --key-file string 이 SSL 키 파일을 사용하여 HTTPS 클라이언트 식별 + --keyring string 확인에 사용되는 공개키의 위치 (기본값 "~/.gnupg/pubring.gpg") + --name-template string 릴리스 이름을 지정하는데 사용되는 탬플릿 지정 + --no-hooks 설치 중 훅 실행 방지 + -o, --output format 지정된 형식으로 출력. 허용되는 값: table, json, yaml (기본값 table) + --password string 요청된 차트를 찾을 수 있는 차트 저장소 비밀번호 + --post-renderer postrenderer 포스트 렌더링에 사용될 실행 파일의 경로. $PATH에 있으면 바이너리가 사용되며 그렇지 않으면 주어진 경로에서 실행 파일을 탐색(기본 exec). + --render-subchart-notes 설정된 경우 상위 차트와 함께 하위 차트 메모를 렌더링 + --replace 해당 이름이 기록에 남아있는 삭제 된 릴리스 인 경우에만 주어진 이름을 재사용. 운영 환경에서는 안전하지 않기에 권장되지 않음 + --repo string 요청된 차트를 찾을 수 있는 차트 저장소 URL + --set stringArray 명령 줄에서 값 설정 (쉼표로 여러 값 또는 개별 값을 지정가능 : 키1 = 값1, 키2 = 값2) + --set-file stringArray 명령 줄을 통해 지정된 각 파일에서 값 설정 (쉼표로 여러 값 또는 개별 값을 지정가능 : 키1 = 경로1, 키2 = 경로2) + --set-string stringArray 명령 줄에서 STRING 값 설정 (쉼표로 여러 값 또는 개별 값을 지정가능 : 키1 = 값1, 키2 = 값2) + --skip-crds 설정된 경우, CRD 미설치. (기본적으로 CRD가 없는 경우에는 설치) + --timeout duration 개별 쿠버네티스 작업(예: 훅에 대한 작업)을 기다리는 시간 (기본값 5m0s) + --username string 요청된 차트를 찾을 수 있는 차트 저장소 사용자 이름 + -f, --values strings YAML 파일 또는 URL에 값 지정 (여러 개를 지정가능) + --verify 사용하기 전에 패키지 확인 + --version string 사용할 정확한 차트 버전을 지정. 지정하지 않으면 최신 버전이 사용 + --wait 설정된 경우, 릴리스를 성공으로 표시하기 전에 모든 파드, PVC, 서비스, 디플로이먼트, 스테이트풀셋, 레플리카셋의 최소 파드 수가 Ready 상태가 될 때까지 --timeout 만큼 대기 +``` + +### 부모 명령어에서 상속된 옵션들 + +``` + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-as-group stringArray 작업에 관해 제시할 그룹. 플래그를 여러 번 사용하여 여러 그룹 지정 가능 + --kube-as-user string 작업에 관해 제시할 사용자명 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용될 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + -n, --namespace string 이 요청에 대한 네임스페이스 스코프 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL 을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") +``` + +### 함께 보기 + +* [helm](helm.md) - 쿠버네티스에 대한 헬름 패키지 매니저. + +###### Auto generated by spf13/cobra on 29-Oct-2020 diff --git a/content/ko/docs/helm/helm_lint.md b/content/ko/docs/helm/helm_lint.md new file mode 100644 index 0000000000..2cbf4e137f --- /dev/null +++ b/content/ko/docs/helm/helm_lint.md @@ -0,0 +1,66 @@ +--- +title: "Helm Lint" +--- + +## helm lint + +이슈가 발생하지 않을지 차트를 검토한다 + +### 개요 + + +이 명령은 차트 경로를 받아 해당 차트가 올바른 +형식(well-formed)인지 검증하는 일련의 테스트를 실행한다. + +만약 린터(linter)가 차트 설치 실패를 일으킬만한 사항을 발견하면, +[ERROR] 메세지를 발생시킬 것이다. 컨벤션이나 권장사항을 위반한 이슈를 발견하면, +[WARNING] 메세지를 발생시킬 것이다. + + +``` +helm lint PATH [flags] +``` + +### 옵션 + +``` + -h, --help lint 에 대한 도움말 + --set stringArray 명령 줄에 값을 설정 (쉼표로 여러 값 또는 개별 값을 지정 가능: 키1=값1,키2=값2) + --set-file stringArray 명령 줄을 통해 지정된 각 파일에서 값을 설정 (쉼표로 여러 값 또는 개별 값을 지정 가능: 키1=값1,키2=값2) + --set-string stringArray 명령 줄에서 STRING 값 설정 (쉼표로 여러 값 또는 개별 값을 지정 가능: 키1=값1,키2=값2) + --strict 검토 경고(lint warning)시 실패로 판정 + -f, --values strings YAML 파일 또는 URL 에 값 지정 (여러 개 지정 가능) + --with-subcharts 하위 차트 의존성 검토 +``` + +### 부모 명령어에서 상속된 옵션들 + +``` + --add-dir-header true이면, 헤더에 파일 디렉토리를 추가 + --alsologtostderr 파일처럼 로그를 표준 오류로로 출력 + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용될 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + --log-backtrace-at traceLocation 로깅 시 N 행에 걸친 스택 추적 내용을 표시 (기본값 :0) + --log-dir string 값을 지정하면, 지정한 디렉토리에 로그 파일 기록 + --log-file string 값을 지정하면, 지정한 로그 파일 사용 + --log-file-max-size uint 로그파일이 증가할 수 있는 최대 크기 지정. 단위는 메가바이트이다. 값이 0이면, 최대 파일크기는 무제한. (기본값 1800) + --logtostderr 로그를 파일이 아닌 표준 오류로 표시 (기본값 true) + -n, --namespace string 요청에 대한 네임스페이스 지정 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL 을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") + --skip-headers 이 값이 true이면, 로그파일에서 헤더 접두어를 미사용 + --skip-log-headers 이 값이 true이면, 로그파일을 열 때 헤더 제외 + --stderrthreshold severity stderr로 로그가 변경될 수 있는 최저 임계점 (기본값 2) + -v, --v Level 로그 수준 상세표시 레벨 + --vmodule moduleSpec 파일로 필터링된 로깅을 위한 패턴=N 설정의 쉼표로 구분된 리스트 +``` + +### 참조 + +* [helm](../helm) - 쿠버네티스에 대한 헬름 패키지 매니저. + +###### Auto generated by spf13/cobra on 14-Sep-2020 diff --git a/content/ko/docs/helm/helm_list.md b/content/ko/docs/helm/helm_list.md new file mode 100644 index 0000000000..d6494ac1f0 --- /dev/null +++ b/content/ko/docs/helm/helm_list.md @@ -0,0 +1,85 @@ +--- +title: "Helm List" +--- + +## helm list + +릴리스를 나열한다. + +### 개요 + + +이 명령은 지정된 네임 스페이스에 대한 모든 릴리스를 나열헌다 (네임 스페이스가 지정되지 않은 경우 현재 네임 스페이스 컨텍스트 사용). + +기본적으로는, 배포되었거나 실패한 릴리스만 나열한다. +'--uninstalled' 및 '--all' 과 같은 플래그는 이 동작을 변경한다. +이러한 플래그는 '--uninstalled --failed' 와 같이 결합 할 수 있다. + +기본적으로, 항목은 알파벳순으로 정렬된다. 출시 날짜별로 정렬하려면 '-d' 플래그를 +사용하자. + +--filter 플래그가 제공되면 필터로 처리된다. +필터는 릴리스 목록에 적용되는 정규식 (Perl 호환 가능)이다. +오직 필터와 일치하는 항목만 반환된다. + + $ helm list --filter 'ara[a-z]+' + NAME UPDATED CHART + maudlin-arachnid 2020-06-18 14:17:46.125134977 +0000 UTC alpine-0.1.0 + +결과가 없으면 'helm list' 는 0으로 종료되지만 +출력은 표시되지 않는다(또는 '-q' 플래그가 없고 헤더만 있는 경우). + +기본적으로 최대 256 개의 항목이 반환 될 수 있다. 이를 제한하려면 '--max' 플래그를 사용하자. +'--max' 를 0으로 설정하면 어떠한 결과도 반환되지 않는다. +대신 서버의 기본값을 반환하는데, 이는 256보다 훨씬 더 클 수 있다. +'--max' 플래그와 '--offset' 플래그를 함께 사용하면 결과를 페이징 할 수 있다. + + +``` +helm list [flags] +``` + +### 옵션 + +``` + -a, --all 필터가 적용되지 않은 모든 릴리스를 표시 + -A, --all-namespaces 모든 네임스페이스로 릴리스를 나열 + -d, --date 릴리스 날짜로 정렬 + --deployed 배포 된 릴리스를 표시. 다른 것을 지정하지 않으면 자동으로 활성화. + --failed 실패한 릴리스를 표시 + -f, --filter string 정규 표현식(Perl 호환). 표현식과 일치하는 모든 릴리스가 결과에 포함된다. + -h, --help list 명령어에 대한 도움말 + -m, --max int 가져올 최대 릴리스의 수 (기본값 256) + --offset int 시작 값에서 오프셋 시 사용되는 목록의 다음 릴리스명 + -o, --output format 지정된 형식으로 출력. 허용되는 값: table, json, yaml (기본값 table) + --pending 펜딩된 릴리스를 표시 + -r, --reverse 정렬 순서 반전 + -l, --selector string 필터링 할 (레이블 쿼리) 셀렉터로, '=', '==', and '!=' 을 지원.(예: -l key1=value1,key2=value2). 시크릿(기본값) 및 컨피그맵 스토리지 백엔드에서만 작동 + -q, --short 짧은 목록 형식 출력 + --superseded 대체된 릴리스를 표시 + --time-format string 시간 형식. 예: --time-format 2009-11-17 20:34:10 +0000 UTC + --uninstalled 제거된 릴리스 표시('helm uninstall --keep-history' 를 사용한 경우) + --uninstalling 현재 제거중인 릴리스 표시 +``` + +### 부모 명령어에서 상속된 옵션들 + +``` + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-as-group stringArray 작업에 관해 제시할 그룹. 플래그를 여러 번 사용하여 여러 그룹 지정 가능 + --kube-as-user string 작업에 관해 제시할 사용자명 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용될 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + -n, --namespace string 이 요청에 대한 네임스페이스 스코프 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL 을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") +``` + +### 함께 보기 + +* [helm](../helm) - 쿠버네티스에 대한 헬름 패키지 매니저. + +###### Auto generated by spf13/cobra on 29-Oct-2020 diff --git a/content/ko/docs/helm/helm_package.md b/content/ko/docs/helm/helm_package.md new file mode 100644 index 0000000000..4ce74584d8 --- /dev/null +++ b/content/ko/docs/helm/helm_package.md @@ -0,0 +1,74 @@ +--- +title: "Helm Package" +--- + +## helm package + +차트 디렉토리를 차트 아카이브로 패키징 + +### 개요 + + +이 명령어는 차트를, 버전이 지정된 차트 아카이브 파일로 패키징한다. +경로가 지정되면 차트(Chart.yaml 파일을 포함해야 함)에 대한 그 경로를 찾은 다음 +해당 디렉토리를 패키징한다. + +버전이 지정된 차트 아카이브는 헬름 패키지 저장소에서 사용된다. + +차트에 서명하려면 `--sign` 플래그를 사용하자. 대부분의 경우, +'--keyring path/to/secret/keys' 와 '--key keyname' 도 지정해야 할 것이다. + + $ helm package --sign ./mychart --key mykey --keyring ~/.gnupg/secring.gpg + +'--keyring' 을 지정하지 않았고 별다른 설정을 하지 않은 환경이라면 +헬름은 보통 공개 키링을 기본값으로 사용한다. + + +``` +helm package [CHART_PATH] [...] [flags] +``` + +### 옵션 + +``` + --app-version string 차트의 appVersion 을 이 버전으로 설정 + -u, --dependency-update 패키징 전에 "Chart.yaml" 에서 "charts/" 디렉토리로 의존성 업데이트 + -d, --destination string 차트를 기록할 위치 지정 (기본값 ".") + -h, --help package 에 대한 도움말 + --key string 서명할 때 사용하는 키의 이름. --sign이 true일 경우 사용 + --keyring string 공개 키링의 위치 (기본값 "~/.gnupg/pubring.gpg") + --sign PGP 개인 키를 사용하여 패키지에 서명 + --version string 차트의 버전을 이 유의적(semver) 버전으로 설정 +``` + +### 부모 명령어에서 상속된 옵션들 + +``` + --add-dir-header 이 값이 true이면, 헤더에 파일 디렉토리를 추가 + --alsologtostderr 로그파일처럼 표준오류로도 로그 출력 + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용될 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + --log-backtrace-at traceLocation 로깅 시 N 행에 걸친 스택 추적 내용을 표시 (기본값 :0) + --log-dir string 값을 지정하면, 지정한 디렉토리에 로그 파일 기록 + --log-file string 값을 지정하면, 지정한 로그 파일 사용 + --log-file-max-size uint 로그파일이 증가할 수 있는 최대 크기 지정. 단위는 메가바이트이다. 값이 0이면, 최대 파일크기는 무제한. (기본값 1800) + --logtostderr 로그를 파일이 아닌 표준 출력으로 표시 (기본값 true) + -n, --namespace string 요청에 대한 네임스페이스 지정 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL 을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") + --skip-headers 이 값이 true이면, 로그파일에서 헤더 접두어를 미사용 + --skip-log-headers 이 값이 true이면, 로그파일을 열 때 헤더 제외 + --stderrthreshold severity stderr로 로그가 변경될 수 있는 최저 임계점 (기본값 2) + -v, --v Level 로그 수준 상세표시 레벨 + --vmodule moduleSpec 파일로 필터링된 로깅을 위한 패턴=N 설정의 쉼표로 구분된 리스트 +``` + +### 참조 + +* [helm](../helm) - 쿠버네티스에 대한 헬름 패키지 매니저. + +###### Auto generated by spf13/cobra on 11-May-2020 diff --git a/content/ko/docs/helm/helm_plugin.md b/content/ko/docs/helm/helm_plugin.md new file mode 100644 index 0000000000..9dcc63e839 --- /dev/null +++ b/content/ko/docs/helm/helm_plugin.md @@ -0,0 +1,45 @@ +--- +title: "Helm Plugin" +--- + +## helm plugin + +헬름 플러그인 설치, 나열, 제거 + +### 개요 + + +클라이언트 측 헬름 플러그인을 관리한다. + + +### 옵션 + +``` + -h, --help helm plugin 명령어의 도움말 +``` + +### 부모 명령어로부터 상속된 옵션 + +``` + --debug 자세한 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-as-group stringArray 작업을 가장(impersonate)하기 위한 그룹. 이 플래그를 반복하여 여러 그룹을 지정 가능 + --kube-as-user string 작업을 가장할 사용자 이름 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용할 전달자(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + -n, --namespace string 이 요청의 네임스페이스 범위 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인을 포함하는 파일 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL 이 포함된 파일 경로(기본값 "~/.config/helm/repositories.yaml") +``` + +### 함께 보기 + +* [helm](helm.md) - 쿠버네티스용 헬름 패키지 관리자 +* [helm plugin install](helm_plugin_install.md) - 하나 이상의 헬름 플러그인 설치 +* [helm plugin list](helm_plugin_list.md) - 설치된 헬름 플러그인 나열 +* [helm plugin uninstall](helm_plugin_uninstall.md) - 하나 이상의 헬름 플러그인 제거 +* [helm plugin update](helm_plugin_update.md) - 하나 이상의 헬름 플러그인 업데이트 + +###### Auto generated by spf13/cobra on 29-Oct-2020 diff --git a/content/ko/docs/helm/helm_plugin_install.md b/content/ko/docs/helm/helm_plugin_install.md new file mode 100644 index 0000000000..31877ef8fd --- /dev/null +++ b/content/ko/docs/helm/helm_plugin_install.md @@ -0,0 +1,46 @@ +--- +title: "Helm Plugin Install" +--- + +## helm plugin install + +하나 이상의 헬름 플러그인을 설치한다. + +### Synopsis + + +이 명령을 사용하면 URL에서 VCS 저장소 또는 로컬 경로로 플러그인을 설치할 수 있다. + + +``` +helm plugin install [options] ... [flags] +``` + +### 옵션 + +``` + -h, --help helm plugin install 명령어의 도움말 + --version string 버전을 강제로 지정. 지정하지 않으면 최신 버전을 설치 +``` + +### 부모 명령어로부터 상속된 옵션 + +``` + --debug 자세한 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-as-group stringArray 작업을 가장(impersonate)하기 위한 그룹. 이 플래그를 반복하여 여러 그룹을 지정 가능 + --kube-as-user string 작업을 가장할 사용자 이름 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용할 전달자(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + -n, --namespace string 이 요청의 네임스페이스 범위 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인을 포함하는 파일 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL 이 포함된 파일 경로(기본값 "~/.config/helm/repositories.yaml") +``` + +### 함께 보기 + +* [helm plugin](helm_plugin.md) - 헬름 플러그인 설치, 나열, 제거 + +###### Auto generated by spf13/cobra on 29-Oct-2020 diff --git a/content/ko/docs/helm/helm_plugin_list.md b/content/ko/docs/helm/helm_plugin_list.md new file mode 100644 index 0000000000..e225d32b7a --- /dev/null +++ b/content/ko/docs/helm/helm_plugin_list.md @@ -0,0 +1,43 @@ +--- +title: "Helm Plugin List" +--- + +## helm plugin list + +설치된 헬름 플러그인 나열 + +### 개요 + +설치된 헬름 플러그인을 나열한다. + +``` +helm plugin list [flags] +``` + +### 옵션 + +``` + -h, --help helm plugin list 명령어의 도움말 +``` + +### 부모 명령어로부터 상속된 옵션 + +``` + --debug 자세한 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-as-group stringArray 작업을 가장(impersonate)하기 위한 그룹. 이 플래그를 반복하여 여러 그룹을 지정 가능 + --kube-as-user string 작업을 가장할 사용자 이름 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용할 전달자(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + -n, --namespace string 이 요청의 네임스페이스 범위 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인을 포함하는 파일 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL 이 포함된 파일 경로(기본값 "~/.config/helm/repositories.yaml") +``` + +### 함께 보기 + +* [helm plugin](helm_plugin.md) - 헬름 플러그인 설치, 나열, 제거 + +###### Auto generated by spf13/cobra on 29-Oct-2020 diff --git a/content/ko/docs/helm/helm_plugin_uninstall.md b/content/ko/docs/helm/helm_plugin_uninstall.md new file mode 100644 index 0000000000..06bd70de11 --- /dev/null +++ b/content/ko/docs/helm/helm_plugin_uninstall.md @@ -0,0 +1,43 @@ +--- +title: "Helm Plugin Uninstall" +--- + +## helm plugin uninstall + +하나 이상의 헬름 플러그인을 제거 + +### 개요 + +하나 이상의 헬름 플러그인을 제거한다. + +``` +helm plugin uninstall ... [flags] +``` + +### 옵션 + +``` + -h, --help helm plugin uninstall 명령어의 도움말 +``` + +### 부모 명령어로부터 상속된 옵션 + +``` + --debug 자세한 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-as-group stringArray 작업을 가장(impersonate)하기 위한 그룹. 이 플래그를 반복하여 여러 그룹을 지정 가능 + --kube-as-user string 작업을 가장할 사용자 이름 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용할 전달자(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + -n, --namespace string 이 요청의 네임스페이스 범위 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인을 포함하는 파일 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL 이 포함된 파일 경로(기본값 "~/.config/helm/repositories.yaml") +``` + +### 함께 보기 + +* [helm plugin](helm_plugin.md) - 헬름 플러그인 설치, 나열, 제거 + +###### Auto generated by spf13/cobra on 29-Oct-2020 diff --git a/content/ko/docs/helm/helm_plugin_update.md b/content/ko/docs/helm/helm_plugin_update.md new file mode 100644 index 0000000000..64e2161e36 --- /dev/null +++ b/content/ko/docs/helm/helm_plugin_update.md @@ -0,0 +1,43 @@ +--- +title: "Helm Plugin Update" +--- + +## helm plugin update + +하나 이상의 헬름 플러그인 업데이트 + +### Synopsis + +하나 이상의 헬름 플러그인을 업데이트한다. + +``` +helm plugin update ... [flags] +``` + +### 옵션 + +``` + -h, --help helm plugin update 명령어의 도움말 +``` + +### 부모 명령어로부터 상속된 옵션 + +``` + --debug 자세한 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-as-group stringArray 작업을 가장(impersonate)하기 위한 그룹. 이 플래그를 반복하여 여러 그룹을 지정 가능 + --kube-as-user string 작업을 가장할 사용자 이름 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용할 전달자(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + -n, --namespace string 이 요청의 네임스페이스 범위 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인을 포함하는 파일 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL 이 포함된 파일 경로(기본값 "~/.config/helm/repositories.yaml") +``` + +### 함께 보기 + +* [helm plugin](helm_plugin.md) - 헬름 플러그인 설치, 나열, 제거 + +###### Auto generated by spf13/cobra on 29-Oct-2020 diff --git a/content/ko/docs/helm/helm_pull.md b/content/ko/docs/helm/helm_pull.md new file mode 100644 index 0000000000..62a5e27db2 --- /dev/null +++ b/content/ko/docs/helm/helm_pull.md @@ -0,0 +1,81 @@ +--- +title: "Helm Pull" +--- + +## helm pull + +저장소에서 차트를 다운로드하고 (선택적으로) 로컬 디렉터리에 압축 해제 + +### 개요 + + +패키지 저장소에서 패키지를 검색하고 로컬로 다운로드 한다. + +이는 검사, 수정 또는 리패키지를 위하여 패키지를 가져올 때 유용하다. 또한 +설치하지 않고 차트의 암호화 검증을 수행하는 데 사용할 +수도 있다. + +다운로드 후 차트를 풀 수 있는 옵션이 있다. 그러면 차트에 대한 +디렉터리가 생성되고 해당 디렉터리에 압축이 해제된다. + +--verify 플래그가 지정된 경우, 요청된 차트에는 출처 파일이 있어야 하며 확인 프로세스를 +통과해야 한다. 프로세스 중 어느 부분에서라도 실패할 경우 오류가 발생할 수 있으며, +차트가 로컬에 저장되지 않는다. + + +``` +helm pull [chart URL | repo/chartname] [...] [flags] +``` + +### 옵션 + +``` + --ca-file string 이 CA 번들을 사용하여 HTTPS 활성화된 서버의 인증서를 확인 + --cert-file string 이 SSL 인증서 파일을 사용하여 HTTPS 클라이언트 식별 + -d, --destination string 차트를 작성할 위치. 이 옵션과 'tardir' 가 지정되면 'tardir' 이 여기에 추가된다. (기본값 ".") + --devel 개발용 버전으로도 사용가능. 버전 '>0.0.0-0' 과 동일하다. 만약 --version 플래그가 설정되면, 이 옵션은 무시된다. + -h, --help pull 에 대한 도움말 + --insecure-skip-tls-verify 차트 다운로드에 tls 인증서 확인 생략 + --key-file string 이 SSL 키 파일을 사용하여 HTTPS 클라이언트 식별 + --keyring string 확인에 사용되는 공개 키의 위치 (기본값 "~/.gnupg/pubring.gpg") + --password string 요청된 차트를 찾을 수 있는 차트 저장소 비밀번호 + --prov 출처 파일을 가져 오기만 하고, 확인은 수행하지 않음 + --repo string 요청된 차트를 찾을 수 있는 차트 저장소 URL + --untar 이 옵션을 'true'로 설정하면, 차트를 다운로드 한 후 압축을 해제 + --untardir string 'untar' 플래그가 'true'로 지정된 경우, 이 플래그를 통해 차트가 확장되는 디렉터리의 이름을 지정 (기본값 ".") + --username string 요청된 차트를 찾을 수 있는 차트 저장소 사용자 이름 + --verify 사용하기 전에 패키지 확인 + --version string 사용할 정확한 차트 버전 지정. 지정하지 않을 경우 최신버전으로 사용 +``` + +### 부모 명령어에서 상속된 옵션들 + +``` + --add-dir-header 이 값이 참이면, 헤더에 파일 디렉터리를 추가 + --alsologtostderr 로그를 표준 오류 및 파일로 표시 + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용될 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + --log-backtrace-at traceLocation 로깅 시 N 행에 걸친 스택 추적 내용을 표시 (기본값 :0) + --log-dir string 값을 지정하면, 지정한 디렉터리에 로그 파일 기록 + --log-file string 값을 지정하면, 지정한 로그 파일 사용 + --log-file-max-size uint 로그파일이 증가할 수 있는 최대 크기 지정. 단위는 메가바이트이다. 값이 0이면, 최대 파일크기는 무제한. (기본값 1800) + --logtostderr 로그를 파일이 아닌 표준 오류로 표시 (기본값 true) + -n, --namespace string 요청에 대한 네임스페이스 지정 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL 을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") + --skip-headers 이 값이 true이면, 로그파일에서 헤더 접두어를 미사용 + --skip-log-headers 이 값이 true이면, 로그파일을 열 때 헤더 제외 + --stderrthreshold severity stderr로 로그가 변경될 수 있는 최저 임계점 (기본값 2) + -v, --v Level 로그 수준 상세표시 레벨 + --vmodule moduleSpec 파일로 필터링된 로깅을 위한 패턴=N 설정의 쉼표로 구분된 리스트 +``` + +### 참조 + +* [helm](../helm) - 쿠버네티스에 대한 헬름 패키지 매니저. + +###### Auto generated by spf13/cobra on 14-Sep-2020 diff --git a/content/ko/docs/helm/helm_repo.md b/content/ko/docs/helm/helm_repo.md new file mode 100644 index 0000000000..4cd997cd7e --- /dev/null +++ b/content/ko/docs/helm/helm_repo.md @@ -0,0 +1,48 @@ +--- +title: "Helm Repo" +--- + +## helm repo + +차트 저장소 추가, 나열, 제거, 업데이트, 색인 생성 + +### 개요 + + +이 명령은 차트 저장소와 상호작용하는 여러 하위명령으로 구성된다. + +차트 저장소를 추가, 제거, 나열, 색인화 하는데 사용될 수 있다. + + +### 옵션 + +``` + -h, --help helm repo 에 대한 도움말 +``` + +### 부모 명령어에서 상속된 옵션들 + +``` + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-as-group stringArray 작업에 관해 제시할 그룹. 플래그를 여러 번 사용하여 여러 그룹 지정 가능 + --kube-as-user string 작업에 관해 제시할 사용자명 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용될 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + -n, --namespace string 이 요청에 대한 네임스페이스 스코프 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL 을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") +``` + +### 함께 보기 + +* [helm](../helm) - 쿠버네티스에 대한 헬름 패키지 매니저. +* [helm repo add](helm_repo_add.md) - 차트 저장소 추가 +* [helm repo index](helm_repo_index.md) - 패키지 된 차트를 포함하는 디렉터리에 인덱스 파일 생성 +* [helm repo list](helm_repo_list.md) - 차트 저장소 나열 +* [helm repo remove](helm_repo_remove.md) - 하나 이상의 차트 저장소 제거 +* [helm repo update](helm_repo_update.md) - 차트 저장소에서 로컬로 사용 가능한 차트 정보 업데이트 + +###### Auto generated by spf13/cobra on 29-Oct-2020 diff --git a/content/ko/docs/helm/helm_repo_add.md b/content/ko/docs/helm/helm_repo_add.md new file mode 100644 index 0000000000..a3aac29071 --- /dev/null +++ b/content/ko/docs/helm/helm_repo_add.md @@ -0,0 +1,52 @@ +--- +title: "Helm Repo Add" +--- + +## helm repo add + +차트 저장소를 추가 + +### 개요 + +차트 저장소를 추가한다. + +``` +helm repo add [NAME] [URL] [flags] +``` + +### 옵션 + +``` + --allow-deprecated-repos 기본적으로, 이 명령은 영구적으로 삭제된 공식 저장소를 추가하는 것을 허용하지 않으며, 이 옵션을 통해 해당 동작을 비활성화. + --ca-file string 이 CA 번들을 사용하여 HTTPS 사용 서버의 인증서를 확인 + --cert-file string 이 SSL 인증서 파일을 사용하여 HTTPS 클라이언트 식별 + --force-update 레포지터리가 이미 있는 경우 교체(덮어쓰기) + -h, --help helm repo add 명령어에 대한 도움말 + --insecure-skip-tls-verify 저장소에 대한 TLS 인증서 검사 건너뛰기 + --key-file string 이 SSL 키 파일을 사용하여 HTTPS 클라이언트 식별 + --no-update 무시. 이전에는, 강제 업데이트를 비활성화하기 위해 사용. force-update 에 의해 향후 미사용 + --password string 차트 저장소 비밀번호 + --username string 차트 저장소 사용자 이름 +``` + +### 부모 명령어에서 상속된 옵션들 + +``` + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-as-group stringArray 작업에 관해 제시할 그룹. 플래그를 여러 번 사용하여 여러 그룹 지정 가능 + --kube-as-user string 작업에 관해 제시할 사용자명 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용될 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + -n, --namespace string 이 요청에 대한 네임스페이스 스코프 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL 을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") +``` + +### 함께 보기 + +* [helm repo](helm_repo.md) - 차트 저장소 추가, 나열, 제거, 업데이트, 색인 생성 + +###### Auto generated by spf13/cobra on 29-Oct-2020 diff --git a/content/ko/docs/helm/helm_repo_index.md b/content/ko/docs/helm/helm_repo_index.md new file mode 100644 index 0000000000..96885448a1 --- /dev/null +++ b/content/ko/docs/helm/helm_repo_index.md @@ -0,0 +1,54 @@ +--- +title: "Helm Repo Index" +--- + +## helm repo index + +패키지된 차트를 포함하는 디렉터리에 인덱스 파일을 생성 + +### 개요 + + +현재 디렉터리를 읽고 찾은 차트를 기반으로 색인 파일을 생성한다. + +이 도구는 차트 저장소에 대한 'index.yaml' 파일을 만드는데 사용된다. +차트에 대한 절대 URL을 설정하려면 '--url' 플래그를 사용하자. + +생성된 인덱스를 기존 인덱스 파일과 병합하려면, '--merge' 플래그를 사용하자. +이 경우 현재 디렉터리에 있는 차트가 기존 인덱스에 병합되고 +로컬차트가 기존차트보다 우선한다. + + +``` +helm repo index [DIR] [flags] +``` + +### 옵션 + +``` + -h, --help helm repo index 명령어의 도움말 + --merge string 생성된 색인을 주어진 색인에 병합 + --url string 차트 저장소의 url +``` + +### 부모 명령어에서 상속된 옵션들 + +``` + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-as-group stringArray 작업에 관해 제시할 그룹. 플래그를 여러 번 사용하여 여러 그룹 지정 가능 + --kube-as-user string 작업에 관해 제시할 사용자명 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용될 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + -n, --namespace string 이 요청에 대한 네임스페이스 스코프 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL 을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") +``` + +### 함께 보기 + +* [helm repo](helm_repo.md) - 차트 저장소 추가, 나열, 제거, 업데이트, 색인 생성 + +###### Auto generated by spf13/cobra on 29-Oct-2020 diff --git a/content/ko/docs/helm/helm_repo_list.md b/content/ko/docs/helm/helm_repo_list.md new file mode 100644 index 0000000000..5cceda002d --- /dev/null +++ b/content/ko/docs/helm/helm_repo_list.md @@ -0,0 +1,44 @@ +--- +title: "Helm Repo List" +--- + +## helm repo list + +차트 저장소 나열 + +### 개요 + +차트 저장소를 나열한다. + +``` +helm repo list [flags] +``` + +### Options + +``` + -h, --help helm repo list 명령어의 도움말 + -o, --output format 지정된 형식으로 출력. 허용되는 값: table, json, yaml (기본값 table) +``` + +### 부모 명령어에서 상속된 옵션들 + +``` + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-as-group stringArray 작업에 관해 제시할 그룹. 플래그를 여러 번 사용하여 여러 그룹 지정 가능 + --kube-as-user string 작업에 관해 제시할 사용자명 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용될 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + -n, --namespace string 이 요청에 대한 네임스페이스 스코프 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL 을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") +``` + +### 함께 보기 + +* [helm repo](helm_repo.md) - 차트 저장소 추가, 나열, 제거, 업데이트, 색인 생성 + +###### Auto generated by spf13/cobra on 29-Oct-2020 diff --git a/content/ko/docs/helm/helm_repo_remove.md b/content/ko/docs/helm/helm_repo_remove.md new file mode 100644 index 0000000000..999c2cb512 --- /dev/null +++ b/content/ko/docs/helm/helm_repo_remove.md @@ -0,0 +1,43 @@ +--- +title: "Helm Repo Remove" +--- + +## helm repo remove + +하나 이상의 차트 저장소 제거 + +### 개요 + +하나 이상의 차트 저장소를 제거한다. + +``` +helm repo remove [REPO1 [REPO2 ...]] [flags] +``` + +### 옵션 + +``` + -h, --help helm repo remove 명령어에 대한 도움말 +``` + +### 부모 명령어에서 상속된 옵션들 + +``` + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-as-group stringArray 작업에 관해 제시할 그룹. 플래그를 여러 번 사용하여 여러 그룹 지정 가능 + --kube-as-user string 작업에 관해 제시할 사용자명 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용될 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + -n, --namespace string 이 요청에 대한 네임스페이스 스코프 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL 을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") +``` + +### 함께 보기 + +* [helm repo](helm_repo.md) - 차트 저장소 추가, 나열, 제거, 업데이트, 색인 생성 + +###### Auto generated by spf13/cobra on 29-Oct-2020 diff --git a/content/ko/docs/helm/helm_repo_update.md b/content/ko/docs/helm/helm_repo_update.md new file mode 100644 index 0000000000..81a3794a1c --- /dev/null +++ b/content/ko/docs/helm/helm_repo_update.md @@ -0,0 +1,46 @@ +--- +title: "Helm Repo Update" +--- + +## helm repo update + +차트 저장소에서 로컬로 사용 가능한 차트의 정보를 업데이트한다. + +### 개요 + + +업데이트 명령어는 각 차트 레포지터리에서 차트에 대한 최신 정보를 가져온다. +정보는 'helm search' 와 같은 명령에서 사용되는 것과 같이 로컬에 캐싱된다. + + +``` +helm repo update [flags] +``` + +### 옵션 + +``` + -h, --help helm repo update 명령어에 대한 도움말 +``` + +### 부모 명령어에서 상속된 옵션들 + +``` + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-as-group stringArray 작업에 관해 제시할 그룹. 플래그를 여러 번 사용하여 여러 그룹 지정 가능 + --kube-as-user string 작업에 관해 제시할 사용자명 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용될 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + -n, --namespace string 이 요청에 대한 네임스페이스 스코프 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL 을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") +``` + +### 함께 보기 + +* [helm repo](helm_repo.md) - 차트 저장소 추가, 나열, 제거, 업데이트, 색인 생성 + +###### Auto generated by spf13/cobra on 29-Oct-2020 diff --git a/content/ko/docs/helm/helm_rollback.md b/content/ko/docs/helm/helm_rollback.md new file mode 100644 index 0000000000..c92c991f39 --- /dev/null +++ b/content/ko/docs/helm/helm_rollback.md @@ -0,0 +1,59 @@ +--- +title: "Helm Rollback" +--- + +## helm rollback + +릴리스를 이전 리비젼으로 롤백한다. + +### 개요 + + +이 명령은 릴리스를 이전 리비젼으로 롤백한다. + +rollback 명령어의 첫 번째 인수는 릴리스의 이름이고, +두 번째 인수는 리비젼(버전) 번호이다. +이 인수를 생략하면 바로 이전 릴리스로 롤백 된다. + +리비젼 번호를 보려면 'helm history RELEASE' 를 실행하자. + + +``` +helm rollback [REVISION] [flags] +``` + +### 옵션 + +``` + --cleanup-on-fail 롤백이 실패할 때 이 롤백에서 생성된 새 리소스의 삭제를 허용 + --dry-run 롤백 모의 실행 + --force 필요한 경우 삭제/재작성을 통해 리소스를 강제로 업데이트 + -h, --help rollback 명령어에 대한 도움말 + --history-max int 릴리스 당 저장되는 최대 리비젼 수를 제한. 제한이 없는 경우는 0을 사용 (default 10) + --no-hooks 롤백 중 훅 실행 방지 + --recreate-pods 해당되는 경우 리소스에 대해 파드 재시작 수행 + --timeout duration 개별 쿠버네티스 작업(예: 훅에 대한 작업)을 기다리는 시간 (기본값 5m0s) + --wait 설정된 경우, 릴리스를 성공으로 표시하기 전에 모든 파드, PVC, 서비스, 디플로이먼트, 스테이트풀셋, 레플리카셋의 최소 파드 수가 Ready 상태가 될 때까지 대기. --timeout 만큼 대기 +``` + +### 부모 명령어에서 상속된 옵션들 + +``` + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-as-group stringArray 작업에 관해 제시할 그룹. 플래그를 여러 번 사용하여 여러 그룹 지정 가능 + --kube-as-user string 작업에 관해 제시할 사용자명 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용될 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + -n, --namespace string 이 요청에 대한 네임스페이스 스코프 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL 을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") +``` + +### 함께 보기 + +* [helm](../helm) - 쿠버네티스에 대한 헬름 패키지 매니저. + +###### Auto generated by spf13/cobra on 29-Oct-2020 diff --git a/content/ko/docs/helm/helm_search.md b/content/ko/docs/helm/helm_search.md new file mode 100644 index 0000000000..7ec7474139 --- /dev/null +++ b/content/ko/docs/helm/helm_search.md @@ -0,0 +1,45 @@ +--- +title: "Helm Search" +--- + +## helm search + +차트에서 키워드 검색 + +### 개요 + + +검색은 추가 한 헬름 허브 및 저장소를 포함하여 저장할 수있는 +다양한 위치에서 Helm 차트를 검색하는 기능을 제공한다. +search 하위 명령을 사용하여 차트의 다른 위치를 검색한다. + + +### 옵션 + +``` + -h, --help helm search 명령어에 대한 도움말 +``` + +### 부모 명령어에서 상속된 옵션들 + +``` + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-as-group stringArray 작업에 관해 제시할 그룹. 플래그를 여러 번 사용하여 여러 그룹 지정 가능 + --kube-as-user string 작업에 관해 제시할 사용자명 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용될 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + -n, --namespace string 이 요청에 대한 네임스페이스 스코프 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL 을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") +``` + +### 함께 보기 + +* [helm](helm.md) - 쿠버네티스에 대한 헬름 패키지 매니저. +* [helm search hub](helm_search_hub.md) - 헬름 허브 또는 모노큘러 인스턴스에서 차트 검색 +* [helm search repo](helm_search_repo.md) - 차트에서 키워드에 대한 저장소 검색 + +###### Auto generated by spf13/cobra on 29-Oct-2020 diff --git a/content/ko/docs/helm/helm_search_hub.md b/content/ko/docs/helm/helm_search_hub.md new file mode 100644 index 0000000000..3371a2d12d --- /dev/null +++ b/content/ko/docs/helm/helm_search_hub.md @@ -0,0 +1,56 @@ +--- +title: "Helm Search Hub" +--- + +## helm search hub + +헬름 허브 또는 모노큘러 인스턴스에서 차트 검색 + +### 개요 + + +헬름 차트에 대한 헬름 허브 또는 모노큘러 인스턴스를 검색한다. + +헬름허브는 공개적으로 사용 가능한 분산 형 차트에 대한 +중앙 집중식 검색을 제공한다. 헬름 프로젝트에서 관리한다. +https://hub.helm.sh에서 방문 할 수 있다. + +모노큘러(Monocular)는 여러 헬름 차트 저장소에서 차트를 +검색 할 수있는 웹 기반 애플리케이션이다. 헬름 허브를 구동하는 코드베이스이다. +https://github.com/helm/monocular에서 찾을 수 있다. + + +``` +helm search hub [keyword] [flags] +``` + +### Options + +``` + --endpoint string 차트에 대해 질의할 모노큘러 인스턴스 (기본값 "https://hub.helm.sh") + -h, --help helm search hub 명령어에 대한 도움말 + --max-col-width uint 출력 테이블의 최대 열 너비 (기본값 50) + -o, --output format 지정된 형식으로 출력. 허용되는 값: table, json, yaml (기본값 table) +``` + +### 부모 명령어에서 상속된 옵션들 + +``` + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-as-group stringArray 작업에 관해 제시할 그룹. 플래그를 여러 번 사용하여 여러 그룹 지정 가능 + --kube-as-user string 작업에 관해 제시할 사용자명 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용될 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + -n, --namespace string 이 요청에 대한 네임스페이스 스코프 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL 을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") +``` + +### 함께 보기 + +* [helm search](helm_search.md) - 차트에서 키워드 검색 + +###### Auto generated by spf13/cobra on 29-Oct-2020 diff --git a/content/ko/docs/helm/helm_search_repo.md b/content/ko/docs/helm/helm_search_repo.md new file mode 100644 index 0000000000..e8e679565a --- /dev/null +++ b/content/ko/docs/helm/helm_search_repo.md @@ -0,0 +1,70 @@ +--- +title: "Helm Search Repo" +--- + +## helm search repo + +차트에서 키워드에 대한 저장소 검색 + +### 개요 + + +검색은 시스템에 구성된 모든 저장소를 읽고 일치하는 +항목을 찾는다. 이러한 저장소 검색은 시스템에 +저장된 메타 데이터를 사용한다. + +찾은 차트의 최신 안정 버전을 표시한다. +--devel 플래그를 지정하면 출력에 시험판 버전이 포함된다. +버전 제약을 사용하여 검색하려면 --version 을 사용하자. + +예: + + # 키워드 "nginx" 와 일치하는 안정적인 릴리스 버전 검색 + $ helm search repo nginx + + # 시험판 버전을 포함하여 키워드 "nginx" 와 일치하는 리릴스 버전 검색 + $ helm search repo nginx --devel + + # 주 버전이 1인 nginx-ingress 의 최신 안정 릴리스 검색 + $ helm search repo nginx-ingress --version ^1.0.0 + +저장소는 'helm repo' 명령어로 관리된다. + + +``` +helm search repo [keyword] [flags] +``` + +### Options + +``` + --devel 개발 버전(알파, 베타 및 릴리스 후보 릴리스)으로 사용. 버전 '> 0.0.0-0' 에 해당하며 --version이 설정되어 있으면 무시. + -h, --help helm search repo 명령어에 대한 도움말 + --max-col-width uint 출력 테이블의 최대 열 너비 (기본값 50) + -o, --output format 지정된 형식으로 출력. 허용되는 값: table, json, yaml (기본값 table) + -r, --regexp 추가한 저장소 검색에 정규식 사용 + --version string 추가한 레포지터리에 유의적 버전관리 제약을 사용하여 검색 + -l, --versions 추가한 저장소에 대해 각 차트의 각 버전과 함께 긴 목록을 한 줄에 표시 +``` + +### 부모 명령어에서 상속된 옵션들 + +``` + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-as-group stringArray 작업에 관해 제시할 그룹. 플래그를 여러 번 사용하여 여러 그룹 지정 가능 + --kube-as-user string 작업에 관해 제시할 사용자명 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용될 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + -n, --namespace string 이 요청에 대한 네임스페이스 스코프 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL 을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") +``` + +### 함께 보기 + +* [helm search](helm_search.md) - 차트에서 키워드 검색 + +###### Auto generated by spf13/cobra on 29-Oct-2020 diff --git a/content/ko/docs/helm/helm_show.md b/content/ko/docs/helm/helm_show.md new file mode 100644 index 0000000000..4fdabfb6d0 --- /dev/null +++ b/content/ko/docs/helm/helm_show.md @@ -0,0 +1,55 @@ +--- +title: "Helm Show" +--- + +## helm show + +차트의 정보를 보여준다 + +### 개요 + + +이 명령어는 차트에 대한 정보를 표시하는 여러 하위 명령어들로 구성된다 + + +### 옵션 + +``` + -h, --help show 에 대한 도움말 +``` + +### 부모 명령어에서 상속된 옵션들 + +``` + --add-dir-header 이 값이 참이면, 헤더에 파일 디렉토리를 추가 + --alsologtostderr 파일처럼 표준 오류로도 로그 출력 + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용될 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + --log-backtrace-at traceLocation 로깅 시 N 행에 걸친 스택 추적 내용을 표시 (기본값 :0) + --log-dir string 값을 지정하면, 지정한 디렉토리에 로그 파일 기록 + --log-file string 값을 지정하면, 지정한 로그 파일 사용 + --log-file-max-size uint 로그파일이 증가할 수 있는 최대 크기 지정. 단위는 메가바이트이다. 값이 0이면, 최대 파일크기는 무제한. (기본값 1800) + --logtostderr 로그를 파일 대신 표준 출력으로 표시 (기본값 true) + -n, --namespace string 요청에 대한 네임스페이스 지정 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL 을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") + --skip-headers 이 값이 true이면, 로그파일에서 헤더 접두어를 미사용 + --skip-log-headers 이 값이 true이면, 로그파일을 열 때 헤더 제외 + --stderrthreshold severity stderr로 로그가 변경될 수 있는 최저 임계점 (기본값 2) + -v, --v Level 로그 수준 상세표시 레벨 + --vmodule moduleSpec 파일로 필터링된 로깅을 위한 패턴=N 설정의 쉼표로 구분된 리스트 +``` + +### 참조 + +* [helm](../helm) - 쿠버네티스에 대한 헬름 패키지 매니저. +* [helm show all](helm_show_all.md) - 차트의 모든 정보를 표시 +* [helm show chart](helm_show_chart.md) - 차트의 정의를 표시 +* [helm show readme](helm_show_readme.md) - 차트의 README 파일을 표시 +* [helm show values](helm_show_values.md) - 차트의 값을 표시 + +###### Auto generated by spf13/cobra on 11-May-2020 diff --git a/content/ko/docs/helm/helm_show_all.md b/content/ko/docs/helm/helm_show_all.md new file mode 100644 index 0000000000..277bded554 --- /dev/null +++ b/content/ko/docs/helm/helm_show_all.md @@ -0,0 +1,66 @@ +--- +title: "Helm Show All" +--- + +## helm show all + +차트의 모든 정보를 표시한다 + +### 개요 + + +이 명령어는 차트(디렉터리, 파일 또는 URL)를 검사하고 모든 내용을 +보여준다. (values.yaml, Charts.yaml, README) + + +``` +helm show all [CHART] [flags] +``` + +### 옵션 + +``` + --ca-file string CA 번들을 사용하여 HTTPS 사용 서버의 인증서를 확인 + --cert-file string SSL 인증서 파일을 사용하여 HTTPS 클라이언트 식별 + --devel 개발 버전도 사용. 버전 '>0.0.0-0'에 해당하며 --version 이 설정되면 무시 + -h, --help all 에 대한 도움말 + --key-file string SSL 키 파일을 사용하여 HTTPS 클라이언트 식별 + --keyring string 확인에 사용되는 공개 키의 위치 (기본값 "~/.gnupg/pubring.gpg") + --password string 요청된 차트를 찾을 수 있는 차트 저장소 비밀번호 + --repo string 요청된 차트를 찾을 수 있는 차트 저장소 URL + --username string 요청된 차트를 찾을 수 있는 차트 저장소 사용자 이름 + --verify 설치하기 전에 패키지 확인 + --version string 설치할 정확한 차트의 버전을 지정. 만약 지정하지 않을 경우 최신 버전 지정 +``` + +### 부모 명령어에서 상속된 옵션들 + +``` + --add-dir-header 이 값이 참이면, 헤더에 파일 디렉토리를 추가 + --alsologtostderr 파일처럼 표준 오류로도 로그 출력 + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용될 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + --log-backtrace-at traceLocation 로깅 시 N 행에 걸친 스택 추적 내용을 표시 (기본값 :0) + --log-dir string 값을 지정하면, 지정한 디렉토리에 로그 파일 기록 + --log-file string 값을 지정하면, 지정한 로그 파일 사용 + --log-file-max-size uint 로그파일이 증가할 수 있는 최대 크기 지정. 단위는 메가바이트이다. 값이 0이면, 최대 파일크기는 무제한. (기본값 1800) + --logtostderr 로그를 파일 대신 표준 출력으로 표시 (기본값 true) + -n, --namespace string 요청에 대한 네임스페이스 지정 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL 을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") + --skip-headers 이 값이 true이면, 로그파일에서 헤더 접두어를 미사용 + --skip-log-headers 이 값이 true이면, 로그파일을 열 때 헤더 제외 + --stderrthreshold severity stderr로 로그가 변경될 수 있는 최저 임계점 (기본값 2) + -v, --v Level 로그 수준 상세표시 레벨 + --vmodule moduleSpec 파일로 필터링된 로깅을 위한 패턴=N 설정의 쉼표로 구분된 리스트 +``` + +### 참조 + +* [helm show](helm_show.md) - 차트의 정보를 표시 + +###### Auto generated by spf13/cobra on 11-May-2020 diff --git a/content/ko/docs/helm/helm_show_chart.md b/content/ko/docs/helm/helm_show_chart.md new file mode 100644 index 0000000000..1dbc47ce52 --- /dev/null +++ b/content/ko/docs/helm/helm_show_chart.md @@ -0,0 +1,65 @@ +--- +title: "Helm Show Chart" +--- + +## helm show chart + +차트의 정의를 보여준다 + +### 개요 + + +이 명령어는 차트(디렉터리, 파일 또는 URL)를 검사하고 Charts.yaml 파일의 내용을 보여준다. + + +``` +helm show chart [CHART] [flags] +``` + +### 옵션 + +``` + --ca-file string CA 번들을 사용하여 HTTPS 사용 서버의 인증서를 확인 + --cert-file string SSL 인증서 파일을 사용하여 HTTPS 클라이언트 식별 + --devel 개발 버전도 사용. 버전 '>0.0.0-0'에 해당하며 --version 이 설정되면 무시 + -h, --help chart 에 대한 도움말 + --key-file string SSL 키 파일을 사용하여 HTTPS 클라이언트 식별 + --keyring string 확인에 사용되는 공개 키의 위치 (기본값 "~/.gnupg/pubring.gpg") + --password string 요청된 차트를 찾을 수 있는 차트 저장소 비밀번호 + --repo string 요청된 차트를 찾을 수 있는 차트 저장소 URL + --username string 요청된 차트를 찾을 수 있는 차트 저장소 사용자 이름 + --verify 설치하기 전에 패키지 확인 + --version string 설치할 정확한 차트의 버전을 지정. 만약 지정하지 않을 경우 최신 버전 지정 +``` + +### 부모 명령어에서 상속된 옵션들 + +``` + --add-dir-header 이 값이 참이면, 헤더에 파일 디렉토리를 추가 + --alsologtostderr 파일처럼 표준 오류로도 로그 출력 + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용될 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + --log-backtrace-at traceLocation 로깅 시 N 행에 걸친 스택 추적 내용을 표시 (기본값 :0) + --log-dir string 값을 지정하면, 지정한 디렉토리에 로그 파일 기록 + --log-file string 값을 지정하면, 지정한 로그 파일 사용 + --log-file-max-size uint 로그파일이 증가할 수 있는 최대 크기 지정. 단위는 메가바이트이다. 값이 0이면, 최대 파일크기는 무제한. (기본값 1800) + --logtostderr 로그를 파일 대신 표준 출력으로 표시 (기본값 true) + -n, --namespace string 요청에 대한 네임스페이스 지정 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL 을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") + --skip-headers 이 값이 true이면, 로그파일에서 헤더 접두어를 미사용 + --skip-log-headers 이 값이 true이면, 로그파일을 열 때 헤더 제외 + --stderrthreshold severity stderr로 로그가 변경될 수 있는 최저 임계점 (기본값 2) + -v, --v Level 로그 수준 상세표시 레벨 + --vmodule moduleSpec 파일로 필터링된 로깅을 위한 패턴=N 설정의 쉼표로 구분된 리스트 +``` + +### 참조 + +* [helm show](helm_show.md) - 차트의 정보를 표시 + +###### Auto generated by spf13/cobra on 11-May-2020 diff --git a/content/ko/docs/helm/helm_show_readme.md b/content/ko/docs/helm/helm_show_readme.md new file mode 100644 index 0000000000..3ee2e77bf2 --- /dev/null +++ b/content/ko/docs/helm/helm_show_readme.md @@ -0,0 +1,66 @@ +--- +title: "Helm Show Readme" +--- + +## helm show readme + +차트의 README 파일을 표시 + +### 개요 + + +이 명령어는 차트(디렉터리, 파일 또는 URL)을 검사하고 README 파일의 내용을 +보여준다. + + +``` +helm show readme [CHART] [flags] +``` + +### 옵션 + +``` + --ca-file string CA 번들을 사용하여 HTTPS 사용 서버의 인증서를 확인 + --cert-file string SSL 인증서 파일을 사용하여 HTTPS 클라이언트 식별 + --devel 개발 버전도 사용. 버전 '>0.0.0-0'과 동등하다. --version 이 지정되면, 이것은 무시된다 + -h, --help readme 에 대한 도움말 + --key-file string SSL 키 파일을 사용하여 HTTPS 클라이언트 식별 + --keyring string 확인에 사용되는 공개 키의 위치 (기본값 "~/.gnupg/pubring.gpg") + --password string 요청된 차트를 찾을 수 있는 차트 저장소 비밀번호 + --repo string 요청된 차트를 찾을 수 있는 차트 저장소 URL + --username string 요청된 차트를 찾을 수 있는 차트 저장소 사용자 이름 + --verify 설치하기 전에 패키지 확인 + --version string 설치할 정확한 차트의 버전을 지정. 만약 지정하지 않을 경우 최신 버전 지정 +``` + +### 부모 명령어에서 상속된 옵션들 + +``` + --add-dir-header 이 값이 참이면, 헤더에 파일 디렉토리를 추가 + --alsologtostderr 파일처럼 표준 오류로도 로그 출력 + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용될 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + --log-backtrace-at traceLocation 로깅 시 N 행에 걸친 스택 추적 내용을 표시 (기본값 :0) + --log-dir string 값을 지정하면, 지정한 디렉토리에 로그 파일 기록 + --log-file string 값을 지정하면, 지정한 로그 파일 사용 + --log-file-max-size uint 로그파일이 증가할 수 있는 최대 크기 지정. 단위는 메가바이트이다. 값이 0이면, 최대 파일크기는 무제한. (기본값 1800) + --logtostderr 로그를 파일 대신 표준 출력으로 표시 (기본값 true) + -n, --namespace string 요청에 대한 네임스페이스 지정 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL 을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") + --skip-headers 이 값이 true이면, 로그파일에서 헤더 접두어를 미사용 + --skip-log-headers 이 값이 true이면, 로그파일을 열 때 헤더 제외 + --stderrthreshold severity stderr로 로그가 변경될 수 있는 최저 임계점 (기본값 2) + -v, --v Level 로그 수준 상세표시 레벨 + --vmodule moduleSpec 파일로 필터링된 로깅을 위한 패턴=N 설정의 쉼표로 구분된 리스트 +``` + +### 참조 + +* [helm show](helm_show.md) - 차트의 정보를 표시 + +###### Auto generated by spf13/cobra on 11-May-2020 diff --git a/content/ko/docs/helm/helm_show_values.md b/content/ko/docs/helm/helm_show_values.md new file mode 100644 index 0000000000..fe8d6e3471 --- /dev/null +++ b/content/ko/docs/helm/helm_show_values.md @@ -0,0 +1,65 @@ +--- +title: "Helm Show Values" +--- + +## helm show values + +차트의 값을 표시 + +### 개요 + + +이 명령어는 차트(디렉터리, 파일 또는 URL)를 검사하고, values.yaml 파일의 내용을 보여준다. + + +``` +helm show values [CHART] [flags] +``` + +### 옵션 + +``` + --ca-file string CA 번들을 사용하여 HTTPS 사용 서버의 인증서를 확인 + --cert-file string SSL 인증서 파일을 사용하여 HTTPS 클라이언트 식별 + --devel 개발 버전도 사용. 버전 '>0.0.0-0'에 해당하며 --version 이 설정되면 무시 + -h, --help values 에 대한 도움말 + --key-file string SSL 키 파일을 사용하여 HTTPS 클라이언트 식별 + --keyring string 확인에 사용되는 공개 키의 위치 (기본값 "~/.gnupg/pubring.gpg") + --password string 요청된 차트를 찾을 수 있는 차트 저장소 비밀번호 + --repo string 요청된 차트를 찾을 수 있는 차트 저장소 URL + --username string 요청된 차트를 찾을 수 있는 차트 저장소 사용자 이름 + --verify 설치하기 전에 패키지 확인 + --version string 설치할 정확한 차트의 버전을 지정. 만약 지정하지 않을 경우 최신 버전 지정 +``` + +### 부모 명령어에서 상속된 옵션들 + +``` + --add-dir-header 이 값이 참이면, 헤더에 파일 디렉토리를 추가 + --alsologtostderr 파일처럼 표준 오류로도 로그 출력 + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용될 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + --log-backtrace-at traceLocation 로깅 시 N 행에 걸친 스택 추적 내용을 표시 (기본값 :0) + --log-dir string 값을 지정하면, 지정한 디렉토리에 로그 파일 기록 + --log-file string 값을 지정하면, 지정한 로그 파일 사용 + --log-file-max-size uint 로그파일이 증가할 수 있는 최대 크기 지정. 단위는 메가바이트이다. 값이 0이면, 최대 파일크기는 무제한. (기본값 1800) + --logtostderr 로그를 파일 대신 표준 출력으로 표시 (기본값 true) + -n, --namespace string 요청에 대한 네임스페이스 지정 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL 을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") + --skip-headers 이 값이 true이면, 로그파일에서 헤더 접두어를 미사용 + --skip-log-headers 이 값이 true이면, 로그파일을 열 때 헤더 제외 + --stderrthreshold severity stderr로 로그가 변경될 수 있는 최저 임계점 (기본값 2) + -v, --v Level 로그 수준 상세표시 레벨 + --vmodule moduleSpec 파일로 필터링된 로깅을 위한 패턴=N 설정의 쉼표로 구분된 리스트 +``` + +### 참조 + +* [helm show](helm_show.md) - 차트의 정보를 표시 + +###### Auto generated by spf13/cobra on 11-May-2020 diff --git a/content/ko/docs/helm/helm_status.md b/content/ko/docs/helm/helm_status.md new file mode 100644 index 0000000000..9ceb317a63 --- /dev/null +++ b/content/ko/docs/helm/helm_status.md @@ -0,0 +1,64 @@ +--- +title: "Helm Status" +--- + +## helm status + +명명된 릴리스의 상태를 표시한다 + +### 개요 + + +이 명령어는 명명된 릴리스의 상태를 표시한다. +상태는 다음으로 구성된다: +- 마지막 배포 시간 +- 릴리스가 있는 k8s 네임스페이스 +- 릴리스의 상태 (가능한 값: unknown, deployed, uninstalled, superseded, failed, uninstalling, pending-install, pending-upgrade or pending-rollback) +이 릴리스를 구성하는, 종류(kind)로 정렬된 리소스 목록 +- 해당되는 경우, 마지막 테스트 스위트(test suite) 수행에 관한 세부 정보 +- 차트에서 제공하는 추가적인 참고 사항 + + +``` +helm status RELEASE_NAME [flags] +``` + +### 옵션 + +``` + -h, --help helm status 에 대한 도움말 + -o, --output format 지정된 형식으로 결과를 표시한다. 허용되는 값: table, json, yaml (기본값 table) + --revision int 지정하면, 해당 리비전의 명명된 릴리스 상태를 표시한다 +``` + +### 부모 명령어에서 상속된 옵션들 + +``` + --add-dir-header 이 값이 true이면, 헤더에 파일 디렉토리를 추가 + --alsologtostderr 파일처럼 표준 오류로도 로그 출력 + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용될 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + --log-backtrace-at traceLocation 로깅 시 N 행에 걸친 스택 추적 내용을 표시 (기본값 :0) + --log-dir string 값을 지정하면, 지정한 디렉토리에 로그 파일 기록 + --log-file string 값을 지정하면, 지정한 로그 파일 사용 + --log-file-max-size uint 로그파일이 증가할 수 있는 최대 크기 지정. 단위는 메가바이트이다. 값이 0이면, 최대 파일크기는 무제한. (기본값 1800) + --logtostderr 로그를 파일 대신 표준 출력으로 표시 (기본값 true) + -n, --namespace string 요청에 대한 네임스페이스 지정 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL 을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") + --skip-headers 이 값이 true이면, 로그파일에서 헤더 접두어를 미사용 + --skip-log-headers 이 값이 true이면, 로그파일을 열 때 헤더 제외 + --stderrthreshold severity stderr로 로그가 변경될 수 있는 최저 임계점 (기본값 2) + -v, --v Level 로그 수준 상세표시 레벨 + --vmodule moduleSpec 파일로 필터링된 로깅을 위한 패턴=N 설정의 쉼표로 구분된 리스트 +``` + +### 참조 + +* [helm](../helm) - 쿠버네티스에 대한 헬름 패키지 매니저. + +###### Auto generated by spf13/cobra on 11-May-2020 diff --git a/content/ko/docs/helm/helm_template.md b/content/ko/docs/helm/helm_template.md new file mode 100644 index 0000000000..69fa122589 --- /dev/null +++ b/content/ko/docs/helm/helm_template.md @@ -0,0 +1,86 @@ +--- +title: "Helm Template" +--- + +## helm template + +로컬에서 템플릿을 렌더링 한다. + +### 개요 + + +차트 템플릿을 로컬에서 렌더링하고 그 결과를 표시한다. + +일반적으로 클러스터 내에서 조회되거나 검색되는 모든 값은 로컬에서 즉흥적으로 사용(faked)된다. +또한 차트 유효성에 대한 서버 측 테스트 (예 : API 지원 여부)가 수행되지는 +않는다. + + +``` +helm template [NAME] [CHART] [flags] +``` + +### 옵션 + +``` + -a, --api-versions stringArray Capabilities.APIVersions에 사용되는 쿠버네티스 API 버전 + --atomic 설정된 경우, 설치 프로세스는 실패할 경우에 대하여 설치본을 삭제. --atomic 을 사용하면 --wait 플래그도 자동으로 설정 + --ca-file string 이 CA 번들을 사용하여 HTTPS 사용 서버의 인증서를 확인 + --cert-file string 이 SSL 인증서 파일을 사용하여 HTTPS 클라이언트 식별 + --create-namespace 릴리스 네임스페이스가 없는 경우 생성 + --dependency-update 차트를 설치하기 전에 헬름 종속성 업데이트 실행 + --description string 사용자 정의 설명 추가 + --devel 개발버전으로도 사용 가능. 버전 '>0.0.0.0' 에 해당하며, --version 이 설정되어 있을 경우 무시 + --disable-openapi-validation 설정된 경우, 설치 프로세스는 쿠버네티스 OpenAPI 스키마에 대해 렌더링 된 템플릿의 유효성 검사 미수행 + --dry-run 모의 설치 + -g, --generate-name 이름 생성 (후에 NAME 매개변수 생략) + -h, --help template 명령어에 대한 도움말 + --include-crds 템플릿 출력에 CRD 포함 CRD + --insecure-skip-tls-verify 차트 다운로드를 위한 TLS 인증서 검사 건너뛰기 + --is-upgrade Release.IsInstall 대신 .Release.IsUpgrade 를 지정 + --key-file string 이 SSL 키 파일을 사용하여 HTTPS 클라이언트 식별 + --keyring string 검증에 사용되는 공개키의 위치 지정(기본값 "~/.gnupg/pubring.gpg") + --name-template string 릴리스 이름을 지정 시 사용되는 템플릿 지정 + --no-hooks 설치 중 훅 실행 방지 + --output-dir string 실행된 템플릿을 표준 출력 대신 지정된 아웃풋 디렉터리의 파일에 작성 + --password string 요청된 차트를 찾을 수 있는 차트 저장소의 비밀번호 + --post-renderer postrenderer 포스트 렌더링에 사용될 실행 파일의 경로. $PATH 에 있으면 바이너리가 사용. 그렇지 않을 경우 주어진 경로에서 실행 파일을 탐색 (기본값 exec) + --release-name 아웃풋 디렉터리에 릴리스 이름 사용 + --render-subchart-notes 설정된 경우, 상위차트와 함께 하위차트의 메모를 렌더링 + --replace 해당 이름이 기록에 남아있는 삭제된 릴리스인 경우에만 주어진 이름을 재사용. 운영 환경에서는 권장되지 않음 + --repo string 요청된 차트를 찾을 수 있는 차트 저장소 URL + --set stringArray 명령 줄에서 값 설정(쉼표로 여러 값 또는 개별 값을 지정 가능: 키1=값1,키2=값2) + --set-file stringArray 명령 줄을 통해 지정된 각 파일에서 값 설정(쉼표로 여러 값 또는 개별 값을 지정 가능: 키1=경로1,키2=경로2) + --set-string stringArray 명령 줄에서 STRING 값 설정(쉼표로 여러 값 또는 개별 값을 지정 가능: 키1=값1,키2=값2) + -s, --show-only stringArray 주어진 템플릿에서 렌더링 된 매니페스트만을 표시 + --skip-crds 설정된 경우, CRD 미설치. 기본적으로 CRD는 아직 없는 경우 설치됨. + --timeout duration 개별 쿠버네티스 작업(예: 훅에 대한 작업)을 기다리는 시간 (기본값 5m0s) + --username string 요청 된 차트를 찾을 수 있는 차트 저장소 사용자 이름 + --validate 현재 가리키는 쿠버네티스 클러스터에 대해 매니페스트의 유효성을 검사. 이는 설치시 수행되는 것과 동일 + -f, --values strings YAML 파일 또는 URL 에 값 지정 (여러 개를 지정 가능) + --verify 사용하기 전에 패키지 확인 + --version string 사용할 정확한 차트 버전 지정. 지정하지 않을 경우 최신 버전 사용 + --wait 설정된 경우, 릴리스를 성공으로 표시하기 전에 모든 파드, PVC, 서비스, 디플로이먼트, 스테이트풀셋, 레플리카셋의 최소 파드가 Ready 상태가 될때까지 대기. --timeout 만큼 대기 +``` + +### 부모 명령어에서 상속된 옵션들 + +``` + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-as-group stringArray 작업에 관해 제시할 그룹. 플래그를 여러 번 사용하여 여러 그룹 지정 가능 + --kube-as-user string 작업에 관해 제시할 사용자명 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용될 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + -n, --namespace string 이 요청에 대한 네임스페이스 스코프 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL 을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") +``` + +### 함께 보기 + +* [helm](../helm) - 쿠버네티스에 대한 헬름 패키지 매니저. + +###### Auto generated by spf13/cobra on 29-Oct-2020 diff --git a/content/ko/docs/helm/helm_test.md b/content/ko/docs/helm/helm_test.md new file mode 100644 index 0000000000..f383ff8d7d --- /dev/null +++ b/content/ko/docs/helm/helm_test.md @@ -0,0 +1,49 @@ +--- +title: "Helm Test" +--- + +## helm test + +릴리스에 대하여 테스트를 수행한다. + +### 개요 + + +test 명령어는 릴리스에 대한 테스트를 실행한다. + +이 명령어가 받는 인수는 배포된 릴리스의 이름이다. +실행할 테스트는 설치된 차트에 정의되어 있다. + +``` +helm test [RELEASE] [flags] +``` + +### 옵션 + +``` + -h, --help helm test 에 대한 도움말 + --logs 테스트 파드에서 로그를 덤프 (모든 테스트가 완료된 후 정리 전에 실행) + --timeout duration 개별 쿠버네티스 작업(예: 훅에 대한 작업)을 기다리는 시간 제한 (기본값 5m0s) +``` + +### 부모 명령어에서 상속된 옵션들 + +``` + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-as-group stringArray 작업에 관해 제시할 그룹. 플래그를 여러 번 사용하여 여러 그룹 지정 가능 + --kube-as-user string 작업에 관해 제시할 사용자명 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용될 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + -n, --namespace string 이 요청에 대한 네임스페이스 스코프 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL 을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm](../helm) - 쿠버네티스에 대한 헬름 패키지 매니저. + +###### Auto generated by spf13/cobra on 29-Oct-2020 diff --git a/content/ko/docs/helm/helm_uninstall.md b/content/ko/docs/helm/helm_uninstall.md new file mode 100644 index 0000000000..573a4a5b89 --- /dev/null +++ b/content/ko/docs/helm/helm_uninstall.md @@ -0,0 +1,67 @@ +--- +title: "Helm Uninstall" +--- + +## helm uninstall + +릴리스 언인스톨 + +### 개요 + + +이 명령어는 릴리스 이름을 사용하여 릴리스를 언인스톨한다. + +차트의 마지막 릴리스 및 릴리스 내역과 관련된 모든 리소스를 제거하여 +나중에 사용할 수 있도록 해제한다. + + +실제 언인스톨은 하지 않고 릴리스가 언인스톨되는 것을 확인해보려면 +'--dry-run' 플래그를 사용하자. + + +``` +helm uninstall RELEASE_NAME [...] [flags] +``` + +### Options + +``` + --description string 사용자 정의 설명 추가 + --dry-run 언인스톨 시뮬레이션 + -h, --help uninstall 에 대한 도움말 + --keep-history 모든 관련 리소스를 제거하고 릴리스를 삭제로 표시하지만 릴리스 내역은 유지 + --no-hooks 언인스톨 중 훅(hook) 실행 방지 + --timeout duration 개별 쿠버네티스 작업(예: 훅(hook)을 위한 작업)을 기다리는 시간 (기본값 5m0s) +``` + +### 상위 명령에서 상속된 옵션들 + +``` + --add-dir-header 이 값이 true이면, 헤더에 파일 디렉토리를 추가 + --alsologtostderr 파일처럼 표준 오류로도 로그 출력 + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용될 문자열 전달 토큰 + --kubeconfig string kubeconfig 파일 경로 + --log-backtrace-at traceLocation 로깅 시 N 행에 걸친 스택 추적 내용을 표시 (기본값 :0) + --log-dir string 이 값이 비어있지 않을 경우, 이 값에 지정된 디렉토리에 로그 파일 쓰기 수행 + --log-file string 이 값이 비어있지 않을 경우, 이 값에 지정된 파일명으로 로그 파일 쓰기 수행 + --log-file-max-size uint 로그파일이 증가할 수 있는 최대 크기 지정. 단위는 메가 바이트이며 값이 0일 경우 최대 파일크기 제한 없음(기본 값 1800) + --logtostderr 로그를 파일이 아닌 표준 출력으로 표시 (기본값 : true) + -n, --namespace string 요청에 대한 네임스페이스 지정 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL 을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") + --skip-headers 이 값이 true이면, 로그파일에서 헤더 접두사를 미사용 + --skip-log-headers 이 값이 true이면, 로그 파일을 열 때 헤더 제외 + --stderrthreshold severity stderr로 로그가 변경될 수 있는 최저 임계점 (기본값 2) + -v, --v Level 상세 로그레벨 수준 + --vmodule moduleSpec 파일로 필터링 된 로깅을 위한 패턴=N 설정의 쉼표로 구분된 리스트 +``` + +### 참조 + +* [helm](../helm) - 쿠버네티스에 대한 헬름 패키지 매니저. + +###### Auto generated by spf13/cobra on 11-May-2020 diff --git a/content/ko/docs/helm/helm_upgrade.md b/content/ko/docs/helm/helm_upgrade.md new file mode 100644 index 0000000000..2e263e24ae --- /dev/null +++ b/content/ko/docs/helm/helm_upgrade.md @@ -0,0 +1,100 @@ +--- +title: "Helm Upgrade" +--- + +## helm upgrade + +릴리스를 업그레이드한다. + +### 개요 + +이 명령어는 릴리스를 새 버전의 차트로 업그레이드한다. + +업그레이드 시 사용되는 인수는 릴리스 및 차트여야 한다. +차트의 인수는 차트 참조('example/mariadb'), 차트 디렉터리 경로, +패키지 차트 또는 정규화된 URL 중 하나일 수 있다. +차트 참조 시 '--version' 플래그가 설정되지 않았을 경우 최신 버전이 지정된다. + +차트의 값을 재정의하려면 '--values' 플래그를 사용하고 파일을 +전달하거나 '--set' 플래그를 사용하고 명령 줄에서 구성을 전달하고, +문자열 값을 강제하려면 '--set-string' 을 사용한다. 값이 큰 경우 +'--value'나 '--set' 대신 +'--set-file'을 사용하여 파일에서 하나의 큰 값을 읽을 수도 있다. + +'--values'/'-f' 플래그를 여러 번 지정할 수도 있다. 지정된 마지막(가장 오른쪽) 파일에 우선 순위가 부여된다. +예를 들어 myvalues.yaml과 override.yaml에 'Test' 라는 키가 포함된 경우 +override.yaml에 설정된 값이 우선한다. + + $ helm upgrade -f myvalues.yaml -f override.yaml redis ./redis + +'--set' 플래그도 여러 번 지정할 수 있다. 지정된 마지막(가장 오른쪽) 파일에 +우선 순위가 부여된다. 예를 들어 'foo' 라는 키에 대해 'bar' 와 'newbar' 에서 +값이 모두 설정된 경우 'newbar' 가 우선한다. + + $ helm upgrade --set foo=bar --set foo=newbar redis ./redis + + +``` +helm upgrade [RELEASE] [CHART] [flags] +``` + +### 옵션 + +``` + --atomic 설정된 경우, 업그레이드 실패 시 변경 사항을 롤백. --atomic 을 사용하면 --wait 플래그가 자동으로 설정 + --ca-file string 이 CA 번들을 사용하여 HTTPS 사용 서버의 인증서를 확인 + --cert-file string 이 SSL 인증서 파일을 사용하여 HTTPS 클라이언트를 식별 + --cleanup-on-fail 업그레이드 실패 시, 이 업그레이드에서 생성된 새 리소스 삭제를 허용 + --create-namespace --install 이 설정된 경우 릴리스 네임스페이스가 없으면 생성 + --description string 사용자 정의 설명을 추가 + --devel 개발 버전도 사용. 버전 '>0.0.0-0'에 해당하며 --version 이 설정되어 있으면 무시 + --disable-openapi-validation 설정된 경우, 업그레이드 프로세스는 쿠버네티스 OpenAPI 스키마에 대해 렌더링된 템플릿의 유효성 검사 미수행 + --dry-run 업그레이드 시뮬레이션 + --force 대체 전략을 통해 리소스 강제 업데이트 + -h, --help 업그레이드 명령어에 대한 도움말 + --history-max int 릴리스 당 저장되는 최대 리비전 수를 제한. 0으로 지정할 경우 무제한(기본값 10) + --insecure-skip-tls-verify 차트 다운로드를 위한 TLS 인증서 검사 건너뛰기 + -i, --install 이 이름의 릴리스가 아직 없는 경우 설치 수행 + --key-file string 이 SSL 키 파일을 사용하여 HTTPS 클라이언트 식별 + --keyring string 확인에 사용되는 공개키의 위치 (기본값 "~/.gnupg/pubring.gpg") + --no-hooks 사전/사후 업그레이드 훅 비활성화 + -o, --output format 지정된 형식으로 출력을 인쇄. 허용되는 값:table, json, yaml (기본값 table) + --password string 요청된 차트를 찾을 수 있는 차트 저장소 비밀번호 + --post-renderer postrenderer 포스트 렌더링에 사용될 실행 파일의 경로. $PATH 에 있으면 바이너리가 사용되며 그렇지 않은 경우, 주어진 경로에서 실행파일을 탐색(기본 exec) + --render-subchart-notes 설정된 경우, 상위 차트와 함께 하위 차트 메모도 렌더링 + --repo string 요청된 차트를 찾을 수 있는 차트 저장소 URL + --reset-values 업그레이드 할 때, 값을 차트에 내장된 값으로 재설정 + --reuse-values 업그레이드 할 때, 마지막 릴리스의 값을 재사용하고 --set 및 -f 를 통해 명령 줄에서 재정의를 병합. '--reset-values' 가 지정될 경우 무시 + --set stringArray 명령줄에서 값 설정(쉼표로 여러 값 또는 개별 값을 지정 가능. key1=val1,key2=val2) + --set-file stringArray 명령줄을 통해 지정된 각 파일에서 값 설정(쉼표로 여러 값 또는 개별 값을 지정 가능. key1=val1,key2=val2) + --set-string stringArray 명령줄에서 STRING 값 설정(쉼표로 여러 값 또는 개별 값을 지정 가능. key1=val1,key2=val2) + --skip-crds 설정된 경우, 설치 플래그가 활성화 된 상태에서 업그레이드를 수행할 때 CRD 미설치. 기본적으로 설치 플래그가 활성화된 상태에서 업그레이드가 수행될때, 아직 없는 경우에는 CRD 설치 + --timeout duration 개별 쿠버네티스 (훅에 대한 작업과 같이)작업을 기다리는 시간 (기본값 5m0s) + --username string 요청된 차트를 찾을 수 있는 차트 저장소 사용자 이름 + -f, --values strings YAML 파일 또는 URL에 값 지정 (여러 개 지정 가능) + --verify 사용하기 전에 패키지 확인 + --version string 사용할 정확한 차트 버전 지정. 지정하지 않을 경우 최신 버전 사용 + --wait 설정된 경우, 릴리스를 성공으로 표시하기 전에 모든 파드, PVC, 서비스, 및 스테이트풀셋 또는 레플리카셋의 최소 파드 수가 준비 상태가 될때까지 대기. --timeout 플래그로 설정된 시간까지 대기 +``` + +### 부모 명령어에서 상속된 옵션들 + +``` + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-as-group stringArray 작업의 가상화를 위한 그룹. 이 플래그를 반복하여 여러 그룹을 지정 가능 + --kube-as-user string 작업의 가상화를 위한 사용자 이름 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용될 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + -n, --namespace string 요청에 대한 네임스페이스 지정 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL 을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") +``` + +### 참조 + +* [helm](helm.md) - 쿠버네티스에 대한 헬름 패키지 매니저. + +###### Auto generated by spf13/cobra on 29-Oct-2020 diff --git a/content/ko/docs/helm/helm_verify.md b/content/ko/docs/helm/helm_verify.md new file mode 100644 index 0000000000..d8b44d352d --- /dev/null +++ b/content/ko/docs/helm/helm_verify.md @@ -0,0 +1,63 @@ +--- +title: "Helm Verify" +--- + +## helm verify + +주어진 경로의 차트가 서명되었고, 유효한지 확인한다. + +### 개요 + + +주어진 차트에 유효한 출처(provenance) 파일이 있는지를 검증한다. + +출처 파일은 차트가 변조되지 않았으며 신뢰할 수 있는 공급자가 +패키징했다는 암호화 검증을 제공한다. + +이 명령어는 로컬 차트를 검증하는데 사용될 수 있다. 다른 여러 명령어는 +동일한 유효성 검사를 실행하는 '--verify' 플래그를 제공한다. 서명된 패키지를 생성하기 위해서는 +'helm package --sign' 명령어를 사용하자. + + +``` +helm verify PATH [flags] +``` + +### 옵션 + +``` + -h, --help verify 에 대한 도움말 + --keyring string 공개 키를 포함하는 키링(keyring) (기본값 "~/.gnupg/pubring.gpg") +``` + +### 부모 명령어에서 상속된 옵션들 + +``` + --add-dir-header 이 값이 true이면, 헤더에 파일 디렉토리를 추가 + --alsologtostderr 파일 및 표준오류로 로그 출력 + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용될 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + --log-backtrace-at traceLocation 로깅 시 N 행에 걸친 스택 추적 내용을 표시 (기본값 :0) + --log-dir string 값을 지정하면, 지정한 디렉토리에 로그 파일 기록 + --log-file string 값을 지정하면, 지정한 로그 파일 사용 + --log-file-max-size uint 로그파일이 증가할 수 있는 최대 크기 지정. 단위는 메가바이트이다. 값이 0이면, 최대 파일크기는 무제한. (기본값 1800) + --logtostderr 로그를 파일이 아닌 표준 오류로 표시 (기본값 true) + -n, --namespace string 요청에 대한 네임스페이스 지정 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL 을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") + --skip-headers 이 값이 true이면, 로그파일에서 헤더 접두어를 미사용 + --skip-log-headers 이 값이 true이면, 로그파일을 열 때 헤더 제외 + --stderrthreshold severity stderr로 로그가 변경될 수 있는 최저 임계점 (기본값 2) + -v, --v Level 로그 수준 상세표시 레벨 + --vmodule moduleSpec 파일로 필터링된 로깅을 위한 패턴=N 설정의 쉼표로 구분된 리스트 +``` + +### 참조 + +* [helm](../helm) - 쿠버네티스에 대한 헬름 패키지 매니저. + +###### Auto generated by spf13/cobra on 14-Sep-2020 diff --git a/content/ko/docs/helm/helm_version.md b/content/ko/docs/helm/helm_version.md new file mode 100644 index 0000000000..4a0e569ac8 --- /dev/null +++ b/content/ko/docs/helm/helm_version.md @@ -0,0 +1,75 @@ +--- +title: "Helm Version" +--- + +## helm version + +클라이언트 버전 정보를 출력한다. + +### 개요 + + +헬름의 버전을 표시한다. + +이 명령어는 헬름 버전을 특정 형식으로 출력한다. +출력결과는 대략 다음과 같을 것이다. + +version.BuildInfo{Version:"v3.2.1", GitCommit:"fe51cd1e31e6a202cba7dead9552a6d418ded79a", GitTreeState:"clean", GoVersion:"go1.13.10"} + +- Version 은 릴리스의 유의적(semantic) 버전이다. +- GitCommit 은 이 버전이 빌드된 커밋의 SHA 값이다. +- GitTreeState 는 이 바이너리를 빌드할 때 로컬 코드 변경이 없었으면 "clean" 이고, + 로컬에서 수정된 코드로 빌드한 바이너리이면 "dirty" 이다. +- GoVersion 은 헬름을 컴파일할 때 사용된 Go 버전이다. +--template 플래그를 사용하면 템플릿에서 다음 속성을 +사용할 수 있다: + +- .Version 은 헬름의 유의적 버전을 포함한다. +- .GitCommit 은 깃 커밋을 의미한다. +- .GitTreeState 는 헬름이 빌드 되었을 때 깃 트리의 상태이다. +- .GoVersion 은 헬름이 컴파일 된 Go 버전을 포함한다. + + +``` +helm version [flags] +``` + +### 옵션 + +``` + -h, --help version 에 대한 도움말 + --short 버전 번호만을 표시 + --template string 버전 문자열 형식에 대한 템플릿 +``` + +### 부모 명령어에서 상속된 옵션들 + +``` + --add-dir-header 이 값이 true이면, 헤더에 파일 디렉토리를 추가 + --alsologtostderr 파일처럼 표준 오류로도 로그 출력 + --debug 장황한(verbose) 출력 활성화 + --kube-apiserver string 쿠버네티스 API 서버의 주소 및 포트 + --kube-context string 사용할 kubeconfig 컨텍스트 이름 + --kube-token string 인증에 사용될 베어러(bearer) 토큰 + --kubeconfig string kubeconfig 파일 경로 + --log-backtrace-at traceLocation 로깅 시 N 행에 걸친 스택 추적 내용을 표시 (기본값 :0) + --log-dir string 값을 지정하면, 지정한 디렉토리에 로그 파일 기록 + --log-file string 값을 지정하면, 지정한 로그 파일 사용 + --log-file-max-size uint 로그파일이 증가할 수 있는 최대 크기 지정. 단위는 메가바이트이다. 값이 0이면, 최대 파일크기는 무제한. (기본값 1800) + --logtostderr 로그를 파일이 아닌 표준 오류로 표시 (기본값 true) + -n, --namespace string 요청에 대한 네임스페이스 지정 + --registry-config string 레지스트리 구성 파일에 대한 경로 (기본값 "~/.config/helm/registry.json") + --repository-cache string 캐시된 저장소 색인이 포함된 파일의 경로 (기본값 "~/.cache/helm/repository") + --repository-config string 저장소 이름 및 URL 을 포함하는 파일 경로 (기본값 "~/.config/helm/repositories.yaml") + --skip-headers 이 값이 true이면, 로그파일에서 헤더 접두어를 미사용 + --skip-log-headers 이 값이 true이면, 로그파일을 열 때 헤더 제외 + --stderrthreshold severity stderr로 로그가 변경될 수 있는 최저 임계점 (기본값 2) + -v, --v Level 로그 수준 상세표시 레벨 + --vmodule moduleSpec 파일로 필터링된 로깅을 위한 패턴=N 설정의 쉼표로 구분된 리스트 +``` + +### 참조 + +* [helm](../helm) - 쿠버네티스에 대한 헬름 패키지 매니저. + +###### Auto generated by spf13/cobra on 14-Sep-2020 diff --git a/content/ko/docs/howto/_index.md b/content/ko/docs/howto/_index.md new file mode 100644 index 0000000000..9fa8d47373 --- /dev/null +++ b/content/ko/docs/howto/_index.md @@ -0,0 +1,10 @@ +--- +title: "사용법" +weight: 2 +--- + +# 사용법 가이드 + +이곳에서는 “…를 어떻게 하나요.?”와 같은 질문에 대한 짧은 답변들을 찾을 수 있을 것이다. +이 사용법 가이드는 주제를 깊이 있게 다루지는 않으며, 그런 것은 [주제 가이드](../topics)내 자료에서 찾을 수 있을 것이다. +다만, 이곳의 가이드는 일반적인 작업들을 빨리 완수할 수 있게 도움을 줄 것이다. diff --git a/content/ko/docs/howto/chart_repository_sync_example.md b/content/ko/docs/howto/chart_repository_sync_example.md new file mode 100644 index 0000000000..8a7e7ccbec --- /dev/null +++ b/content/ko/docs/howto/chart_repository_sync_example.md @@ -0,0 +1,89 @@ +--- +title: "차트 리포지토리 동기화" +description: "로컬 및 원격 차트 리포지토리를 동기화하는 방법" +weight: 2 +--- + +*참고: 이곳의 예제들은 차트 리포지토리를 제공하는* +*Google Cloud Storage (GCS) 버킷에 맞게 작성되었다.* + +## 전제 조건 +* [gsutil](https://cloud.google.com/storage/docs/gsutil) 툴을 설치해야 한다. *gsutill rsync 기능이 필요하다.* +* 헬름 바이너리에 대한 접근 권한이 있어야 한다. +* _선택 사항: 실수로 파일을 삭제할 경우를 대비하여 GCS 버킷에 [오브젝트 버전 관리](https://cloud.google.com/storage/docs/gsutil/addlhelp/ObjectVersioningandConcurrencyControl#top_of_page)를 설정하는 것을 추천한다._ + +## 로컬 차트 리포지토리 디렉터리 설정 +[차트 리포지토리 가이드]({{< ref +"/docs/topics/chart_repository.md" >}})에서 한 것처럼 로컬 디렉터리를 만들고, 패키지된 차트를 그 디렉터리로 옮긴다. + +예제: +```console +$ mkdir fantastic-charts +$ mv alpine-0.1.0.tgz fantastic-charts/ +``` + +## 업데이트 된 index.yaml 생성 +다음과 같이 `helm repo index` 헬름 명령어에 원격 리포지토리의 디렉터리 경로와 URL을 전달하여 +업데이트된 index.yaml 파일을 생성한다. + +```console +$ helm repo index fantastic-charts/ --url https://fantastic-charts.storage.googleapis.com +``` +그러면 업데이트된 index.yaml 파일이 생성되고 +`fantastic-charts/` 디렉토리에 위치하게 된다. + +## 로컬 및 원격 차트 리포지토리 동기화 +`scripts/sync-repo.sh` 명령어에 로컬 디렉터리명과 +GCS 버킷명을 전달하여 디렉터리 컨텐츠를 GCS 버킷에 업로드한다. + +예제: +```console +$ pwd +/Users/me/code/go/src/helm.sh/helm +$ scripts/sync-repo.sh fantastic-charts/ fantastic-charts +Getting ready to sync your local directory (fantastic-charts/) to a remote repository at gs://fantastic-charts +Verifying Prerequisites.... +Thumbs up! Looks like you have gsutil. Let's continue. +Building synchronization state... +Starting synchronization +Would copy file://fantastic-charts/alpine-0.1.0.tgz to gs://fantastic-charts/alpine-0.1.0.tgz +Would copy file://fantastic-charts/index.yaml to gs://fantastic-charts/index.yaml +Are you sure you would like to continue with these changes?? [y/N]} y +Building synchronization state... +Starting synchronization +Copying file://fantastic-charts/alpine-0.1.0.tgz [Content-Type=application/x-tar]... +Uploading gs://fantastic-charts/alpine-0.1.0.tgz: 740 B/740 B +Copying file://fantastic-charts/index.yaml [Content-Type=application/octet-stream]... +Uploading gs://fantastic-charts/index.yaml: 347 B/347 B +Congratulations your remote chart repository now matches the contents of fantastic-charts/ +``` +## 차트 리포지토리 업데이트 +필요시 차트 리포지토리 컨텐츠의 로컬 복사본을 따로 보관하거나 +`gsutil rsync` 를 사용하여 원격 차트 리파지토리 컨텐츠를 로컬 디렉토리에 +복사해 둘 수 있다. + +예제: +```console +$ gsutil rsync -d -n gs://bucket-name local-dir/ # the -n flag does a dry run +Building synchronization state... +Starting synchronization +Would copy gs://bucket-name/alpine-0.1.0.tgz to file://local-dir/alpine-0.1.0.tgz +Would copy gs://bucket-name/index.yaml to file://local-dir/index.yaml + +$ gsutil rsync -d gs://bucket-name local-dir/ # performs the copy actions +Building synchronization state... +Starting synchronization +Copying gs://bucket-name/alpine-0.1.0.tgz... +Downloading file://local-dir/alpine-0.1.0.tgz: 740 B/740 B +Copying gs://bucket-name/index.yaml... +Downloading file://local-dir/index.yaml: 346 B/346 B +``` + +유용한 링크: +* [gsutil rsync](https://cloud.google.com/storage/docs/gsutil/commands/rsync#description) 에 + 대한 문서 +* [차트 리포지토리 가이드]({{< ref "/docs/topics/chart_repository.md" >}}) +* Google Cloud Storage의 + [오브젝트 버전 관리 및 동시성 제어](https://cloud.google.com/storage/docs/gsutil/addlhelp/ObjectVersioningandConcurrencyControl#overview)에 + 대한 문서 + diff --git a/content/ko/docs/howto/charts_tips_and_tricks.md b/content/ko/docs/howto/charts_tips_and_tricks.md new file mode 100644 index 0000000000..0ec6791ca8 --- /dev/null +++ b/content/ko/docs/howto/charts_tips_and_tricks.md @@ -0,0 +1,292 @@ +--- +title: "차트 개발 팁과 비법" +description: "Covers some of the tips and tricks Helm chart developers have learned while building production-quality charts." +weight: 1 +--- + +이 가이드는 핼름 차트 개발자들이 production-quality 차트들을 만들면서 배운 팁과 비법을 +담고 있습니다. + +## 템플릿 함수 이해하기 + +Helm uses [Go templates](https://godoc.org/text/template) for templating your +resource files. While Go ships several built-in functions, we have added many +others. + +First, we added all of the functions in the [Sprig +library](https://masterminds.github.io/sprig/). + +We also added two special template functions: `include` and `required`. The +`include` function allows you to bring in another template, and then pass the +results to other template functions. + +For example, this template snippet includes a template called `mytpl`, then +lowercases the result, then wraps that in double quotes. + +```yaml +value: {{ include "mytpl" . | lower | quote }} +``` + +The `required` function allows you to declare a particular values entry as +required for template rendering. If the value is empty, the template rendering +will fail with a user submitted error message. + +The following example of the `required` function declares an entry for +.Values.who is required, and will print an error message when that entry is +missing: + +```yaml +value: {{ required "A valid .Values.who entry required!" .Values.who }} +``` + +## 문자열에는 따옴표를 쓰고, 정수형에는 쓰지 말자 + +문자열 데이터를 사용할 때에는 문자열로 그대로 두기보다 +쌍따옴표로 값을 묶는 것이 안전합니다.: + +```yaml +name: {{ .Values.MyName | quote }} +``` + +하지만 integer는 많은 경우에 쿠버네티스에서 파싱에러가 발생할 수 있으니 +_쌍따옴표를 사용하지 마세요._ + +```yaml +port: {{ .Values.Port }} +``` + +env 변수들의 경우에는 앞서 말한 내용과는 다르게 모든 값들을 쌍따옴표로 묶는 것이 좋습니다.: + +```yaml +env: + - name: HOST + value: "http://host" + - name: PORT + value: "1234" +``` + +## 'include' 함수 사용하기 + +Go 언어의 내장 지시어인 `template`를 사용해 다른 템플릿으로 부터 템플릿을 가져올 수 있는 방법을 +제공합니다. 하지만 이 지시어는 파이프 라인과는 함께 사용 될 수 없습니다. + +헬름에는 특별한 함수 `include`가 있습니다. 이 함수는 다른 템플릿으로 부터 템플릿을 가져오고 +그 템플릿의 출력 값에 연산을 수행 할 수 있도록 합니다. + +``` +{{ include "toYaml" $value | indent 2 }} +``` + +위의 예제에는 `toYaml`이라고 불리는 템플릿이 포함되어 있습니다. 이 템플릿은 `$value`에 값을 전달하고 +그 출력 값을 `indent` 함수에 전달합니다. + +YAML이 들여쓰기와 공백을 중요하게 생각하기 때문에 이 방법은 문맥에 맞는 적절한 들여쓰기를 하면서 코드 스니펫을 +가져올 수 있는 좋은 방법입니다. + +## 'required' 함수 사용하기 + +Go 언어는 map에 존재하지 않은 키에 접근하는 상황을 제어하기 위한 템플릿 옵션이 있습니다. +주로 `template.Options("missingkey=option")`로 설정되며 `option`값은 `default`, `zero` 혹은 `error`가 될 수 있습니다. +옵션(option) 설정을 error로 하면 map에 존재하지 않는 키에 접근하려는 모든 상황에 에러를 발생하며 실행을 멈출 것입니다. +차트 개발자가 `values.yaml`에서 값을 가져올 때 이러한 규칙을 적용시키고 싶은 상황이 있을 수 있습니다. + +`required` 함수는 개발자가 템플릿이 랜더링될 때 필수로 입력되어야 하는 값(항목)을 선언할 수 있도록 합니다. +이 값(항목)이 `values.yaml`에 비어있다면, template은 랜더링을 하지 않고 개발자가 작성한 에러 메세지를 반환할 것입니다. + +예를 들어서: + +``` +{{ required "A valid foo is required!" .Values.foo }} +``` + +위의 예제는 `.Values.foo`가 정의 되어있다면 값을 랜더링 하고, +`.Values.foo`가 정의되어 있지 않다면 랜더링에 실패하고 종료할 것 입니다. + +## 'tpl' 함수 사용하기 + +`tpl` 함수를 이용하여 템플릿내에 정의 된 템플릿 형식의 문자열의 렌더링 값을 구할 수 있습니다. 이 함수는 차트에 템플릿 문자열을 변수로 전달하거나 외부 설정 파일들을 랜더링 할때 유용합니다. 문법: `{{ tpl TEMPLATE_STRING VALUES }}` + +예를 들어: + +```yaml +# values +template: "{{ .Values.name }}" +name: "Tom" + +# template +{{ tpl .Values.template . }} + +# output +Tom +``` + +외부 설정 값을 랜더링 하는 예제: + +```yaml +# external configuration file conf/app.conf +firstName={{ .Values.firstName }} +lastName={{ .Values.lastName }} + +# values +firstName: Peter +lastName: Parker + +# template +{{ tpl (.Files.Get "conf/app.conf") . }} + +# output +firstName=Peter +lastName=Parker +``` + +## 이미지 풀 시크릿 생성하기 +Image pull secrets은 _registry_, _username_, 그리고 +_password_의 조합이 기본입니다. 앱을 띄우는데 이 값들이 필요할 수 있지만, 이 값을 만들기 위해서는 `base64`를 몇번 수행해야 합니다. 우리는 helper 템플릿을 작성하여 시크릿 페이로드로써 사용될 도커 설정 파일을 구성할 수 있습니다. 여기 예제가 있습니다.: + +먼저 `values.yaml`에 다음과 같은 신원정보가 정의 되어 있다고 가정해 봅시다.: +```yaml +imageCredentials: + registry: quay.io + username: someone + password: sillyness + email: someone@host.com +``` + +그 다음, helper 템플릿을 다음과 같이 정의합니다.: +``` +{{- define "imagePullSecret" }} +{{- with .Values.imageCredentials }} +{{- printf "{\"auths\":{\"%s\":{\"username\":\"%s\",\"password\":\"%s\",\"email\":\"%s\",\"auth\":\"%s\"}}}" .registry .username .password .email (printf "%s:%s" .username .password | b64enc) | b64enc }} +{{- end }} +{{- end }} +``` + +마지막으로 큰 템플릿에서 helper 템플릿을 사용해 시크릿을 생성합니다.: +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: myregistrykey +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +``` + +## 자동 디플로이먼트 전환(roll) + +Often times ConfigMaps or Secrets are injected as configuration files in +containers or there are other external dependency changes that require rolling +pods. Depending on the application a restart may be required should those be +updated with a subsequent `helm upgrade`, but if the deployment spec itself +didn't change the application keeps running with the old configuration resulting +in an inconsistent deployment. + +The `sha256sum` function can be used to ensure a deployment's annotation section +is updated if another file changes: + +```yaml +kind: Deployment +spec: + template: + metadata: + annotations: + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} +[...] +``` + +In the event you always want to roll your deployment, you can use a similar +annotation step as above, instead replacing with a random string so it always +changes and causes the deployment to roll: + +```yaml +kind: Deployment +spec: + template: + metadata: + annotations: + rollme: {{ randAlphaNum 5 | quote }} +[...] +``` + +Both of these methods allow your Deployment to leverage the built in update +strategy logic to avoid taking downtime. + +NOTE: In the past we recommended using the `--recreate-pods` flag as another +option. This flag has been marked as deprecated in Helm 3 in favor of the more +declarative method above. + +## 헬름에 리소스를 언인스톨하지 않도록 알리기 + +Sometimes there are resources that should not be uninstalled when Helm runs a +`helm uninstall`. Chart developers can add an annotation to a resource to +prevent it from being uninstalled. + +```yaml +kind: Secret +metadata: + annotations: + "helm.sh/resource-policy": keep +[...] +``` + +(Quotation marks are required) + +The annotation `"helm.sh/resource-policy": keep` instructs Helm to skip deleting +this resource when a helm operation (such as `helm uninstall`, `helm upgrade` or +`helm rollback`) would result in its deletion. _However_, this resource becomes +orphaned. Helm will no longer manage it in any way. This can lead to problems if +using `helm install --replace` on a release that has already been uninstalled, +but has kept resources. + +## "Partials" 및 템플릿 포함(include) 사용하기 + +Sometimes you want to create some reusable parts in your chart, whether they're +blocks or template partials. And often, it's cleaner to keep these in their own +files. + +In the `templates/` directory, any file that begins with an underscore(`_`) is +not expected to output a Kubernetes manifest file. So by convention, helper +templates and partials are placed in a `_helpers.tpl` file. + +## 의존성이 많은 복잡한 차트 + +Many of the charts in the [official charts +repository](https://github.com/helm/charts) are "building blocks" for creating +more advanced applications. But charts may be used to create instances of +large-scale applications. In such cases, a single umbrella chart may have +multiple subcharts, each of which functions as a piece of the whole. + +The current best practice for composing a complex application from discrete +parts is to create a top-level umbrella chart that exposes the global +configurations, and then use the `charts/` subdirectory to embed each of the +components. + +## YAML은 JSON의 상위집합이다 + +According to the YAML specification, YAML is a superset of JSON. That means that +any valid JSON structure ought to be valid in YAML. + +This has an advantage: Sometimes template developers may find it easier to +express a datastructure with a JSON-like syntax rather than deal with YAML's +whitespace sensitivity. + +As a best practice, templates should follow a YAML-like syntax _unless_ the JSON +syntax substantially reduces the risk of a formatting issue. + +## 랜덤 값을 생성할 때는 주의하자 + +There are functions in Helm that allow you to generate random data, +cryptographic keys, and so on. These are fine to use. But be aware that during +upgrades, templates are re-executed. When a template run generates data that +differs from the last run, that will trigger an update of that resource. + +## 하나의 명령어로 설치 또는 업그레이드하기 + +Helm provides a way to perform an install-or-upgrade as a single command. Use +`helm upgrade` with the `--install` command. This will cause Helm to see if the +release is already installed. If not, it will run an install. If it is, then the +existing release will be upgraded. + +```console +$ helm upgrade --install --values +``` diff --git a/content/ko/docs/intro/_index.md b/content/ko/docs/intro/_index.md new file mode 100644 index 0000000000..f06063d8ec --- /dev/null +++ b/content/ko/docs/intro/_index.md @@ -0,0 +1,8 @@ +--- +title: "소개" +weight: 1 +--- + +# 헬름 소개 + +헬름이 처음이신가요? 이곳에서 시작하세요! diff --git a/content/ko/docs/intro/install.md b/content/ko/docs/intro/install.md new file mode 100644 index 0000000000..e3a398f46d --- /dev/null +++ b/content/ko/docs/intro/install.md @@ -0,0 +1,177 @@ +--- +title: "헬름 설치하기" +description: "헬름 설치하고 작동하는 방법 배우기." +weight: 2 +--- + +이 가이드는 헬름 CLI를 설치하는 방법을 설명한다. +헬름은 소스 또는 미리-빌드된(pre-built) +바이너리 릴리스로 설치할 수 있다. + +## 헬름 프로젝트로 + +헬름 프로젝트는 헬름을 가져와서 설치하는데 2가지 방법을 제공한다. +이것들은 헬름을 릴리스하기 위한 공식적인 방법들이다. +이외에도, 헬름 커뮤니티에서는 다양한 패키지 관리자를 통해 +헬름을 설치할 수 있는 방법을 제공하고 있다. 이러한 방법을 통한 설치는 아래에 있는 공식적인 방법들에서 확인할 수 있다. + +### 바이너리 릴리스로 + +헬름의 모든 [릴리스](https://github.com/helm/helm/releases)는 +다양한 OS들의 바이너리 릴리스를 제공한다. +이 바이너리 버전들은 수동으로 다운로드하여 설치할 수 있다. + +1. [원하는 버전](https://github.com/helm/helm/releases)을 다운로드한다. +2. 압축해제한다. (`tar -zxvf helm-v3.0.0-linux-amd64.tar.gz`) +3. 압축해제된 디렉토리에서 `helm` 바이너리를 찾아서, 원하는 목적지로 이동시킨다. +(`mv linux-amd64/helm /usr/local/bin/helm`) + +거기서부터, 클라이언트를 구동하고 [stable 저장소를 +추가](https://helm.sh/docs/intro/quickstart/#initialize-a-helm-chart-repository)할 수 있어야 한다: +`helm help`. + +**참고:** 헬름 자동화 테스트는 CircleCi 빌드와 릴리스 사이에, 리눅스 AMD64에서만 수행된다. +다른 OS들에 대한 테스트는, +대상 OS에 대한 헬름을 요청하는 커뮤니티에서 담당한다. + +### 스크립트로 + +이제 헬름은 헬름 최신 버전을 자동으로 가져와서 +[로컬에 설치](https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3)하는 +인스톨러 스크립트를 제공한다. + +이 스크립트를 받아서 로컬에서 실행할 수 있다. +문서화가 잘 되어 있으므로 실행 전에 문서를 읽어보면 무엇을 하는 것인지 이해할 수 있을 것이다. + +```console +$ curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 +$ chmod 700 get_helm.sh +$ ./get_helm.sh +``` + +최신이 필요하다면 `curl +https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash` +을 해보자. + +## 패키지 매니저를 통해서 + +헬름 커뮤니티 운영체제 패키지 관리자를 통해서 헬름을 설치할 수 있는 기능을 제공한다. +이것들은 헬름 프로젝트에서 지원되지 않으며 +신뢰 할 수 있는 제 3자로 간주되지 않는다. + +### Homebrew로 (맥OS) + +헬름 커뮤니티 멤버들은 Homebrew용 헬름 포뮬러 빌드에 기여해왔다. +이 포뮬러는 보통 최신이다. + +```console +brew install helm +``` + +(참고: emacs-helm 라는 포뮬러도 있는데, 다른 프로젝트이다.) + +### Chocolatey로 (윈도우) + +헬름 커뮤니티 멤버들은 [Chocolatey](https://chocolatey.org/)용 +[헬름 패키지](https://chocolatey.org/packages/kubernetes-helm) 빌드에 기여해왔다. +이 패키지는 보통 최신이다. + +```console +choco install kubernetes-helm +``` + +### Scoop으로 (윈도우) + +헬름 커뮤니티 멤버들은 [Scoop](https://scoop.sh)용 +[헬름 패키지](https://github.com/ScoopInstaller/Main/blob/master/bucket/helm.json) 빌드에 기여해왔다. 이 패키지는 보통 최신이다. + +```console +scoop install helm +``` + +### Apt로 (데비안/우분투) + +헬름 커뮤니티 멤버들은 Apt용 +[헬름 패키지](https://helm.baltorepo.com/stable/debian/)에 기여해왔다. +이 패키지는 보통 최신이다. + +```console +curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null +sudo apt-get install apt-transport-https --yes +echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list +sudo apt-get update +sudo apt-get install helm +``` + +### dnf/yum로 (페도라) +Fedora 35부터, 공식 저장소에서 헬름을 사용할 수 있다. +헬름을 호출하여 설치할 수 있다. + +```console +sudo dnf install helm +``` + +### Snap으로 + +[Snapcrafters](https://github.com/snapcrafters) 커뮤니티는 +[헬름 패키지](https://snapcraft.io/helm)의 Snap 버전을 유지보수한다. + +```console +sudo snap install helm --classic +``` + +### pkg로 (FreeBSD) + +FreeBSD 커뮤니티 멤버들은 [FreeBSD Ports Collections](https://man.freebsd.org/ports)용 +[헬름 패키지](https://www.freshports.org/sysutils/helm) +빌드에 기여해왔다. +이 패키지는 보통 최신이다. + +```console +pkg install helm +``` + +### 개발용 빌드 + +릴리스 외에도 헬름의 개발용 스냅샷을 +다운로드하거나 설치할 수 있다. + +### 카나리(canary) 빌드에서 + +"카나리" 빌드는 최신 마스터 브랜치로부터 빌드된 헬름 소프트웨어의 버전이다. +공식 릴리스가 아니며, 안정적이지 않을 수 있다. +하지만 최신 기능을 테스트할 기회를 제공한다. + +카나리 헬름 바이너리는 [get.helm.sh](https://get.helm.sh)에 저장된다. +아래는 일반 빌드에 대한 링크들이다: + +- [리눅스 AMD64](https://get.helm.sh/helm-canary-linux-amd64.tar.gz) +- [맥OS AMD64](https://get.helm.sh/helm-canary-darwin-amd64.tar.gz) +- [테스트용 윈도우 +AMD64](https://get.helm.sh/helm-canary-windows-amd64.zip) + +### 소스에서 (리눅스, 맥OS) + +소스로 헬름을 빌드하는 것은 약간 작업이 더 많다. +하지만 최신 (프리-릴리스) 헬름 버전을 테스트하기에는 가장 좋은 방법이다. + +작동하는 Go 환경이 필수적이다. + +```console +$ git clone https://github.com/helm/helm.git +$ cd helm +$ make +``` + +필요시에는 의존성(dependencies)을 페치(fetch)하고 캐시(cache)하며 설정 유효성검사를 하게 된다. +그러고 나서 `helm`을 컴파일하여 `bin/helm`에 둔다. + +## 맺음말 + +대부분의 경우, 설치는 미리-빌드된(pre-built) `helm` 바이너리를 가져오는 것으로 간단하게 설치할 수 있다. +이 문서는 좀 더 다양한 방법으로 헬름을 +사용하려는 사용자를 위한 여러 가지 방법을 제공한다. + +일단 헬름 클라이언트가 성공적으로 설치되면, 차트를 관리하고 +[stable 저장소를 추가](https://helm.sh/docs/intro/quickstart/#initialize-a-helm-chart-repository)하기 위해 +헬름을 사용할 수 있다. diff --git a/content/ko/docs/intro/quickstart.md b/content/ko/docs/intro/quickstart.md new file mode 100644 index 0000000000..dd85bf5f80 --- /dev/null +++ b/content/ko/docs/intro/quickstart.md @@ -0,0 +1,134 @@ +--- +title: "퀵스타트 가이드" +description: "배포판, FAQ, 플러그인의 설명을 포함한 헬름 설치 및 시작 방법" +weight: 1 +--- + +이 가이드는 헬름을 빠르게 시작하는 +방법에 대해 다룬다. + +## 전제 조건 + +헬름을 성공적이고 안전하게 사용하려면 +다음과 같은 전제 조건들이 필요하다. + +1. 쿠버네티스 클러스터 +2. 설치를 위해 어떤 보안 구성을 사용할 것인지 결정하기(필요시) +3. 헬름 설치 및 구성 + +### 쿠버네티스 설치 혹은 클러스터에 접근 + +- 쿠버네티스가 설치되어 있어야 한다. 최신 릴리스의 헬름을 사용하기 위해서, + 대부분의 경우 두번째 최신 마이너 릴리스 버전인 쿠버네티스 최신 안정(latest stable) + 릴리스 버전 설치를 권장한다. +- 또한 로컬로 구성된 `kubectl` 복사본이 있어야 한다. + +헬름과 쿠버네티스 사이의 버전차이정책(skew) 최대 버전은 [헬름 버전 지원 정책](https://helm.sh/docs/topics/version_skew/)을 참고한다. + +## 헬름 설치 + +헬름 클라이언트의 바이너리 릴리스를 다운로드한다. `homebrew` 와 같은 툴을 사용하거나 +[공식 릴리스 페이지](https://github.com/helm/helm/releases)를 참고하면 된다. + +자세한 내용이나 다른 옵션에 대해서는 [설치 +가이드]({{< ref "install.md" >}})를 참고한다. + +## 헬름 차트 리포지토리 초기화 + +헬름이 준비되면, 차트 리포지토리를 추가할 수 있다. 가능한 헬름 차트 레포지토리를 위해서 [Artifact +Hub](https://artifacthub.io/packages/search?kind=0)를 +확인한다. + +```console +$ helm repo add bitnami https://charts.bitnami.com/bitnami +``` + +차트 리포지토리 추가가 완료되면 설치할 수 있는 차트들의 목록을 볼 수 있다. + +```console +$ helm search repo bitnami +NAME CHART VERSION APP VERSION DESCRIPTION +bitnami/bitnami-common 0.0.9 0.0.9 DEPRECATED Chart with custom templates used in ... +bitnami/airflow 8.0.2 2.0.0 Apache Airflow is a platform to programmaticall... +bitnami/apache 8.2.3 2.4.46 Chart for Apache HTTP Server +bitnami/aspnet-core 1.2.3 3.1.9 ASP.NET Core is an open-source framework create... +# ... and many more +``` + +## 예제 차트 설치 + +차트를 설치하기 위해서, `helm install` 커맨드를 실행한다. +헬름은 차트를 설치하기 위한 몇가지 방법들이 존재하는데, +가장 쉬운 방법은 `bitnami` 차트들을 이용하는 것이다. + +```console +$ helm repo update # Make sure we get the latest list of charts +$ helm install bitnami/mysql --generate-name +NAME: mysql-1612624192 +LAST DEPLOYED: Sat Feb 6 16:09:56 2021 +NAMESPACE: default +STATUS: deployed +REVISION: 1 +TEST SUITE: None +NOTES: ... +``` + +위의 예에서, `bitnami/mysql` 차트가 릴리스되었고, +새로운 릴리스의 이름은 `mysql-1612624192` 이다. + +MySQL 차트에 대한 간단한 정보를 보려면 +`helm show chart bitnami/mysql` 를 실행한다. 또는 차트에 대한 모든 정보를 보려면 `helm show all bitnami/mysql` +를 실행할 수도 있다. + +차트를 설치할 때마다, 새로운 릴리스가 생성된다. 따라서 하나의 차트를 +동일한 클러스터에 여러 번 설치할 수 있다. 각각을 독립적으로 +관리 및 업그레이드 할 수 있다. + +`helm install` 커맨드는 다양한 기능을 가진 매우 강력한 커맨드이다. +더 많은 정보를 얻으려면, 이곳을 확인하면 된다. +[헬름 사용 가이드]({{< ref "using_helm.md" >}}) + +## 릴리스에 대해 알아보기 + +헬름을 사용하여 릴리스된 내용을 쉽게 확인할 수 있다. + +```console +$ helm list +NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION +mysql-1612624192 default 1 2021-02-06 16:09:56.283059 +0100 CET deployed mysql-8.3.0 8.0.23 +``` + +`helm list` (or `helm ls`) 함수는 배포된 모든 릴리스 목록을 보여준다. + +## 릴리스 설치 제거 + +릴리스를 설치 제거하려면, `helm uninstall` 커맨드를 사용한다. + +```console +$ helm uninstall mysql-1612624192 +release "mysql-1612624192" uninstalled +``` + +쿠버네티스에서 `mysql-1612624192` 를 설치 제거하면, 릴리스 이력 뿐 아니라 +릴리스와 관련된 리소스들도 모두 제거된다. + +`--keep-history` 플래그가 제공되면, 릴리스 이력은 유지된다. 그러면 +릴리스에 대한 정보를 요청할 수 있다. + +```console +$ helm status mysql-1612624192 +Status: UNINSTALLED +... +``` + +헬름은 릴리스를 제거한 후에도 릴리스를 추적하므로, 클러스터 이력을 +감사(audit)할 수 있고, 릴리스 삭제 취소도 가능하다. (`helm rollback`을 사용) + +## 도움말 읽기 + +헬름 커맨드 사용법에 대해 더 배우려면, `helm help` 을 사용하거나 +커맨드 뒤에 `-h` 플래그를 사용한다. + +```console +$ helm get -h +``` diff --git a/content/ko/docs/intro/using_helm.md b/content/ko/docs/intro/using_helm.md new file mode 100644 index 0000000000..14787e00fa --- /dev/null +++ b/content/ko/docs/intro/using_helm.md @@ -0,0 +1,479 @@ +--- +title: "헬름 사용하기" +description: "헬름의 기본사항을 설명한다." +weight: 3 +--- + +이 가이드는, 쿠버네티스 클러스터에서 패키지를 관리하는, 헬름 사용시의 기본사항을 설명한다. +헬름 클라이언트는 이미 [설치되어]({{< ref "install.md" >}}) 있다고 가정한다. + +명령어 몇 개를 빨리 실행해보는 데에 관심이 있다면 [퀵스타트 가이드]({{< ref "quickstart.md" >}})를 참고하는 것도 좋다. +이 장은 헬름 명령어들의 세부사항을 다루며, 헬름을 사용하는 방법을 설명한다. + +## 주요 개념 3가지 + +*차트*는 헬름 패키지이다. +이 패키지에는 쿠버네티스 클러스터 내에서 애플리케이션, 도구, 서비스를 구동하는데 필요한 모든 리소스 정의가 포함되어 있다. +쿠버네티스에서의 Homebrew 포뮬러, Apt dpkg, YUM RPM 파일과 같은 것으로 생각할 수 있다. + +*저장소*는 차트를 모아두고 공유하는 장소이다. +이것은 마치 Perl의 [CPAN 아카이브](https://www.cpan.org)나 [페도라 패키지 데이터베이스](https://src.fedoraproject.org/)와 같은데, 쿠버네티스 패키지용이라고 보면 된다. + +*릴리스*는 쿠버네티스 클러스터에서 구동되는 차트의 인스턴스이다. +일반적으로 하나의 차트는 동일한 클러스터내에 여러 번 설치될 수 있다. +설치될 때마다, 새로운 _release_ 가 생성된다. + +MySQL 차트의 경우를 생각해보자. +클러스터 내에 데이터베이스 2대를 구동하려면, 차트를 두번 설치하면 된다. +차례로 각각의 _release name_ 을 가지는, 각각의 _release_ 를 가지게 될 것이다. + +이러한 개념을 염두에 두고, 헬름 설명을 이어간다. + +헬름은 쿠버네티스 내부에 _charts_ 를 설치하고, 각 설치에 대해 새로운 _release_ 를 생성한다. +새로운 차트를 찾기 위해 헬름 차트 _repositories_ 를 검색할 수 있다. + +## 'helm search': 차트 찾기 + +헬름은 강력한 검색 명령어를 제공한다. 서로 다른 2가지 소스 유형을 검색하는데 사용할 수 있다. + +- `helm search hub`는 여러 저장소들에 있는 헬름 차트들을 포괄하는 [헬름 허브](https://hub.helm.sh)를 검색한다. +- `helm search repo`는 `helm repo add`를 사용하여 로컬 헬름 클라이언트에 추가된 저장소들을 검색한다. + 검색은 로컬 데이터 상에서 이루어지며, 퍼블릭 네트워크 접속이 필요하지 않다. + +`helm search hub`를 실행하면 공개적으로 사용 가능한 차트들을 찾아볼 수 있다. + +```console +$ helm search hub wordpress +URL CHART VERSION APP VERSION DESCRIPTION +https://hub.helm.sh/charts/bitnami/wordpress 7.6.7 5.2.4 Web publishing platform for building blogs and ... +https://hub.helm.sh/charts/presslabs/wordpress-... v0.6.3 v0.6.3 Presslabs WordPress Operator Helm Chart +https://hub.helm.sh/charts/presslabs/wordpress-... v0.7.1 v0.7.1 A Helm chart for deploying a WordPress site on ... +``` + +위와 같이 하면 헬름 허브에서 모든 `wordpress` 차트를 찾는다. + +필터 없이 `helm search hub`을 실행하면 사용 가능한 모든 차트를 보여준다. + +`helm search repo`를 사용하면, 기존에 추가된 저장소들에 있는 차트 이름을 볼 수 있다. + +```console +$ helm repo add brigade https://brigadecore.github.io/charts +"brigade" has been added to your repositories +$ helm search repo brigade +NAME CHART VERSION APP VERSION DESCRIPTION +brigade/brigade 1.3.2 v1.2.1 Brigade provides event-driven scripting of Kube... +brigade/brigade-github-app 0.4.1 v0.2.1 The Brigade GitHub App, an advanced gateway for... +brigade/brigade-github-oauth 0.2.0 v0.20.0 The legacy OAuth GitHub Gateway for Brigade +brigade/brigade-k8s-gateway 0.1.0 A Helm chart for Kubernetes +brigade/brigade-project 1.0.0 v1.0.0 Create a Brigade project +brigade/kashti 0.4.0 v0.4.0 A Helm chart for Kubernetes +``` + +helm search는 퍼지 문자열 매칭 알고리즘을 사용하므로, 단어 또는 문구의 일부분만 입력해도 된다. + +```console +$ helm search repo kash +NAME CHART VERSION APP VERSION DESCRIPTION +brigade/kashti 0.4.0 v0.4.0 A Helm chart for Kubernetes +``` +search는 사용 가능한 패키지를 찾는 좋은 방법이다. +설치하려는 패키지를 찾았다면 `helm install`을 이용하여 설치할 수 있다. + +## 'helm install': 패키지 설치 + +새 패키지를 설치하려면, `helm install` 명령어를 사용하자. + +가장 간단하게는 사용자가 지정한 릴리스 이름, 설치하려는 차트 이름의 2개 인수를 받는다. + +```console +$ helm install happy-panda stable/mariadb +Fetched stable/mariadb-0.3.0 to /Users/mattbutcher/Code/Go/src/helm.sh/helm/mariadb-0.3.0.tgz +happy-panda +Last Deployed: Wed Sep 28 12:32:28 2016 +Namespace: default +Status: DEPLOYED + +Resources: +==> extensions/Deployment +NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE +happy-panda-mariadb 1 0 0 0 1s + +==> v1/Secret +NAME TYPE DATA AGE +happy-panda-mariadb Opaque 2 1s + +==> v1/Service +NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE +happy-panda-mariadb 10.0.0.70 3306/TCP 1s + + +Notes: +MariaDB can be accessed via port 3306 on the following DNS name from within your cluster: +happy-panda-mariadb.default.svc.cluster.local + +To connect to your database run the following command: + + kubectl run happy-panda-mariadb-client --rm --tty -i --image bitnami/mariadb --command -- mysql -h happy-panda-mariadb +``` + +이제 `mariadb` 차트가 설치되었다. +차트를 설치하면 새 _release_ 오브젝트가 생성된다는 점을 알아두자. +위에서 릴리스의 이름이 `happy-panda`이다. +(헬름이 생성해주는 이름을 그대로 사용하려면 릴리스 이름을 넣지 말고 `--generate-name`을 사용하자.) + +설치하는 동안, `helm` 클라이언트는 어떤 리소스가 생성되는지, 릴리스의 상태는 어떤지, 추가 설정단계가 있는지에 관한 유용한 정보를 출력할 것이다. + +헬름은 모든 리소스가 구동(running)할 때까지 기다리지 않는다. + +많은 차트들이 크기 600M 이상의 Docker 이미지를 필요로 하며, 클러스터에 설치되기까지는 상당한 시간이 걸린다. + +릴리스의 상태 추적을 계속하거나, 구성 정보를 재확인하려면, `helm status`를 사용하자. + +```console +$ helm status happy-panda +Last Deployed: Wed Sep 28 12:32:28 2016 +Namespace: default +Status: DEPLOYED + +Resources: +==> v1/Service +NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE +happy-panda-mariadb 10.0.0.70 3306/TCP 4m + +==> extensions/Deployment +NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE +happy-panda-mariadb 1 1 1 1 4m + +==> v1/Secret +NAME TYPE DATA AGE +happy-panda-mariadb Opaque 2 4m + + +Notes: +MariaDB can be accessed via port 3306 on the following DNS name from within your cluster: +happy-panda-mariadb.default.svc.cluster.local + +To connect to your database run the following command: + + kubectl run happy-panda-mariadb-client --rm --tty -i --image bitnami/mariadb --command -- mysql -h happy-panda-mariadb +``` + +위와 같이 릴리스의 현재 상태가 표시된다. + + +### 설치 전 차트 커스터마이징 + +여기서는 이 차트의 기본 구성 옵션들만 사용할 것이다. +대부분의 경우 선호하는 구성을 사용하기 위해 차트를 커스터마이징하게 될 것이다. + +차트에 어떤 옵션이 구성 가능한지 보려면, `helm show values`를 사용하자. + +```console +$ helm show values stable/mariadb +Fetched stable/mariadb-0.3.0.tgz to /Users/mattbutcher/Code/Go/src/helm.sh/helm/mariadb-0.3.0.tgz +## Bitnami MariaDB image version +## ref: https://hub.docker.com/r/bitnami/mariadb/tags/ +## +## Default: none +imageTag: 10.1.14-r3 + +## Specify a imagePullPolicy +## Default to 'Always' if imageTag is 'latest', else set to 'IfNotPresent' +## ref: https://kubernetes.io/docs/user-guide/images/#pre-pulling-images +## +# imagePullPolicy: + +## Specify password for root user +## ref: https://github.com/bitnami/bitnami-docker-mariadb/blob/master/README.md#setting-the-root-password-on-first-run +## +# mariadbRootPassword: + +## Create a database user +## ref: https://github.com/bitnami/bitnami-docker-mariadb/blob/master/README.md#creating-a-database-user-on-first-run +## +# mariadbUser: +# mariadbPassword: + +## Create a database +## ref: https://github.com/bitnami/bitnami-docker-mariadb/blob/master/README.md#creating-a-database-on-first-run +## +# mariadbDatabase: +# ... +``` + +YAML 형식 파일에 있는 이러한 설정들을 오버라이드(override)하여, 설치시 파일과 함께 반영시킬 수 있다. + +```console +$ echo '{mariadbUser: user0, mariadbDatabase: user0db}' > config.yaml +$ helm install -f config.yaml stable/mariadb --generate-name +``` + +위와 같이 하면 `user0`이라는 기본 MariaDB 사용자가 생성될 것이고, +이 사용자에게는 새로 생성된 `user0db` 데이터베이스에 대한 접근권한이 부여되지만, +나머지 모든 기본설정은 해당 차트를 따르게 된다. + +설치 작업에 구성 데이터를 전달하는 방법에는 두가지가 있다. + +- `--values` (또는 `-f`): 오버라이드(override)할 YAML 파일을 지정한다. + 여러 번 지정할 수 있지만 가장 오른쪽에 있는 파일이 우선시된다. +- `--set`: 명령줄 상에서 오버라이드(override)를 지정한다. + +둘 다 사용하면, `--set` 값은 더 높은 우선순위를 가진 `--values` 으로 병합된다. +`--set`에 명시된 오버라이드 사항들은 컨피그맵(ConfigMap)으로 보관된다. +`helm get values `로 해당 릴리스에 대한 `--set` 설정값들을 조회할 수 있다. +`--set` 설정값들은 `helm upgrade`를 실행할 때 `--reset-values`를 명시하여 제거할 수 있다. + +#### `--set`의 형식과 제한점 + +`--set` 옵션은 0개 이상의 이름/값 쌍을 받는다. +가장 간단하게는 `--set name=value`와 같이 사용할 수 있다. +YAML로 표현하면 다음과 같다. + +```yaml +name: value +``` + +여러 개의 값들은 `,` 문자로 구분된다. 그래서 `--set a=b,c=d`는 다음과 같다. + +```yaml +a: b +c: d +``` + +더 복잡한 표현도 지원한다. 예를 들어, `--set outer.inner=value` +는 다음과 같이 표현된다. +```yaml +outer: + inner: value +``` + +리스트는 `{`, `}` 를 사용하여 표현할 수 있다. +예를 들어, `--set name={a, b, c}`는 다음과 같이 표현된다. + +```yaml +name: + - a + - b + - c +``` + +헬름 2.5.0이라면, 배열 인덱스 문법을 써서 리스트 항목들에 접근할 수 있다. +예를 들어 `--set servers[0].port=80` 는 다음과 같이 된다. + +```yaml +servers: + - port: 80 +``` + +여러 개의 값들이 이런 방식으로 설정될 수 있다. +`--set servers[0].port=80,servers[0].host=example` 행은 다음과 같이 된다. + +```yaml +servers: + - port: 80 + host: example +``` + +때로는 `--set` 행에 특수문자를 써야할 필요가 있을 것이다. +문자를 이스케이프하기 위해 백슬래시를 사용할 수 있다. `--set name=value1\,value2`는 다음과 같다. + +```yaml +name: "value1,value2" +``` + +비슷한 예로, `toYaml` 기능으로 어노테이션, 레이블, 노드 셀렉터를 파싱하는 차트에서 편리하게 사용되는 점 표기를 이스케이프할 수 있다. +`--set nodeSelector."kubernetes\.io/role"=master`를 나타내는 구문은 다음과 같다. + +```yaml +nodeSelector: + kubernetes.io/role: master +``` + +여러 단계로 중첩된 자료구조는 `--set`로 표현하기 어려울 수 있다. +차트 설계자는 `values.yaml` 파일의 형식을 설계할 때 `--set`를 사용하는 경우도 고려해주면 좋다. + +### 더 많은 설치 방법들 + +`helm install` 명령어를 사용하여 여러 소스에서 설치를 수행할 수 있다. + +- 차트 저장소 (위에서 살펴본 것) +- 로컬 차트 압축파일 (`helm install foo foo-0.1.1.tgz`) +- 압축해제된 차트 디렉토리 (`helm install foo path/to/foo`) +- 완전한 URL (`helm install foo https://example.com/charts/foo-1.2.3.tgz`) + +## 'helm upgrade' 및 'helm rollback': 릴리스 업그레이드 및 실패 복구 + +새로운 버전의 차트가 릴리스되었을 때, 또는 릴리스의 구성을 변경하고자 할 때, +`helm upgrade` 명령어를 사용할 수 있다. + +업그레이드는 현존하는 릴리스를 가지고, 사용자가 입력한 정보에 따라 업그레이드한다. +쿠버네티스 차트는 크고 복잡할 수 있기 때문에, 헬름은 최소한의 개입으로 업그레이드를 수행하려고 한다. +최근 릴리스 이후로 변경된 것들만 업데이트하게 될 것이다. + +```console +$ helm upgrade -f panda.yaml happy-panda stable/mariadb +Fetched stable/mariadb-0.3.0.tgz to /Users/mattbutcher/Code/Go/src/helm.sh/helm/mariadb-0.3.0.tgz +happy-panda has been upgraded. Happy Helming! +Last Deployed: Wed Sep 28 12:47:54 2016 +Namespace: default +Status: DEPLOYED +... +``` + +위의 경우, `happy-panda` 릴리스의 차트가 업그레이드되는데 새 YAML 파일도 반영된다. + +```yaml +mariadbUser: user1 +``` + +`helm get values`를 사용하여 새로운 설정이 적용되었는지 확인해 볼 수 있다. + +```console +$ helm get values happy-panda +mariadbUser: user1 +``` + +`helm get` 명령어는 클러스터에서 릴리스 정보를 확인할 때 유용한 도구이다. +위의 예에서 `panda.yaml`의 새로운 값이 클러스터에 배포되었음을 확인할 수 있다. + +릴리스가 계획대로 되지 않는다면, +`helm rollback [RELEASE] [REVISION]`를 사용하여 이전 릴리스로 간단히 롤백할 수 있다. + +```console +$ helm rollback happy-panda 1 +``` + +위와 같이 하면 happy-panda가 맨 첫번째 릴리스 버전으로 롤백된다. +릴리스 버전은 증분 리비전(incremental revision)을 나타낸다. +설치, 업그레이드, 롤백 등이 실행될 때마다, 리비전 번호는 1씩 증가한다. +첫 번째 리비전 번호는 항상 1이다. +특정 릴리스의 리비전 번호를 확인하기 위해서는 `helm history [RELEASE]`를 사용할 수 있다. + +## 설치/업그레이드/롤백에 관한 유용한 옵션들 + +설치/업그레이드/롤백 시의 헬름 작동을 커스터마이징하는 다른 여러 유용한 옵션들이 있다. +아래 나열한 CLI 플래그가 전체 목록은 아니라는 점을 알아두자. +모든 플래그들에 관한 설명을 보려면, `helm --help`을 실행하자. + +- `--timeout`: 쿠버네티스 명령어가 완료되기를 기다려주는 시간 값(초) + 기본값은 5m0s` +- `--wait`: 릴리스가 성공적이었다고 기록하기 전에, + 모든 포드들이 준비 상태가 되고 PVC들이 연결되고 + 디플로이먼트가 최소한(`Desired` - `maxUnavailable`)의 준비 상태 포드 수를 갖추며 + 서비스들이 IP 주소(`LoadBalancer`라면 인그레스)를 가질 때까지 + 기다린다. `--timeout` 값만큼 기다릴 것이다. + 타임아웃되면 릴리스는 `FAILED`로 기록될 것이다. 참고: + 롤링 업데이트 전략의 일부로서 `replicas` 설정은 1이고 `maxUnavailable` 설정은 0이 아닌 디플로이먼트의 경우, + `--wait`는 최소 준비 상태 포드 수를 만족하면 준비 상태로 응답할 것이다. +- `--no-hooks`: 명령어에 대한 훅(hook) 작동을 생략함 +- `--recreate-pods` (`upgrade`와 `rollback`에만 적용가능): 이 플래그는 + 모든 포드들의 재생성을 일으킬 수 있다 (디플로이먼트에 속한 포드들은 제외). (헬름 3에서 사용 중단(DEPRECATED)) + +## 'helm uninstall': 릴리스 언인스톨하기 + +클러스터에서 릴리스를 언인스톨하고자 할 때, `helm uninstall`을 사용해보자. + +```console +$ helm uninstall happy-panda +``` + +이렇게 하면 클러스터에서 릴리스가 제거될 것이다. +`helm list` 명령어로 현재 배포된 모든 릴리스들을 확인할 수 있다. + +```console +$ helm list +NAME VERSION UPDATED STATUS CHART +inky-cat 1 Wed Sep 28 12:59:46 2016 DEPLOYED alpine-0.1.0 +``` + +위의 결과에서 `happy-panda` 릴리스가 언인스톨된 것을 확인할 수 있다. + +Helm 구버전에서는 릴리스를 삭제하면 삭제된 기록이 남았는데, +Helm 3에서는 삭제시에 릴리스 기록도 제거한다. +삭제 릴리스 기록을 보존하고 싶다면, `helm uninstall --keep-history`을 사용하자. +`helm list --uninstalled`는 사용하면, `--keep-history` 플래그로 언인스톨된 릴리스들만 볼 수 있다. + +`helm list --all` 플래그는, 실패하거나 삭제(`--keep-history` 지정된 경우)된 기록을 포함하여, +헬름이 가지고 있는 모든 릴리스 기록들을 보여준다. + + +```console +$ helm list --all +NAME VERSION UPDATED STATUS CHART +happy-panda 2 Wed Sep 28 12:47:54 2016 UNINSTALLED mariadb-0.3.0 +inky-cat 1 Wed Sep 28 12:59:46 2016 DEPLOYED alpine-0.1.0 +kindred-angelf 2 Tue Sep 27 16:16:10 2016 UNINSTALLED alpine-0.1.0 +``` + +기본적으로 릴리스는 바로 삭제되기 때문에, 언인스톨된 리소스를 롤백하는 것을 불가능하는 것을 알아두자. + +## 'helm repo': 저장소 작업하기 + +헬름 3는 더 이상 기본 차트 저장소를 제공하지 않는다. +`helm repo` 명령어 그룹은 저장소를 추가, 목록조회, 제거하는 명령어를 제공한다. + +`helm repo list`를 사용하여 어떤 저장소들이 설정되어 있는지 확인할 수 있다. + +```console +$ helm repo list +NAME URL +stable https://charts.helm.sh/stable +mumoshu https://mumoshu.github.io/charts +``` + +`helm repo add`로 새 저장소들을 추가할 수 있다. + +```console +$ helm repo add dev https://example.com/dev-charts +``` + +차트 저장소는 자주 바뀌므로, `helm repo update`을 실행하여 언제든 헬름 클라이언트를 +업데이트할 수 있다. + +`helm repo remove`로 저장소들을 삭제할 수 있다. + +## 내 차트 만들기 + + +[차트 개발 가이드](https://helm.sh/docs/topics/charts/)는 내 차트를 개발하는 방법을 설명한다. +하지만 `helm create` 명령어를 사용하여 빠르게 시작해볼 수 있다: + +```console +$ helm create deis-workflow +Creating deis-workflow +``` + +이제 `./deis-workflow`에 차트가 생겼다. +생성된 차트를 편집하거나 내 템플릿을 생성할 수 있다. + +차트를 편집했다면, `helm lint`를 실행하여 형식이 맞지는 검증할 수 있다. + +배포용 차트로 패키징하고자 할 때는, `helm package` 명령어를 사용할 수 있다: + +```console +$ helm package deis-workflow +deis-workflow-0.1.0.tgz +``` + +이 차트는 이제 `helm install`로 쉽게 설치할 수 있다: + +```console +$ helm install deis-workflow ./deis-workflow-0.1.0.tgz +... +``` + +패키징된 차트들은 차트 저장소에 보관할 수 있다. +업로드하는 방법을 알아보려면 차트 저장소 서버에 관한 문서를 보자. + +참고: `stable` 저장소는 [쿠버네티스 차트 GitHub 저장소](https://github.com/helm/charts)에서 관리한다. +해당 프로젝트는 차트 소스코드를 받고 검사(audit) 후 패키징한다. + +## 맺음말 + +이 장은 검색, 설치, 업그레이드, 언인스톨을 포함한 `helm` 클라이언트의 기본 사용패턴을 다룬다. +또한 `helm status`, `helm get`, `helm repo`와 같은 유용한 도구 명령어도 다루었다. + +이 명령어들에 대해 더 알아보려면, 헬름에 내장된 도움말을 보도록 하자. +`helm help` + +다음 장에서는, 차트 개발 프로세스를 살펴볼 것이다. diff --git a/content/ko/docs/topics/_index.md b/content/ko/docs/topics/_index.md new file mode 100644 index 0000000000..876a18ddb4 --- /dev/null +++ b/content/ko/docs/topics/_index.md @@ -0,0 +1,8 @@ +--- +title: "주제" +weight: 3 +--- + +# 주제 가이드 + +알고 싶었던 헬름의 모든 핵심부분에 관한 설명을 이곳에서 찾을 수 있을 것이다. diff --git a/content/ko/docs/topics/advanced.md b/content/ko/docs/topics/advanced.md new file mode 100644 index 0000000000..7e6ef4464f --- /dev/null +++ b/content/ko/docs/topics/advanced.md @@ -0,0 +1,221 @@ +--- +title: "고급 헬름 기법" +description: "헬름의 숙련된 사용자를 위한 다양한 고급 기능을 설명한다." +weight: 9 +--- + +이 섹션에서는 헬름 사용에 관한 다양한 고급 기능과 기법을 설명한다. +이 섹션의 정보는 차트 및 릴리스의 고급 사용자 정의 및 조작을 +수행하려는 헬름의 "숙련 사용자"를 위한 것이다. 이러한 각 +고급 기능에는 고유한 장단점 및 주의사항이 있으므로, 각 기능은 +헬름에 대해 충분한 지식을 가지고 신중하게 사용해야한다. +바꿔 말해서, [Peter Parker +원칙](https://en.wikipedia.org/wiki/With_great_power_comes_great_responsibility)을 유념하자. + +## 포스트 렌더링 +포스트 렌더링은 차트 설치 프로그램이 헬름으로 설치하기 전에 +렌더링된 매니페스트를 수동으로 조작, 구성 및 유효성 검사를 할 수 있는 기능을 제공한다. +이를 통해 [`kustomize`](https://kustomize.io) 같은 도구를 사용하는 고급 구성 사용자들이, +공개 차트를 포크하거나 차트 유지관리자에게 소프트웨어에 대한 +모든 최종 구성옵션을 지정하도록 요구하지 않고도 +구성 변경사항을 적용할 수 있도록 해준다. 또한 엔터프라이즈 환경이나 +배포 전 매니페스트 분석시에 공통 도구와 사이트카를 주입하는 +사용 사례도 있다. + +### 전제 조건 +- 헬름 버전 3.1 이상 + +### 사용법 +포스트 렌더러는 STDIN 에서 렌더링된 쿠버네티스 매니페스트를 받고 +STDOUT 으로 유효한 쿠버네티스 매니페스트를 반환하는 실행파일이면 된다. +실패 시에는 0이 아닌 종료 코드를 반환해야 한다. +이것은 두 구성 요소 사이의 유일한 "API" 이다. +이러한 구조는 포스트 렌더 프로세스로 수행할 수 있는 작업에 유연성을 제공한다. + +포스트 렌더러는 `install`, `upgrade`, `template` 과 함께 사용할 수 있다. 포스트 +렌더러를 사용하려면 렌더러 실행파일의 경로와 함께 +`--post-renderer` 플래그를 사용한다. + +```shell +$ helm install mychart stable/wordpress --post-renderer ./path/to/executable +``` + +경로에 구분자가 없으면 $PATH 에서 검색하고, 그렇지 않으면 상대경로를 +완전한 전체 경로로 풀어낸다. + +여러 개의 포스트 렌더러를 사용하려면 스크립트에서 모두 호출하거나 빌드한 +바이너리 도구에서 함께 호출해야 한다. bash의 경우, +`renderer1 | renderer2 | renderer3` 와 같이 간단하게 표현할 수 있다. + +`kustomize` 를 포스트 렌더러로 사용하는 예는 +[이곳](https://github.com/thomastaylor312/advanced-helm-demos/tree/master/post-render)에서 확인할 수 있다. + +### 주의사항 +포스트 렌더러를 사용할 때 유의해야 하는 몇 가지 중요한 사항들이 있다. +포스트 렌더러를 사용할 때 가장 중요한 것은, 해당 릴리스를 +수정하는 모든 사람들이 반복 가능한 빌드를 갖기 위해서는 **반드시** 동일한 +렌더러를 사용해야 한다는 것이다. 이 기능은 사용자가 사용 중인 +렌더러를 전환하거나 렌더러 사용을 중지할 수 있게 하려고 만들어졌지만 +우발적인 수정이나 데이터 손실을 방지하기 위해서는 신중하게 수행해야 한다. + +또 다른 중요한 사항은 보안에 관한 것이다. 포스트 렌더러를 사용하는 +경우 다른 임의의 실행 파일의 경우와 마찬가지로 신뢰할 수 있는 +소스에서 가져온 것인지 확인해야 한다. 신뢰할 수 없거나 확인되지 +않은 렌더러를 사용하는 것은 종종 시크릿 데이터를 포함하는 렌더링 +된 템플릿에 대한 전체 접근 권한을 갖게 되므로 권장되지 않는다. + +### 사용자 정의 포스트 렌더러 +포스트 렌더러 단계는 Go SDK에서 사용할 때 훨씬 더 많은 유연성을 제공한다. +모든 포스트 렌더러는 다음 Go 인터페이스만 구현하면 된다. + +```go +type PostRenderer interface { + // Run 함수는 헬름 렌더링 매니페스트로 채워진 단일 버퍼가 필요하다. + // 수정된 결과가 별도의 버퍼에 반환되거나 포스트 렌더링 단계를 실행하는 + // 동안 이슈나 실패가 발생한 경우 오류가 반환된다. + Run(renderedManifests *bytes.Buffer) (modifiedManifests *bytes.Buffer, err error) +} +``` + +Go SDK 사용에 대한 자세한 내용은 [Go SDK 섹션](#go-sdk)를 참조하자. + +## Go SDK +헬름 3는 헬름을 활용하는 소프트웨어 및 도구를 +빌드할 때 더 나은 경험을 제공하기 위해 완전 +재구성된 Go SDK를 선보였다. +전체 문서는 [https://pkg.go.dev/helm.sh/helm/v3](https://pkg.go.dev/helm.sh/helm/v3)에서 +찾을 수 있지만 가장 일반적인 패키지 중 일부와 간단한 예제는 다음과 같다. + +### 패키지 개요 +다음은 가장 널리 사용되는 패키지들의 목록과 +그에 관한 간단한 설명이다. + +- `pkg/action`: 헬름 작업을 수행하기 위한 기본 "클라이언트"를 + 포함해야 한다. 이것은 CLI가 내부적으로 사용하는 것과 + 동일한 패키지이다. 다른 Go 프로그램에서 기본 헬름 명령어만 + 수행하고자 하는 경우 이 패키지가 적합하다. +- `pkg/{chart,chartutil}`: 차트를 로드하고 조작하는데 사용되는 메서드 및 + 헬퍼이다. +- `pkg/cli` 및 해당 하위 패키지: 표준 헬름 환경 변수에 대한 모든 + 핸들러를 포함하고 하위 패키지에는 출력 및 값 파일 + 처리를 포함한다. +- `pkg/release`: `Release` 오브젝트 및 상태를 정의한다. + +이 외에도 더 많은 패키지가 있으므로, 자세한 내용은 설명서를 확인하자! + +### 간단한 예 +다음은 Go SDK를 사용하여 `helm list` 를 수행하는 간단한 예이다. + +```go +package main + +import ( + "log" + "os" + + "helm.sh/helm/v3/pkg/action" + "helm.sh/helm/v3/pkg/cli" +) + +func main() { + settings := cli.New() + + actionConfig := new(action.Configuration) + // You can pass an empty string instead of settings.Namespace() to list + // all namespaces + if err := actionConfig.Init(settings.RESTClientGetter(), settings.Namespace(), os.Getenv("HELM_DRIVER"), log.Printf); err != nil { + log.Printf("%+v", err) + os.Exit(1) + } + + client := action.NewList(actionConfig) + // Only list deployed + client.Deployed = true + results, err := client.Run() + if err != nil { + log.Printf("%+v", err) + os.Exit(1) + } + + for _, rel := range results { + log.Printf("%+v", rel) + } +} + +``` + +## 스토리지 백엔드 + +헬름 3는 기본 릴리스 정보 저장소를 릴리스의 네임스페이스에서 +시크릿으로 변경하였다. 헬름 2는 기본적으로 릴리스 정보를 +틸러(Tiller) 인스턴스 네임스페이스의 컨피그맵으로 저장한다. +다음 하위 섹션에서는 다양한 백엔드를 구성하는 방법을 보여준다. +이 구성은 `HELM_DRIVER` 환경 변수를 기반으로 한다. +값은 `[configmap, secret, sql]` 중 하나로 설정될 수 있다. + +### 컨피그맵 스토리지 백엔드 + +컨피그맵 백엔드를 활성화 하려면 환경 변수를 `HELM_DRIVER` 에서 `configmap` 로 +설정해야 한다. + +다음과 같이 셸에서 설정할 수 있다. + +```shell +export HELM_DRIVER=configmap +``` + +기본 백엔드에서 컨피그맵 백엔드로 전환하려면 +직접 마이그레이션을 수행해야 한다. 다음 명령어를 +사용하여 릴리스 정보를 검색할 수 있다. + +```shell +kubectl get secret --all-namespaces -l "owner=helm" +``` + +**운영 참고사항**: 출시 정보에는 무단 접근으로부터 +보호해야 하는 민감한 데이터(예: 비밀번호, 개인키 및 +기타 자격증명)가 포함될 수 있다. 예를 들어 +[RBAC](https://kubernetes.io/docs/reference/access-authn-authz/rbac/)을 +사용하여 쿠버네티스 인증을 관리할 때 컨피그맵 +리소스에 대한 광범위한 접근 권한을 부여하는 +동시에 시크릿 리소스에 대한 접근을 제한할 수 있다. +예를 들어 기본 [사용자 대면 역할](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#user-facing-roles) 보기 +권한은 대부분의 리소스에 접근 권한을 부여하지만, 보안 시크릿에는 부여하지 않는다. +또한 [암호화 된 저장소](https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/)에 +대해 시크릿 데이터를 구성할 수 있다. +컨피그맵 백엔드로 전환하기로 결정한 경우 애플리케이션의 민감한 데이터가 노출될 수 있으므로 유의해야 한다. + +### SQL 스토리지 백엔드 + +SQL 데이터베이스에 릴리스 정보를 저장하는 ***베타*** SQL +스토리지 백엔드가 있다. + +이러한 스토리지 백엔드는 릴리스 정보의 무게가 1MB를 초과하는 경우에 사용하면 +특히 유용하다. (이 경우 쿠버네티스의 기본 etcd 키-값 저장소의 +내부 제한으로 인해 컨피그맵/시크릿에 저장할 수 없다.) + +SQL 백엔드를 활성화하려면 SQL 데이터베이스를 배포하고 환경변수 +`HELM_DRIVER` 에서 `sql` 로 설정해야 한다. DB 세부 정보는 +환경변수 `HELM_DRIVER_SQL_CONNECTION_STRING` 으로 설정된다. + +다음과 같이 셸에서 설정할 수 있다. + +```shell +export HELM_DRIVER=sql +export HELM_DRIVER_SQL_CONNECTION_STRING=postgresql://helm-postgres:5432/helm?user=helm&password=changeme +``` + +> 참고: 현재 PostgreSQL 만 지원된다. + +**운영 참고사항**: 다음을 권장한다. +- 운영 데이터베이스를 준비하자. PostgreSQL에 대한 자세한 내용은 [서버 관리](https://www.postgresql.org/docs/12/admin.html) 문서를 참조하자. +- 릴리스 정보를 위해 쿠버네티스 RBAC를 미러링하도록 [권한 관리](/docs/permissions_sql_storage_backend/)를 +활성화하자. + +기본 백엔드에서 SQL 백엔드로 전환하려면 +직접 마이그레이션을 수행해야 한다. 다음 +명령어를 통해 릴리스 정보를 검색할 수 있다. + +```shell +kubectl get secret --all-namespaces -l "owner=helm" +``` diff --git a/content/ko/docs/topics/architecture.md b/content/ko/docs/topics/architecture.md new file mode 100644 index 0000000000..aca4d08b6f --- /dev/null +++ b/content/ko/docs/topics/architecture.md @@ -0,0 +1,61 @@ +--- +title: "헬름 아키텍처" +description: "헬름 아키텍처를 개괄적으로 설명한다." +weight: 8 +--- + +# 쿠버네티스 헬름 아키텍처 + +이 문서에서는 헬름 아키텍처를 개괄적으로 설명한다. + +## 헬름의 목적 + +헬름은 _차트_라고 하는 쿠버네티스 패키지를 관리하는 도구이다. +헬름으로 다음과 같은 것들을 할 수 있다. + +- 스크래치(scratch)부터 새로운 차트 생성 +- 차트 아카이브(tgz) 파일로 차트 패키징 +- 차트가 저장되는 곳인 차트 리포지터리와 상호작용 +- 쿠버네티스 클러스터에 차트 인스톨 및 언인스톨 +- 헬름으로 설치된 차트들의 릴리스 주기 관리 + +헬름에는 다음과 같은 중요한 3가지 개념이 있다. + +1. _차트_는 쿠버네티스 애플리케이션의 인스턴스를 생성하는 데에 필요한 정보의 꾸러미이다. +2. _설정_은 릴리스 가능한 객체를 생성하기 위해 패키징된 차트로 병합될 수 있는 설정 정보를 가진다. +3. _릴리스_는 _차트_의 구동중 인스턴스이며, 특정 _설정_이 결합되어 있다. + +## 컴포넌트 + +헬름은 실행프로그램이며, 다음 2가지 부분으로 나누어 구현되었다. + +**헬름 클라이언트**는 엔드유저용 명령줄 클라이언트이다. +이 클라이언트는 다음과 같은 것들을 관장한다. + +- 로컬 차트 개발 +- 리포지터리 관리 +- 릴리스 관리 +- 헬름 라이브러리와 인터페이스 제공 + - 설치할 차트를 전달 + - 기존 릴리스에 대한 업그레이드 또는 언인스톨 요청 + +**헬름 라이브러리**는 모든 헬름 동작 수행에 대한 로직을 제공한다. +쿠버네티스 API 서버에 대한 인터페이스 역할을 하며 다음의 기능들을 제공한다. + +- 릴리스를 빌드하기 위해 차트와 설정 결합 +- 쿠버네티스에 차트 설치, 후속 릴리스 객체 제공 +- 쿠버네티스와 상호작용하여 업그레이드 및 언인스톨 수행 + +단독형 헬름 라이브러리에는 헬름 로직이 캡슐화되어 있어 +다른 클라이언트에서 효과적으로 활용할 수 있다. + +## 구현 + +헬름 클라이언트와 라이브러리는 Go 프로그래밍 언어로 작성되었다. + +라이브러리는 쿠버네티스와 소통하기 위해 쿠버네티스 클라이언트 라이브러리를 사용한다. +현재, 라이브러리는 REST+JSON을 사용하며, +쿠버네티스 내부에 위치한 시크릿(secret) 안에 정보를 저장한다. +따라서 별도의 데이터베이스가 필요하지 않다. + +설명 파일은 가능하면 YAML로 작성한다. diff --git a/content/ko/docs/topics/chart_repository.md b/content/ko/docs/topics/chart_repository.md new file mode 100644 index 0000000000..bac8cbb91e --- /dev/null +++ b/content/ko/docs/topics/chart_repository.md @@ -0,0 +1,309 @@ +--- +title: "차트 저장소 가이드" +description: "헬름 차트 저장소를 만들고 작업하는 방법" +weight: 6 +--- + +이 섹션에서는 Helm 차트 저장소를 만들고 작업하는 방법을 설명한다. +고수준에서 차트 저장소는 패키지형 차트를 저장하고 +공유할 수 있는 장소다. + +공식 차트 저장소는 [쿠버네티스 차트](https://github.com/helm/charts)가 +관리하고 있으며 참여를 환영한다. 하지만 헬름도 자신만의 차트 저장소를 +쉽게 만들고 운영할 수 있게 해준다. 이 가이드에서는 +그렇게 하는 방법을 설명한다. + +## 전제 조건 + +* [빠른 시작]({{< ref path="quickstart.md" lang="en" >}}) 가이드 살펴보기 +* [차트]({{< ref path="/docs/topics/charts.md" lang="en" >}}) 문서 읽기 + +## 차트 저장소 생성 + +_차트 저장소_ 는 `index.yaml` 파일과 패키지화된 차트를 +저장하는 HTTP 서버다. 차트를 공유할 준비가 되면 +차트 저장소에 업로드하는 것이 가장 선호되는 방법이다. + +**참고:** Helm 2.0.0의 경우 차트 저장소는 고유한 인증 방법이 없다. +GitHub에 [이슈 트래킹 +프로세스](https://github.com/helm/helm/issues/1038)가 있다. + +차트 저장소는 YAML과 tar 파일을 서비스할 수 있고 +GET 요청에 응답할 수 있는 모든 HTTP 서버가 될 수 있기 때문에, +자신만의 차트 저장소를 호스팅하는 것에 관한 한 수많은 옵션이 있다. +예를 들어 GCS(구글 클라우드 스토리지) 버킷, Amazon S3 버킷, GitHub Pages를 +사용하거나 직접 웹 서버를 만들 수도 있다. + +### 차트 저장소 구조 + +차트 저장소는 패키지형 차트와 저장소에 있는 모든 차트의 인덱스를 가진 `index.yaml` 이라는 +특수 파일로 구성된다. 종종 `index.yaml` 에 기술된 차트도 +[출처 파일]({{< ref path="provenance.md" lang="en" >}})처럼 동일한 서버에서 +호스팅된다. + +예를 들어, 저장소 `https://example.com/charts` 의 레이아웃은 +다음과 같을 수 있다: + +``` +charts/ + | + |- index.yaml + | + |- alpine-0.1.2.tgz + | + |- alpine-0.1.2.tgz.prov +``` + +이 경우에는 인덱스 파일에 하나의 차트, 즉 알파인 차트에 대한 정보가 포함되며, +해당 차트에 대한 다운로드 URL +`https://example.com/charts/alpine-0.1.2.tgz` 을 제공한다. + +차트 패키지가 `index.yaml` 파일과 동일한 서버에 위치할 필요는 없다. +하지만 그렇게 하는 것이 종종 가장 쉽다. + +### 인덱스 파일 + +인덱스 파일은 `index.yaml` 이라는 yaml 파일이다. 차트의 +`Chart.yaml` 파일의 내용을 포함하여 패키지에 대한 메타데이터가 +포함되어 있다. 적합한 차트 저장소는 인덱스 파일이 있어야 한다. +인덱스 파일에는 차트 저장소의 각 차트에 대한 정보가 들어 있다. +`helm repo index` 명령은 패키지형 차트를 포함하는 지정된 +로컬 디렉토리를 기반으로 인덱스 파일을 생성한다. + +인덱스 파일의 예: + +```yaml +apiVersion: v1 +entries: + alpine: + - created: 2016-10-06T16:23:20.499814565-06:00 + description: Deploy a basic Alpine Linux pod + digest: 99c76e403d752c84ead610644d4b1c2f2b453a74b921f422b9dcb8a7c8b559cd + home: https://helm.sh/helm + name: alpine + sources: + - https://github.com/helm/helm + urls: + - https://technosophos.github.io/tscharts/alpine-0.2.0.tgz + version: 0.2.0 + - created: 2016-10-06T16:23:20.499543808-06:00 + description: Deploy a basic Alpine Linux pod + digest: 515c58e5f79d8b2913a10cb400ebb6fa9c77fe813287afbacf1a0b897cd78727 + home: https://helm.sh/helm + name: alpine + sources: + - https://github.com/helm/helm + urls: + - https://technosophos.github.io/tscharts/alpine-0.1.0.tgz + version: 0.1.0 + nginx: + - created: 2016-10-06T16:23:20.499543808-06:00 + description: Create a basic nginx HTTP server + digest: aaff4545f79d8b2913a10cb400ebb6fa9c77fe813287afbacf1a0b897cdffffff + home: https://helm.sh/helm + name: nginx + sources: + - https://github.com/helm/charts + urls: + - https://technosophos.github.io/tscharts/nginx-1.1.0.tgz + version: 1.1.0 +generated: 2016-10-06T16:23:20.499029981-06:00 +``` + +## 차트 저장소 호스팅 + +이 절은 차트 저장소를 서비스하는 몇 가지 방법을 보여준다. + +### 구글 클라우드 스토리지 + +첫 번째 단계는 **GCS 버킷 만들기**다. `fantastic-charts` 라고 부를 것이다. + +![GCS 버킷 생성](https://helm.sh/img/create-a-bucket.png) + +다음으로, **버킷 권한을 수정**하여 버킷을 공개하자. + +![권한 수정](https://helm.sh/img/edit-permissions.png) + +**버킷을 공개하기 위해** 다음 줄을 넣자. + +![버킷 공개](https://helm.sh/img/make-bucket-public.png) + +축하한다, 이제 차트를 서비스할 빈 GCS 버킷이 준비되었다! + +구글 클라우드 스토리지 명령줄 도구 또는 GCS 웹 UI를 사용하여 차트 +저장소를 업로드하자. 이것은 공식 쿠버네티스 차트 저장소가 +차트를 호스팅하는 기술이기 때문에, 만약 막히면 당신은 [그 프로젝트를 +간단히 보는 것](https://github.com/helm/charts)이 좋을 것이다. + +**참고:** 공용 GCS 버킷은 `https://bucket-name.storage.googleapis.com/` 에서 간단한 +HTTPS를 통해 접근할 수 있다. + +### JFrog 아티팩토리 + +JFrog 아티팩토리를 사용하여 차트 저장소를 만들 수도 있다. JFrog 아티팩토리가 있는 +차트 저장소에 대한 자세한 내용은 +[여기](https://www.jfrog.com/confluence/display/RTF/Helm+Chart+Repositories)를 참조하자. + +### 깃헙 페이지 예제 + +비슷한 방법으로 깃헙 페이지를 사용하여 차트 저장소를 만들 수 있다. + +깃헙은 두 가지 방법으로 정적 웹 페이지를 서비스할 수 있도록 한다. + +- `docs/` 디렉토리의 내용을 서비스하도록 프로젝트를 설정 +- 특정 브랜치를 서비스하도록 프로젝트를 설정 + +첫 번째 방법이 쉽지만 두 번째 방법을 택하겠다. + +첫 번째 단계는 **gh-pages 분기를 만드는** 것이다. 로컬에서 만들 수 있다. + +```console +$ git checkout -b gh-pages +``` + +깃헙 저장소의 **Branch** 버튼을 눌러 웹 브라우저를 통해 만들 수도 있다. + +![깃헙 페이지 브랜치 생성](https://helm.sh/img/create-a-gh-page-button.png) + +그런 다음 **gh-pages 브랜치**가 깃헙 페이지로 설정되어 있는지 +확인하고 저장소의 **Settings**를 클릭한 다음 **깃헙 페이지** 섹션으로 +스크롤하여 아래와 같이 설정하자. + +![깃헙 페이지 브랜치 생성](https://helm.sh/img/set-a-gh-page.png) + +기본적으로 **Source**는 **gh-pages 브랜치**로 설정된다. 기본적으로 설정되어 있지 +않으면 선택하자. + +원한다면 거기서 **사용자 지정 도메인(Custom domain)** 을 사용할 수 있다. + +그리고 차트를 서비스할 때 HTTPS가 사용되도록 **HTTPS 강제(Enforce HTTPS)** 가 선택되어 +있는지 확인하자. + +이러한 설정에서 **master 브랜치**를 사용하여 차트 코드를 저장하고 +**gh-pages 브랜치**를 차트 저장소로 저장할 수 있다 +(예: `https://USERNAME.github.io/REPONAME`). 데모 [TS 차트](https://github.com/technosophos/tscharts) +저장소는 `https://technosophos.github.io/tscharts/` 에서 +접근할 수 있다. + +### 일반 웹 서버 + +헬름 차트를 서비스하도록 일반 웹 서버를 설정하려면 +다음 작업만 수행하면 된다. + +- 서버가 서비스할 수 있는 디렉토리에 인덱스 및 차트 저장 +- 인증 요구 사항 없이 `index.yaml` 파일에 접근할 수 + 있는지 확인 +- `yaml` 파일이 올바른 내용 유형(`text/yaml` 또는 `text/x-yaml`)과 함께 서비스되는지 + 확인. + +예를 들어, `$WEBROOT/charts` 에서 차트를 서비스하려면 +웹 루트 `charts/` 디렉토리가 있는지 확인하고 인덱스 파일과 +차트를 해당 폴더 안에 넣자. + +### 차트뮤지엄 저장소 서버 + +차트뮤지엄은 Go 언어로 작성된 오픈소스 헬름 차트 저장소 서버로, +[구글 클라우드 스토리지](https://cloud.google.com/storage/), [아마존 +S3](https://aws.amazon.com/s3/), [마이크로소프트 애저 블롭 +스토리지](https://azure.microsoft.com/en-us/services/storage/blobs/), [알리바바 +클라우드 OSS 스토리지](https://www.alibabacloud.com/product/oss), [오픈스택 오브젝트 +스토리지](https://developer.openstack.org/api-ref/object-store/), [오라클 클라우드 +인프라 오브젝트 스토리지](https://cloud.oracle.com/storage), [바이두 클라우드 +BOS 스토리지](https://cloud.baidu.com/product/bos.html), [텐센트 클라우드 오브젝트 +스토리지](https://intl.cloud.tencent.com/product/cos), [디지털오션 +스페이스](https://www.digitalocean.com/products/spaces/), +[미니오](https://min.io/), [etcd](https://etcd.io/)를 포함한 클라우드 스토리지 +백엔드를 지원한다. + +[차트뮤지엄](https://chartmuseum.com/docs/#using-with-local-filesystem-storage) +서버를 사용하여 로컬 파일 시스템에서 +차트 저장소를 호스팅할 수 있다. + +## 차트 저장소 관리 + +차트 저장소가 생겼으니 이 가이드의 마지막 부분에서는 해당 저장소에서 차트를 +유지하는 방법을 설명한다. + + +### 차트 저장소에 차트 저장 + +차트 저장소가 생겼으니 차트와 인덱스 파일을 저장소에 +업로드해 보자. 차트 저장소의 차트는 +올바르게 패키징하고(`helm package chart-name/`) 버전([SemVer 2](https://semver.org/) +가이드라인에 따라)이 제공되어야 한다. + +다음 단계는 예제 워크플로우를 구성하지만 차트 +저장소에 차트를 저장하고 갱신하는 데 원하는 +워크플로우를 모두 사용하자. + +패키지형 차트가 준비되면 새 디렉토리를 만들고 +패키지형 차트를 해당 디렉토리로 이동시키자. + +```console +$ helm package docs/examples/alpine/ +$ mkdir fantastic-charts +$ mv alpine-0.1.0.tgz fantastic-charts/ +$ helm repo index fantastic-charts --url https://fantastic-charts.storage.googleapis.com +``` + +마지막 명령은 방금 생성한 로컬 디렉토리의 경로와 +원격 차트 저장소의 URL을 사용하여 지정된 디렉토리 +경로 내에 `index.yaml` 파일을 구성한다. + + +이제 동기화 도구를 사용하거나 수동으로 차트 저장소에 +차트 및 인덱스 파일을 업로드할 수 있다. 구글 클라우드 스토리지를 +사용하는 경우 gsutil 클라이언트를 사용하여 이 [예제 워크플로우]({{< ref path="/docs/howto/chart_repository_sync_example.md" lang="en" >}})를 +확인하자. 깃헙의 경우 해당 목적지 브랜치에 차트를 간단히 넣을 수 있다. + +### 기존 저장소에 새로운 차트 추가 + +저장소에 새로운 차트를 추가할 때마다 인덱스를 재생성해야 한다. +`helm repo index` 명령은 로컬에서 찾은 차트만 포함하여 +`index.yaml` 파일을 처음부터 완전히 재구성한다. + +그러나 `--merge` 플래그를 사용하여 새 차트를 기존 `index.yaml` 파일(GCS와 같은 +원격 저장소로 작업할 때 유용한 옵션)에 점진적으로 추가할 수 있다. 자세히 알아보기 +위해 `helm repo index --help`를 실행하자. + +수정된 `index.yaml` 파일과 차트를 모두 업로드하자. 그리고 출처 파일을 생성했다면 +그것도 업로드하자. + +### 다른 사람과 차트 공유 + +차트를 공유할 준비가 되면 다른 사람에게 +저장소의 URL을 알려주자. + +그들은 저장소를 조회하기 위해 사용하고자 하는 +이름과 `helm repo add [이름] [URL]` 명령을 통해 +저장소를 헬름 클라이언트에 추가할 것이다. + +```console +$ helm repo add fantastic-charts https://fantastic-charts.storage.googleapis.com +$ helm repo list +fantastic-charts https://fantastic-charts.storage.googleapis.com +``` + +차트가 HTTP 기본 인증을 지원할 경우 사용자 이름과 암호를 대야 할 수 있다: + +```console +$ helm repo add fantastic-charts https://fantastic-charts.storage.googleapis.com --username my-username --password my-password +$ helm repo list +fantastic-charts https://fantastic-charts.storage.googleapis.com +``` + +**참고:** 저장소에 유효한 `index.yaml`이 포함되어 있지 않으면 저장소가 추가되지 않는다. + +**참고:** 헬름 저장소가 자체 서명된 인증서를 사용하는 경우 +CA 검증을 건너뛰기 위해서 +`helm repo add --insecure-skip-tls-verify ...` 을 사용할 +수 있다. + +그 후에 사용자들은 당신의 차트를 검색할 수 있을 것이다. +당신이 저장소를 업데이트한 후에는 사용자들이 `helm repo update` 명령을 +사용하여 최신 차트 정보를 가져올 수 있다. + +*내부에서 `helm repo add` 및 `helm repo update` 명령은 +index.yaml 파일을 가져와 `$XDG_CACHE/helm/repository/cache/` 디렉토리에 +저장하고 있다. 여기는 `helm search` 기능이 +차트에 대한 정보를 찾는 곳이다.* diff --git a/content/ko/docs/topics/chart_tests.md b/content/ko/docs/topics/chart_tests.md new file mode 100644 index 0000000000..f960eb5499 --- /dev/null +++ b/content/ko/docs/topics/chart_tests.md @@ -0,0 +1,142 @@ +--- +title: "차트 테스트" +description: "차트를 실행하고 테스트 하는 방법을 설명한다." + +weight: 3 +--- + +차트에는 함께 작동하는 여러 쿠버네티스 리소스 및 구성요소가 포함되어 +있다. 차트 작성자는 차트가 설치될 때 예상대로 작동하는지 확인하는 몇 가지 +테스트를 작성할 수 있다. 이러한 테스트는 차트 사용자가 차트에 따라 수행될 +작업을 이해하는 데에도 도움이 된다. + +헬름 차트의 **테스트** 는 `template/` 디렉토리에 있으며 실행하기 위해 +주어진 명령어로 컨테이너를 지정하는 작업 정의이다. 테스트가 성공한 것으로 +판정되려면 컨테이너가 성공적으로 종료되어야 한다(exit 0). 작업 정의에는 +헬름 테스트 훅 어노테이션(`helm.sh/hook: test`)이 반드시 포함되어야 한다. + +헬름 v3 까지는, 작업 정의에 `helm.sh/hook: test-success` 또는 `helm.sh/hook: test-failure` 와 +같은 헬름 테스트 훅 어노테이션 중 하나가 포함되어야 했다. +`helm.sh/hook: test-success` 는 여전히 `helm.sh/hook: test` 과 +하위 호환되는 대안으로 허용된다. + +예제 테스트: + +- values.yaml 파일의 구성이 제대로 삽입되었는지 + 확인 + - 사용자 이름과 비밀번호가 올바르게 작동하는지 확인 + - 잘못된 사용자 이름과 비밀번호가 작동하지는 않는지 확인 +- 서비스가 작동하고 올바르게 로드 밸런싱 되는지 확인 +- 기타 + +helm test 명령어를 사용하여 헬름에서 릴리스에 대한 사전 +정의된 테스트를 실행할 수 있다. 이렇게 하면 차트 사용자가 차트(또는 애플리케이션)의 릴리스가 +기대한대로 작동하는지 확인할 수 있다. + +## 예제 테스트 + +다음은 [비트나미(bitnami) 워드프레스 차트](https://hub.helm.sh/charts/bitnami/wordpress)에 +있는 헬름 테스트 파드의 정의에 대한 예이다. 차트 사본을 다운로드하면 +파일을 로컬에서 확인할 수 있다. + +```console +$ helm repo add bitnami https://charts.bitnami.com/bitnami +$ helm pull bitnami/wordpress --untar +``` + +``` +wordpress/ + Chart.yaml + README.md + values.yaml + charts/ + templates/ + templates/tests/test-mariadb-connection.yaml +``` + +`wordpress/templates/tests/test-mariadb-connection.yaml` 에서, +해 볼 수 있는 테스트를 확인할 수 있다. + +```yaml +{{- if .Values.mariadb.enabled }} +apiVersion: v1 +kind: Pod +metadata: + name: "{{ .Release.Name }}-credentials-test" + annotations: + "helm.sh/hook": test +spec: + containers: + - name: {{ .Release.Name }}-credentials-test + image: {{ template "wordpress.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy | quote }} + {{- if .Values.securityContext.enabled }} + securityContext: + runAsUser: {{ .Values.securityContext.runAsUser }} + {{- end }} + env: + - name: MARIADB_HOST + value: {{ template "mariadb.fullname" . }} + - name: MARIADB_PORT + value: "3306" + - name: WORDPRESS_DATABASE_NAME + value: {{ default "" .Values.mariadb.db.name | quote }} + - name: WORDPRESS_DATABASE_USER + value: {{ default "" .Values.mariadb.db.user | quote }} + - name: WORDPRESS_DATABASE_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "mariadb.fullname" . }} + key: mariadb-password + command: + - /bin/bash + - -ec + - | + mysql --host=$MARIADB_HOST --port=$MARIADB_PORT --user=$WORDPRESS_DATABASE_USER --password=$WORDPRESS_DATABASE_PASSWORD + restartPolicy: Never +{{- end }} +``` + +## 릴리스에서 테스트 스위트를 실행하는 단계 + +먼저 클러스터에 차트를 설치하여 릴리스를 만든다. 모든 파드가 +활성화될 때까지 기다려야 할 수도 있다. 설치 직후 바로 테스트하는 경우, +일시적인 오류가 발생할 수도 있고, 다시 테스트해야 할 수도 있다. + +```console +$ helm install quirky-walrus wordpress --namespace default +$ helm test quirky-walrus +Pod quirky-walrus-credentials-test pending +Pod quirky-walrus-credentials-test pending +Pod quirky-walrus-credentials-test pending +Pod quirky-walrus-credentials-test succeeded +Pod quirky-walrus-mariadb-test-dqas5 pending +Pod quirky-walrus-mariadb-test-dqas5 pending +Pod quirky-walrus-mariadb-test-dqas5 pending +Pod quirky-walrus-mariadb-test-dqas5 pending +Pod quirky-walrus-mariadb-test-dqas5 succeeded +NAME: quirky-walrus +LAST DEPLOYED: Mon Jun 22 17:24:31 2020 +NAMESPACE: default +STATUS: deployed +REVISION: 1 +TEST SUITE: quirky-walrus-mariadb-test-dqas5 +Last Started: Mon Jun 22 17:27:19 2020 +Last Completed: Mon Jun 22 17:27:21 2020 +Phase: Succeeded +TEST SUITE: quirky-walrus-credentials-test +Last Started: Mon Jun 22 17:27:17 2020 +Last Completed: Mon Jun 22 17:27:19 2020 +Phase: Succeeded +[...] +``` + +## 참고 + +- 테스트를 정의할 때는 단일 yaml 파일에 하거나 또는 `template/` 디렉토리의 여러 + yaml 파일에 분산하여 할 수도 있다. +- 따로 분리하기 위해 `<차트-이름>/templates/tests/` 와 같은 `tests/` 디렉토리 아래에 + 테스트 스위트를 넣어둘 수도 있다. +- 테스트는 [헬름 훅](/docs/charts_hooks/) 이므로, + `helm.sh/hook-weight` 나 `helm.sh/hook-delete-policy` 와 같은 어노테이션을 테스트 + 리소스와 함께 사용할 수 있다. diff --git a/content/ko/docs/topics/charts.md b/content/ko/docs/topics/charts.md new file mode 100644 index 0000000000..1dbc5c02e6 --- /dev/null +++ b/content/ko/docs/topics/charts.md @@ -0,0 +1,1099 @@ +--- +title: "차트" +description: "차트 형식을 설명하고, 헬름으로 차트를 빌드하기 위한 기본지침을 제공한다." +weight: 1 +--- + +헬름은 *charts* 라는 패키지 포맷을 사용한다. 차트는 쿠버네티스 리소스와 +관련된 셋을 설명하는 파일의 모음이다. 하나의 차트는 memcached 파드를 +배포하는 것처럼 단순한 형태나 HTTP 서버, 데이터베이스, 캐시 등으로 +구성된 완전한 웹앱 같이 복잡한 형태로 사용될수 있다. + +차트는 특정한 디렉터리 구조를 가진 파일들로 생성된다. 이 파일들은 +배포할 버전이 지정된 아카이브로 패키지화 될 수 있다. + +설치하지 않고 공개된 차트를 다운로드 받거나 보기 위해, +`helm pull chartrepo/chartname` 명령을 사용할 수 있다. + +이 문서는 차트 형식을 설명하고, 차트를 헬름으로 구성하는 +기본 가이드를 제공한다. + +## 차트 파일 구조 + +차트는 디렉터리 안에 파일들의 모음으로 구성된다. 디렉터리명은 +(버전 정보 없는) 차트명이다. 따라서, +WordPress 를 설명하는 차트는 `wordpress/` 디렉터리에 저장된다. + +디렉터리 안에서 헬름은 다음과 같은 구조를 가진다. + +```text +wordpress/ + Chart.yaml # 차트에 대한 정보를 가진 YAML 파일 + LICENSE # 옵션: 차트의 라이센스 정보를 가진 텍스트 파일 + README.md # 옵션: README 파일 + values.yaml # 차트에 대한 기본 환경설정 값들 + values.schema.json # 옵션: values.yaml 파일의 구조를 제약하는 JSON 파일 + charts/ # 이 차트에 종속된 차트들을 포함하는 디렉터리 + crds/ # 커스텀 자원에 대한 정의 + templates/ # values와 결합될 때, 유효한 쿠버네티스 manifest 파일들이 생성될 템플릿들의 디렉터리 + templates/NOTES.txt # 옵션: 간단한 사용법을 포함하는 텍스트 파일 +``` + +헬름은 `charts/`, `crds/`, `templates/` 디렉터리와 나열된 파일명의 사용을 +예약한다. 다른 파일들은 그대로 남는다. + +## Chart.yaml 파일 + +`Chart.yaml` 파일은 차트의 필수 요소이다. 다음과 같은 필드를 포함한다. + +```yaml +apiVersion: 차트 API 버전 (필수) +name: 차트명 (필수) +version: SemVer 2 버전 (필수) +kubeVersion: 호환되는 쿠버네티스 버전의 SemVer 범위 (선택) +description: 이 프로젝트에 대한 간략한 설명 (선택) +type: 차트 타입 (선택) +keywords: + - 이 프로젝트에 대한 키워드 리스트 (선택) +home: 프로젝트 홈페이지의 URL (선택) +sources: + - 이 프로젝트의 소스코드 URL 리스트 (선택) +dependencies: # 차트 필요조건들의 리스트 (optional) + - name: 차트명 (nginx) + version: 차트의 버전 ("1.2.3") + repository: 저장소 URL ("https://example.com/charts") 또는 ("@repo-name") + condition: (선택) 차트들의 활성/비활성을 결정하는 boolean 값을 만드는 yaml 경로 (예시: subchart1.enabled) + tags: # (선택) + - 활성화 / 비활성을 함께하기 위해 차트들을 그룹화 할 수 있는 태그들 + enabled: (선택) 차트가 로드될수 있는지 결정하는 boolean + import-values: # (선택) + - ImportValues 는 가져올 상위 키에 대한 소스 값의 맵핑을 보유한다. 각 항목은 문자열이거나 하위 / 상위 하위 목록 항목 쌍일 수 있다. + alias: (선택) 차트에 대한 별명으로 사용된다. 같은 차트를 여러번 추가해야할때 유용하다. +maintainers: # (선택) + - name: maintainer들의 이름 (각 maintainer마다 필수) + email: maintainer들의 email (각 maintainer마다 선택) + url: maintainer에 대한 URL (각 maintainer마다 선택) +icon: 아이콘으로 사용될 SVG나 PNG 이미지 URL (선택) +appVersion: 이 앱의 버전 (선택). SemVer인 필요는 없다. +deprecated: 차트의 deprecated 여부 (선택, boolean) +annotations: + example: 키로 매핑된 주석들의 리스트 (선택). +``` + +다른 필드 내용은 생략한다. + +### 차트와 버저닝 + +모든 차트는 버전 번호를 가져야한다. 버전은 [SemVer2](https://semver.org/spec/v2.0.0.html) +표준을 따라야 한다. 이전 헬름과 다르게, +헬름 v2 이상은 버전 번호를 release 마커로 사용한다. +저장소에 있는 패키지들은 이름과 버전으로 구분된다. + +예를 들어, 버전 필드가 `version: 1.2.3` 으로 설정된 `nginx` 차트는 +다음같이 이름이 지어진다. + +```text +nginx-1.2.3.tgz +``` + +`version:1.2.3-alpha.1+ef365` 같은 더 복잡한 SemVer 2 +이름도 지원된다. SemVer가 아닌 이름은 시스템에 의해 +명백하게 허용되지 않는다. + +**참고:** 헬름 클래식과 배포 매니저는 둘다 깃허브를 +지향한 차트였지만, 헬름 v2와 이후 버전은 깃허브나 깃에 +의존하지도, 필요로 하지도 않는다. 따라서 깃 SHA 값의 버전관리에서는 모두 +사용하지 않는다. + +`Chart.yaml` 의 안에 있는 `version` 필드는 CLI를 포함한 +많은 헬름 툴에서 사용된다. 패키지를 생성할 때, +`helm package` 명령은 `Chart.yaml` 에서 찾은 버전을 +패키지 이름에 있는 토큰으로 사용한다. 시스템은 차트 +패키지명 안의 버전 번호가 `Chart.yaml` 안의 버전 번호와 +일치한다고 가정한다. 이 가정을 충족하지 못하면 에러가 발생한다. + +### `apiVersion` 필드 + +`apiVersion` 필드는 최소 헬름 3을 필요로 하는 헬름 차트에 +대해 `v2` 여야 한다. 이전 헬름 버전을 지원하는 차트는 +`apiVersion` 이 `v1` 으로 설정되어 있고, 헬름 3에 의해 여전히 설치 가능하다. + +`v1` 에서 `v2` 로 변경하기: + +- 종속성을 정의하는 `dependencies`필드는 `v1` 차트를 위한 + 독립된 `requirements.yaml` 파일에 위치([Chart + Dependencies](#차트-의존성) 보기). +- `type`필드는 어플리케이션과 라이브러리 차트를 + 식별([ChartTypes](#차트-타입) 보기) + +### `appVersion` 필드 + +`appVersion` 필드는 `version` 필드와 관련이 없음을 주의하라. 이 필드는 +어플리케이션의 버전을 명시하는 방법이다. 예를 들어, `drupal` 차트가 +`appVersion: 8.2.1` 을 가진다면, 차트에 (기본값으로) 포함되는 Drupal의 +버전은 `8.2.1`임을 나타낸다. 이 필드는 정보만 제공하고, +차트 버전 계산에 영향이 없다. 버전을 따옴표로 감싸는 것을 매우 +권장한다. 이것은 YAML 파서가 버전 번호를 string으로 다루게 한다. 따옴표 없이 +남기면 몇몇의 경우에 파싱 문제가 생길 수 있다. 예를 들어, YAML은 `1.0` 을 +소숫점으로, `1234e10` 같은 깃 커밋 SHA를 과학적 기수법으로 해석한다. + +현재 헬름 v3.5.0에서, `helm create`는 기본값으로 `appVersion` 필드를 따옴표로 감싼다. + +### `kubeVersion` 필드 + +선택 필드인 `kubeVersion` 은 지원되는 쿠버네티스 버전에 대한 +semver 제약 조건을 정의할 수 있다. 헬름은 차트를 설치할 때 버전 제약을 판단하고, +클러스터가 지원되지 않는 쿠버네티스 버전을 구동하면 실패한다. + +버전 제약은 공백으로 분리된 AND 비교로 다음과 같이 구성된다. +``` +>= 1.13.0 < 1.15.0 +``` +다음 예제와 같이 표현 각각은 OR `||` 연산과 +결합될 수 있다. +``` +>= 1.13.0 < 1.14.0 || >= 1.14.1 < 1.15.0 +``` +이 예제에서 버전 `1.14.0` 은 제외되어, 특정 버전의 버그가 +차트를 제대로 실행하지 못하게 하는 것으로 이해할 수 있다. + +버전 제약에 사용하는 `=` `!=` `>` `<` `>=` `<=` 연산 외에도, +다음 약칭 표기법이 지원된다. + + * 닫힌 간격에 대한 하이픈 범위, `1.1 - 2.3.4` 는 `>=1.1 <= 2.3.4` 와 + 동일하다. + * 와일드카드 `x`, `X` ,`*`, 예를 들어 `1.2.x` 는 `>= 1.2.0 < 1.3.0` 와 + 동일하다. + * 물결 범위 (패치 버전 변화는 허용), `~1.2.3`는 `>= 1.2.3 < 1.3.0` 와 + 동일하다. + * 탈자 범위 (마이너 버전 변화는 허용), `^1.2.3` 는`>= 1.2.3 < 2.0.0` 와 + 동일하다. + +지원되는 유의적 버전 제약의 상세한 표현은 +[Masterminds/semver](https://github.com/Masterminds/semver)에서 확인한다. + +### 미사용 예정 차트 + +차트 저장소에서 차트를 관리할 때, 가끔 차트를 미사용 예정으로 표시하는 것이 +필요하다. `Chart.yaml` 에 있는 선택 필드인 `deprecated` 는 차트가 미사용 +예정임을 표시하는데 사용될 수 있다. 저장소에 있는 차트의 **최신** 버전이 +미사용 예정으로 표시 된다면, 차트는 전체가 미사용 예정이라고 판단한다. +미사용 예정을 체크하지 않은 새로운 버전을 발행함으로써 차트명을 +이후에 재사용 할 수 있다. 차트를 미사용 하는 것에 대한 +[kubernetes/charts](https://github.com/helm/charts) 프로젝트를 따르는 작업흐름은 다음과 같다. + +1. 차트의 `Chart.yaml` 를 업데이트 하여 차트를 미사용 예정으로 표시하여 + 버전을 올린다. +2. 차트 저장소에 새로운 차트 버전을 발행한다. +3. 차트를 소스 저장소에서 삭제한다 (예. git) + +### 차트 타입 + +`type` 필드는 차트의 타입을 정의한다. `application`, `library` 의 +두가지 타입이 있다. Application은 기본 타입이며 +온전하게 작동할 수 있는 표준 차트이다. +[library chart]({{< ref "/docs/topics/library_charts.md" >}}) 는 차트 빌더에 +유틸리티나 함수를 제공한다. library chart는 설치가 불가능하고, 보통 +어떤 리소스 오브젝트도 갖지 않는다는 점에서 application chart와는 다르다. + +**참고:** application chart는 library chart로 사용될 수 있다. 타입을 +`library` 로 설정하여 활성화 한다. 차트는 모든 유틸리티와 +함수 기능을 활용할 수 있는 상태의 library chart로 렌더링된다. 차트의 +모든 리소스 오브젝트는 렌더링되지 않는다. + +## 차트 라이센스, README 와 NOTES + +차트는 설치, 구성, 사용법, 라이센스를 +설명하는 파일을 가질 수 있다. + +LICENSE는 차트에 대한 [license](https://en.wikipedia.org/wiki/Software_license) 를 +포함하는 일반 텍스트 파일이다. 차트는 템플릿 안에서 프로그래밍 로직을 +가지는 것으로써의 라이센스를 포함할 수 있으므로 환경 설정 +전용이 아니다. 필요한 경우, 차트에 의해 설치된 어플리케이션을 위해 +별도의 라이센스로 나눠질 수 있다. + +차트에 대한 README는 마크다운(README.md)의 포맷이어야 하며, +일반적으로 다음을 포함한다. + +- 차트가 제공하는 어플리케이션이나 서비스에 관한 설명 +- 차트를 실행하기 위한 전제조건이나 필요조건 +- `values.yaml` 에 있는 옵션과 기본값에 대한 설명 +- 차트의 설치나 환경설정에 관련이 있을 수 + 있는 다른 정보 + +허브 및 기타 사용자 인터페이스가 `README.md` 파일의 콘텐츠에서 +가져온 차트에 대한 세부 정보를 표시하는 경우 + +차트는 릴리즈의 상태를 보여줄때와 설치 후에 출력될 짧은 일반 텍스트를 +`template/NOTES.txt` 파일에 적을 수 있다. 이 파일은 +[template](#템플릿과-값)으로 평가되고 사용법 메모, 다음 스텝, 차트의 +릴리즈와 관련된 다른 정보를 표시하기 위해 사용될 수 있다. 예를 들어, +지시 사항(instructions)은 데이터베이스에 연결하기, 웹 UI에 액세스하기 +등에 대해 제공될 수 있다. 이 파일이 `helm install` 이나 `helm status` 가 +실행될 때 STDOUT으로 출력되기 때문에, 내용을 간단하게 유지하고, +상세 내용은 README를 참조하도록 하는 것을 권장한다. + +## 차트 의존성 + +헬름에서 하나의 차트는 0개 이상의 다른 차트에 의존한다. +이 의존성은 `Chart.yaml` 에 `dependencies` 필드를 사용하여 직접 연결되거나 +`charts/` 디렉터리로 가져와서 수동으로 관리할 수 있다. + +### `dependencies` 필드를 통해 의존성 관리하기 + +현재 차트가 필요로 하는 차트들은 `dependencies` 필드에 +리스트로 정의된다. + +```yaml +dependencies: + - name: apache + version: 1.2.3 + repository: https://example.com/charts + - name: mysql + version: 3.2.1 + repository: https://another.example.com/charts +``` + +- `name` 필드는 사용할 차트명이다. +- `version` 필드는 사용할 차트의 버전이다. +- `repository` 필드는 차트 저장소의 완전한 URL 이다. 반드시 로컬 환경에서 + `helm repo add` 를 사용해야 함을 주의하라. +- URL 대신 저장소의 이름을 사용할 수 있다. + +```console +$ helm repo add fantastic-charts https://fantastic-charts.storage.googleapis.com +``` + +```yaml +dependencies: + - name: awesomeness + version: 1.0.0 + repository: "@fantastic-charts" +``` + +일단 종속성을 정의하면, `helm dependency update` 를 실행할 수 있고, +실행하면 종속성 파일을 사용해서 모든 명시된 +차트를 `charts/` 디렉터리 안에 다운로드 받는다. + +```console +$ helm dep up foochart +Hang tight while we grab the latest from your chart repositories... +...Successfully got an update from the "local" chart repository +...Successfully got an update from the "stable" chart repository +...Successfully got an update from the "example" chart repository +...Successfully got an update from the "another" chart repository +Update Complete. Happy Helming! +Saving 2 charts +Downloading apache from repo https://example.com/charts +Downloading mysql from repo https://another.example.com/charts +``` + +`helm dependency update` 가 차트를 가져올 때, +차트 아카이브의 형태로 `charts/` 디렉터리에 저장한다. +위의 예제 같은 경우, 다음 파일들을 차트 디렉터리에서 볼수 있다. + +```text +charts/ + apache-1.2.3.tgz + mysql-3.2.1.tgz +``` + +#### 의존성 안에서의 대체 필드 + +위에서 본 필드 외에도, 각각의 필요 엔트리는 +선택적 필드인 `alias` 를 가질 수 있다. + +종속성 차트에 대한 별명(alias)을 추가하여, dependencies 안에 +새로운 종속성 이름을 별명으로 사용하여 넣게 된다. + +다른 이름으로 차트에 엑세스 해야 하는 경우 +`alias` 를 사용할 수 있다. + +```yaml +# parentchart/Chart.yaml + +dependencies: + - name: subchart + repository: http://localhost:10191 + version: 0.1.0 + alias: new-subchart-1 + - name: subchart + repository: http://localhost:10191 + version: 0.1.0 + alias: new-subchart-2 + - name: subchart + repository: http://localhost:10191 + version: 0.1.0 +``` + +위의 예에서 `parentchart` 에 대해 모두 3개의 종속성을 얻게 된다. + +```text +subchart +new-subchart-1 +new-subchart-2 +``` + +같은 동작을 수동으로 하는 방법은 `charts/` 디렉터리에 같은 차트를 여러번 다른 이름으로 +복사/붙여넣기 하면된다. + +#### 의존성 안에서의 태그와 조건 필드 + +위에서 본 필드 외에도, 각각의 필요 엔트리는 선택필드인 +`tags` 와 `condition` 을 가질 수 있다. + +모든 차트는 기본으로 로드된다. `tags` 나 `condition` 필드가 +존재하면, 차트가 적용될지에 대한 로딩 제어를 위해 +사용되고 평가된다. + +Condition - condition 필드는 1개 이상의 (콤마로 구분되는) +YAML 경로이다. 최상단 부모의 values에 이 경로가 존재하고 +boolean 값으로 판단할수 있다면, 차트는 boolean 값에 의해 +활성화 혹은 비활성화 된다. 리스트에서 발견된 유효한 첫번째 경로만이 평가되고, +이 경로가 존재하지 않으면 해당 condition은 무효하다. + +Tags - tags 필드는 이 차트와 관련된 레이블의 YAML 리스트이다. +최상단 부모의 values에서, 태그를 가진 모든 차트는 +특정한 태그와 boolean 값에 의해 활성화 또는 비활성화 된다. + +```yaml +# parentchart/Chart.yaml + +dependencies: + - name: subchart1 + repository: http://localhost:10191 + version: 0.1.0 + condition: subchart1.enabled, global.subchart1.enabled + tags: + - front-end + - subchart1 + - name: subchart2 + repository: http://localhost:10191 + version: 0.1.0 + condition: subchart2.enabled,global.subchart2.enabled + tags: + - back-end + - subchart2 +``` + +```yaml +# parentchart/values.yaml + +subchart1: + enabled: true +tags: + front-end: false + back-end: true +``` + +위 예에서 `front-end` 태그를 가진 모든 차트는 비활성화 되지만, 부모의 values에서 +`subchart1.enabled` 가 true로 평가되었기 때문에, condition은 `front-end` 태그를 +덮어쓰고 `subchart1` 은 활성화된다. + +`subchart2` 는 `back-end` 와 태그되었고 이 태그는 `true` 로 평가되어서, +`subchart2` 는 활성화된다. 또한 `subchart2` 가 특정한 +condition을 가지지만, 부모의 values에 대응되는 경로가 없어서, +이 condition은 아무 영향이 없다. + +##### 태그 및 조건과 함께 CLI 사용 + +`--set` 파라미터는 보통 tag와 condition 값을 수정할때 사용할 수 있다. + +```console +helm install --set tags.front-end=true --set subchart2.enabled=false +``` + +##### 태그 및 조건 확인 + +- **(values에 셋팅된) Condition은 항상 tag를 덮어쓴다.** 존재하는 첫번째 condition 경로가 사용되고 그 차트의 다른 것들은 무시된다. +- tag는 '어떤 차트의 tag라도 true면 차트를 활성화 시킬것' 으로 평가한다. +- tag와 condition 값은 최상단 부모의 values에 셋팅되어야 한다. +- values의 `tags:` 키는 최상단 레벨의 키여야 한다. 전역과 중첩된 `tags:` 테이블은 현재 지원되지 않는다. + +#### 의존성을 통해 자식 값 가져오기 + +몇몇 케이스에서 자식 차트의 values가 부모의 차트에 영향을 미치고 +공통 기본값으로 공유되도록 하고싶을 수 있다. `exports` 포맷을 +사용하는 것의 추가 이점은 향후 도구를 통해 사용자가 설정할수 있는 값을 +가능하게 하는 것이다. + +import 될 값을 포함하는 키는 YAML 리스트를 사용해서 부모 차트의 `dependencies` 안에 +`import-values` 필드로 명시할 수 있다. 리스트의 각 아이템은 +자식 차트의 `exports` 필드로부터 import 되는 키이다. + +`exports` 키 안에 포함되지 않은 import value를 +사용하려면, [child-parent](#자식-부모-형식-사용하기) 포맷을 사용하라. 두 포맷 모두 +아래에서 설명한다. + +##### 내보내기 형식 사용하기 + +자식의 `values.yaml` 파일이 루트에 `exports` 필드를 가진다면, +이 필드의 내용은 다음 예제처럼 import 하기 위한 키를 명시함으로써 +부모의 values에 직접 import 될수 있다. + +```yaml +# parent's Chart.yaml file + +dependencies: + - name: subchart + repository: http://localhost:10191 + version: 0.1.0 + import-values: + - data +``` + +```yaml +# child's values.yaml file + +exports: + data: + myint: 99 +``` + +import 리스트에 `data` 키를 명시했기 때문에, 헬름은 `data` 키에 대한 +자식 차트의 `exports` 필드를 찾고 그것의 내용을 import 한다. + +최종 부모의 values는 export된 필드를 포함한다. + +```yaml +# parent's values + +myint: 99 +``` + +부모의 `data` 키가 부모의 최종 values에 포함되지 않음을 주의하라. +부모의 키에 명시할 필요가 있다면, 'child-parent' 포맷을 사용하라. + +##### 자식-부모 형식 사용하기 + +자식 차트의 values의 `exports` 키에 포함되지 않은 +values에 접근하려면, import될 (자식) values의 +키와 부모 차트의 values (부모)안의 목적지 경로를 +명시해야 한다. + +아래의 예제에 있는 `import-values` 는 `child` 경로에서 발견된어떤 값이든 취하고, +값들을 `parent:` 에 명시된 경로에 부모의 값들로 복사하라고 +헬름에게 지시한다. + +```yaml +# parent's Chart.yaml file + +dependencies: + - name: subchart1 + repository: http://localhost:10191 + version: 0.1.0 + ... + import-values: + - child: default.data + parent: myimports +``` + +위의 예제에서, subchart1의 값들 안에 `default.data` 에서 발견된 +values는 다음과 같이 부모 차트의 values 안의 +`myimports` 키로 import 된다. + +```yaml +# parent's values.yaml file + +myimports: + myint: 0 + mybool: false + mystring: "helm rocks!" +``` + +```yaml +# subchart1's values.yaml file + +default: + data: + myint: 999 + mybool: true +``` + +부모 차트의 values 결과는 다음과 같다. + +```yaml +# parent's final values + +myimports: + myint: 999 + mybool: true + mystring: "helm rocks!" +``` + +부모의 최종 values는 이제 subchart1에서 import된 +`myint` 와 `mybool` 필드를 가진다. + +### `charts/` 디렉터리를 통해 수동으로 의존성 관리 + +더 많은 종속성 제어가 필요하다면, +이 종속성들은 dependency 차트를 `charts/` 디렉터리로 +복사함으로써 정확하게 표현될 수 있다. + +종속성은 차트 아카이브(`foo-1.2.3.tgz`)나 비압축 차트 디렉터리가 +될수 있다. 이름은 `_`나 `.`로 시작될 수 없다. 이런 파일은 +차트 로더가 무시한다. + +예를 들어서, WordPress 차트가 Apache 차트에 의존한다면, +(올바른 버전의) Apache 차트는 WordPress 차트의 +`charts/` 디렉터리 안에 저장된다. + +```yaml +wordpress: + Chart.yaml + # ... + charts/ + apache/ + Chart.yaml + # ... + mysql/ + Chart.yaml + # ... +``` + +위의 예제는 어떻게 WordPress 차트가 Apache와 MySLQ에 대한 의존성을 +표현하는지 `charts/` 디렉터리에 이 차트들을 포함시킴으로써 보여준다. + +**팁:** _`charts/` 디렉터리 안에 종속성을 가져오려면, +`helm pull` 명령을 사용하라._ + +### 의존성 사용의 운영적 관점 + +위 섹션은 차트 종속성을 어떻게 명시하는지 설명하지만, `helm install` 과 +`helm upgrade` 를 사용하는 차트 설치에 어떻게 영향을 미치는가? + +"A"라는 차트가 다음과 같은 쿠버네티스 오브젝트를 생성한다고 가정하자. + +- namespace "A-Namespace" +- statefulset "A-StatefulSet" +- service "A-Service" + +A가 오브젝트를 생성하는 B 차트에 의존성을 가진다고 하자. + +- namespace "B-Namespace" +- replicaset "B-ReplicaSet" +- service "B-Service" + +차트 A의 installation / upgrade 후에, 단일 헬름 릴리즈가 생성 / 수정 된다. +릴리즈는 다음 순서로 위의 쿠버네티스 오브젝트를 전부를 +생성 / 업데이트한다. + +- A-Namespace +- B-Namespace +- A-Service +- B-Service +- B-ReplicaSet +- A-StatefulSet + +왜냐하면 헬름이 차트를 설치/업그레이드 할때, +차트와 모든 종속성으로부터 쿠버네티스 오브젝트가 + +- 단일 집합으로 통합된다. +- 이름에 따른 타입으로 정렬된다. +- 그 순서에 의해 생성/업데이트 된다. + +이런 이유로 단일 릴리즈는 차트와 종속성에 대한 모든 +오브젝트와 함께 생성된다. + +쿠버네티스 타입의 설치 순서는 +kind_sorter.go([the Helm source file](https://github.com/helm/helm/blob/484d43913f97292648c867b56768775a55e4bba6/pkg/releaseutil/kind_sorter.go))의 열거형 타입 설치 순서에 의해 +제공된다. + +## 템플릿과 값 + +헬름 차트 템플릿은 [sprig 라이브러리](https://github.com/Masterminds/sprig)에서 +50개 정도의 애드온 템플릿 함수와 +몇가지 기타 [특수 함수]({{< ref "/docs/howto/charts_tips_and_tricks.md" >}})가 +추가된 [Go template language](https://golang.org/pkg/text/template/)로 +작성되었다. + +모든 템플릿 파일은 차트의 `templates` 디렉터리 안에 저장된다. +헬름이 차트를 렌더링할때, 템플릿 엔진을 통해 이 디렉터리 안에 +모든 파일을 전달한다. + +템플릿에 대한 values는 2가지 방법으로 제공된다. + +- 차트 개발자는 차트의 안에 `values.yaml` 이라 부르는 파일을 제공할 수 있다. 이 파일은 기본 값을 포함할 수 있다. +- 차트 사용자는 값을 포함한 YAML파일을 제공할 수 있다. `helm install` 커맨드 라인으로 제공받을 수 있다. + +사용자가 커스텀 값을 제공할 때, 차트의 `values.yaml` 파일에 +있는 값을 덮어쓴다. + +### 템플릿 파일 + +템플릿 파일은 Go 템플릿 작성에 대한 표준 규약을 따른다 +([텍스트/템플릿 Go 패키지 문서](https://golang.org/pkg/text/template/)). +예제 템플릿 파일은 +다음과 같을 수 있다. + +```yaml +apiVersion: v1 +kind: ReplicationController +metadata: + name: deis-database + namespace: deis + labels: + app.kubernetes.io/managed-by: deis +spec: + replicas: 1 + selector: + app.kubernetes.io/name: deis-database + template: + metadata: + labels: + app.kubernetes.io/name: deis-database + spec: + serviceAccount: deis-database + containers: + - name: deis-database + image: {{ .Values.imageRegistry }}/postgres:{{ .Values.dockerTag }} + imagePullPolicy: {{ .Values.pullPolicy }} + ports: + - containerPort: 5432 + env: + - name: DATABASE_STORAGE + value: {{ default "minio" .Values.storage }} +``` + +([https://github.com/deis/charts](https://github.com/deis/charts)에 느슨하게 결합된) 위의 예는 +쿠버네티스 리플리케이션 컨트롤러에 대한 템플릿이다. +다음 4가지 템플릿 값을 사용할 수 있다. +(보통 `values.yaml` 에 정의된다.) + +- `imageRegistry`: 도커 이미지의 소스 레지스트리 +- `dockerTag`: 도커 이미지의 태그 +- `pullPolicy`: 쿠버네티스의 pull 정책 +- `storage`: 기본값이 `"minio"`로 설정되는 저장소 백엔드 + +이 모든 값은 템플릿 작성자에 의해 정의된다. 헬름은 +파라미터를 요구하거나 지시하지 않는다. + +많은 작동중인 차트를 보려면, [쿠버네티스 차트 프로젝트](https://github.com/helm/charts)를 +참고하라. + +### 미리 정의된 값 + +`values.yaml` 파일 (혹은 `--set` 플래그)로 제공되는 값은 템플릿 안에서 +`.Values` 객체로 접근 가능하다. 그러나 템플릿 안에서 접근 가능한 +다른 미리 정의된 데이터의 조각이 있다. + +다음 값은 미리 정의되었고, 모든 템플릿에서 접근 가능하며, 덮어쓸수 없다. 모든 값과 +마찬가지로, 이름은 대소문자를 구별한다. + +- `Release.Name`: 릴리즈의 이름(차트의 이름 아님) +- `Release.Namespace`: 차트가 릴리즈된 네임스페이스 +- `Release.Service`: 릴리즈를 수행하는 서비스 +- `Release.IsUpgrade`: 현재 업그레이드나 롤백중이면 true로 설정된다. +- `Release.IsInstall`: 현재 설치중이면 true로 설정된다. +- `Chart`: `Chart.yaml`의 내용. 차트의 버전은 `Chart.Version`으로, 메인테이너는 `Chart.Maintainers`로 얻을 수 있다. +- `Files`: 차트에 모든 특별하지 않은 파일을 포함하는 맵과 같은 오브젝트이다. 템플릿에 접근을 제공하지는 않지만, (`.helmignore`로 배제되지 않았다면) 존재하는 추가 파일에 대한 엑세스를 제공한다. 파일은 `{{ index .Files "file.name" }}`나 `{{.Files.Get name }}`함수를 사용해서 접근할 수 있다. +- `Capabilities`: 쿠버네티스의 버전(`{{ .Capabilities.KubeVersion }}`)과 지원되는 쿠버네티스 API 버전 (`{{ .Capabilities.APIVersions.Has "batch/v1" }}`)에 대한 정보를 포함하는 맵과 같은 오브젝트 + +**주의:** 익명의 `Chart.yaml` 필드는 무시된다. 이 필드는 +`Chart` 오브젝트의 안에서 접근이 불가능하다. 따라서 +`Chart.yaml` 은 템플릿으로 구조화된 데이터를 제멋대로 +전달하기 위해 사용될 수 없다. + +### 값 파일 + +이전 섹션에서의 템플릿을 고려할때, 필수적인 값을 제공하는 +`values.yaml` 은 다음과 같다. + +```yaml +imageRegistry: "quay.io/deis" +dockerTag: "latest" +pullPolicy: "Always" +storage: "s3" +``` + +values 파일은 YAML 포맷이다. 차트는 기본 `values.yaml` +파일을 포함한다. 헬름 설치 명령은 추가 YAML 값을 제공함으로써 +사용자가 값을 덮어쓸 수 있게한다. + +```console +$ helm install --generate-name --values=myvals.yaml wordpress +``` + +이 방법으로 값이 전달될때, 디폴트 values 파일로 이 값들은 병합된다. +예를 들어, `myvals.yaml` 파일은 다음과 같다고 하자. + +```yaml +storage: "gcs" +``` + +차트의 `values.yaml` 로 병합될때, 생성된 내용의 결과는 +다음과 같다. + +```yaml +imageRegistry: "quay.io/deis" +dockerTag: "latest" +pullPolicy: "Always" +storage: "gcs" +``` + +오직 마지막 필드가 덮여쓰여짐을 주의하라. + +**참고:** 차트의 안에 포함된 디폴트 값 파일은 `values.yaml` 의 이름을 가져야한다. 반면에, +커맨드 라인에 명시하는 파일은 아무 이름이나 가질 수 있다. + +**참고:** `--set` 플래그가 `helm install` 이나 `helm upgrade` 에 사용된다면, +이 값들은 클라이언트에서 YAML로 간단하게 변환된다. + +**참고:** values 파일에 필수적인 엔트리가 있다면, 차트 템플릿에서 +['required' 함수]({{< ref "/docs/howto/charts_tips_and_tricks.md" >}})를 사용함으로써 필수로 정의될 수 있다. + +값중 어떤 것이라도 템플릿의 안에서 `.Values` 오브젝트를 사용하여 +접근이 가능하다. + +```yaml +apiVersion: v1 +kind: ReplicationController +metadata: + name: deis-database + namespace: deis + labels: + app.kubernetes.io/managed-by: deis +spec: + replicas: 1 + selector: + app.kubernetes.io/name: deis-database + template: + metadata: + labels: + app.kubernetes.io/name: deis-database + spec: + serviceAccount: deis-database + containers: + - name: deis-database + image: {{ .Values.imageRegistry }}/postgres:{{ .Values.dockerTag }} + imagePullPolicy: {{ .Values.pullPolicy }} + ports: + - containerPort: 5432 + env: + - name: DATABASE_STORAGE + value: {{ default "minio" .Values.storage }} +``` + +### 범위, 의존성, 값 + +values 파일은 최상위 차트에 대한 값과 차트의 `charts/` 디렉터리에 +포함된 차트중 어떤 것이라도 정의할 수 있다. 또는, 다르게 표현하면, +values 파일은 차트와 그것의 종속성 모두에게 값을 제공할 수 있다. +예를 들어 위의 데모 WordPress 차트는 `mysql` 과 `apaches` +모두를 종속성으로 가진다. values 파일은 이 요소들의 모두를 +값으로 제공할 수 있다. + +```yaml +title: "My WordPress Site" # Sent to the WordPress template + +mysql: + max_connections: 100 # Sent to MySQL + password: "secret" + +apache: + port: 8080 # Passed to Apache +``` + +더 높은 레벨의 차트는 더 아래 레벨에서 정의된 변수에 대해 엑세스할 수 있다. +그러므로 WordPress 차트는 `.Values.mysql.password` 로 MySQL +패스워드에 접근할 수 있다. 더 낮은 레벨의 차트는 부모차트에 엑세스가 불가능하므로, +MySQL은 `title` 속성에 접근할 수 없다. 이 문제로 `apache.port` 에도 +접근할 수 없다. + +값은 네임스페이스가 지정되지만, 네임스페이스는 정리된다. WordPress 차트에서는 +MySQL 패스워드 필드를 `.Values.mysql.password` 로 접근 가능하다. 그러나 +MySQL 차트에서는 값의 범위가 축소되고 네임스페이스 접두사가 삭제되므로, +`.Values.password` 로 간단히 패스워드 필드를 볼수 있다. + +#### 전역 값 + +2.0.0-Alpha.2 현재로, 헬름은 특별한 "전역" 값을 제공한다. +이전 예제의 수정된 버전을 보자. + +```yaml +title: "My WordPress Site" # Sent to the WordPress template + +global: + app: MyWordPress + +mysql: + max_connections: 100 # Sent to MySQL + password: "secret" + +apache: + port: 8080 # Passed to Apache +``` + +위에서 값 `app: MyWordPress` 도 함께 `global` 섹션에 추가했다. +이 값은 `.Values.global.app` 으로 모든 차트에서 이용 가능하다. + +예를 들어, `mysql` 템플릿은 `app` 을 `{{.Values.global.app}}` 로 +접근할 수 있고, `apache` 에서도 마찬가지 이다. 사실상, 위의 values 파일은 +다음과 같이 다시 만들어진다. + +```yaml +title: "My WordPress Site" # Sent to the WordPress template + +global: + app: MyWordPress + +mysql: + global: + app: MyWordPress + max_connections: 100 # Sent to MySQL + password: "secret" + +apache: + global: + app: MyWordPress + port: 8080 # Passed to Apache +``` + +전역값은 하나의 최상위 레벨 변수를 모든 서브 차트와 공유하는 방법을 제공하고, +label 같은 `metadata` 속성을 셋팅하는 것 같은 일에서 유용하다. + +서브 차트가 전역 변수를 선언하면, (서브차트의 서브차트에게) _하향_으로 전달되지만, +부모의 차트로 _상향_되지는 않는다. 서브차트가 부모 차트의 값에 +영향을 주는 방법은 없다. + +또한 부모 차트의 전역 변수는 서브 차트의 +전역 변수보다 우선한다. + +### 스키마 파일 + +가끔, 차트 메인테이너는 값에 구조를 정의하고 싶을 수 있다. +`values.schema.json` 파일에 스키마를 정의함으로써 가능하다. +스키마는 [JSON 스키마](https://json-schema.org/)로 표현된다. +이 스키마는 다음과 같이 보인다. + +```json +{ + "$schema": "https://json-schema.org/draft-07/schema#", + "properties": { + "image": { + "description": "Container Image", + "properties": { + "repo": { + "type": "string" + }, + "tag": { + "type": "string" + } + }, + "type": "object" + }, + "name": { + "description": "Service name", + "type": "string" + }, + "port": { + "description": "Port", + "minimum": 0, + "type": "integer" + }, + "protocol": { + "type": "string" + } + }, + "required": [ + "protocol", + "port" + ], + "title": "Values", + "type": "object" +} +``` + +이 스키마는 유효성 검사를 위해 값에 적용된다. +유효성 검사는 다음 명령중 하나가 일어날때 발생한다. + +- `helm install` +- `helm upgrade` +- `helm lint` +- `helm template` + +이 스키마의 필요조건을 만족한 `values.yaml` 파일의 예는 +다음과 같다. + +```yaml +name: frontend +protocol: https +port: 443 +``` + +스키마가 최종 `.Values` 오브젝트에 적용되고, `values.yaml` 파일에만 +적용되지 않는 다는 것을 주의하라. 즉, 다음과 같이 적절한 +`--set` 옵션과 함께 차트가 설치되면, +다음 `yaml` 파일은 유효하다. + +```yaml +name: frontend +protocol: https +``` + +```console +helm install --set port=443 +``` + +게다가, 최종 `.Values` 오브젝트는 _모든_ 서브차트 스키마에서 체크된다. +즉, 부모차트에 의해 서브차트의 제한은 우회될수 없다. +이 또한 반대 방향으로 작동한다. 서브차트가 서브차트의 +`values.yaml` 파일에서 만족하지 못한 필요조건을 가진다면, +부모 차트는 이 조건을 만족 시켜야만한다. + +### 참고 자료 + +템플릿, values, 스키마 파일등을 작성하려면 다음 표준 참고자료가 +도움이 될 것이다. + +- [Go templates](https://godoc.org/text/template) +- [Extra template functions](https://godoc.org/github.com/Masterminds/sprig) +- [The YAML format](https://yaml.org/spec/) +- [JSON Schema](https://json-schema.org/) + +## 사용자 지정 리소스정의 (CRDs) + +쿠버네티스는 쿠버네티스 오브젝트의 새로운 타입을 정의하는 것에 대한 메커니즘을 제공한다. +사용자 지정 리소스 정의(CRDs, Custom Resource Definitions)를 사용해서, +쿠버네티스 개발자는 커스텀 리소스 타입을 정의할 수 있다. + +헬름 3에서, CRDs는 특별한 객체 종류로 다뤄진다. CRDs는 차트의 나머지보다 +먼저 설치되고, 몇몇 제한이 적용된다. + +CRD YAML 파일은 차트안의 `crds/` 디렉터리에 위치해야한다. +(YAML 시작과 끝 마커로 분리된) 다수의 CRDs는 같은 파일에 +위치할수 있다. 헬름은 CRD 디렉터리의 _모든_ 파일을 쿠버네티스로 +로드하려고 시도한다. + +CRD 파일은 _템플릿화 될수 없다_. 순수 YAML 문서여야 한다. +헬름이 새로운 차트를 설치할때, CRDs를 업로드 하고, API 서버에 +의해 이용가능해지도록 CRD가 만들때까지 정지되며, 템플릿 엔진이 +시작하고, 나머지 차트를 렌더링 하고, 쿠버네티스로 업로드한다. +순서때문에, CRD 정보는 헬름 템플릿의 `Capabilities` 오브젝트에서 +이용 가능하고, 헬름 템플릿은 CRDs에서 정의된 오브젝트의 새로운 +인스턴스를 만들 수 있다. + +예를 들어, 차트가 `crds/` 디렉터리에 `CronTab` 에 대한 CRD를 가진다면, `templates/` +디렉터리 안에 `CronTab` 종류의 인스턴스를 생성할 수 있다. + +```text +crontabs/ + Chart.yaml + crds/ + crontab.yaml + templates/ + mycrontab.yaml +``` + +`crontab.yaml` 파일은 반드시 템플릿 명령 없이 CRD를 포함해야한다. + +```yaml +kind: CustomResourceDefinition +metadata: + name: crontabs.stable.example.com +spec: + group: stable.example.com + versions: + - name: v1 + served: true + storage: true + scope: Namespaced + names: + plural: crontabs + singular: crontab + kind: CronTab +``` + +그러면 템플릿 `mycrontab.yaml` 은 (보통 템플릿을 사용하여) 새로운 +`CronTab` 을 생성할 수 있다. + +```yaml +apiVersion: stable.example.com +kind: CronTab +metadata: + name: {{ .Values.name }} +spec: + # ... +``` + +헬름은 `templates/` 안에 것들을 설치하기 전에 `CronTab` kind가 +설치되어 있고, 쿠버네티스 API 서버에서 이용 가능한지 +확인한다. + +### CRD 에서의 제약사항 + +대부분의 쿠버네티스에서의 오브젝트와 다르게, CRDs는 전역으로 설치된다. +이 이유로, 헬름은 CRDs를 관리하는 것에 매우 조심스럽게 접근한다. +CRDs는 다음 제약이 적용된다. + +- CRDs는 절대 재설치 불가능하다. 헬름이 (버전에 상관 없이) `crds/` 디렉터리에 CRDs가 존재한다는 것을 알아낸다면, 헬름은 설치나 업그레이드 시도를 하지 않는다. +- CRDs는 절대 업그레이드나 롤백이 불가능하다. 헬름은 오직 설치 작업시에만 CRDs를 생성한다. +- CRDs는 절대 삭제될수 없다. CRD를 자동으로 지우는 것은 모든 클러스터 안의 네임스페이스에 영향을 주는 CRD's 내용의 모든것을 삭제한다. 따라서, 헬름은 CRDs를 삭제하지 않는다. + +CRDs를 업그레이드나 삭제하고 싶으면 몹시 조심하여 수동으로 +수행하라. + +## 헬름을 사용하여 차트 관리하기 + +`helm` 도구에는 차트 작업을 위한 몇몇 명령이 있다. + +다음은 새로운 차트를 생성한다. + +```console +$ helm create mychart +Created mychart/ +``` + +일단 차트를 수정하면, `helm` 은 차트아카이브로 +패키징할 수 있다. + +```console +$ helm package mychart +Archived mychart-0.1.-.tgz +``` + +차트의 포맷이나 정보 이슈를 찾는 것에 `helm` 을 +사용할 수 있다. + +```console +$ helm lint mychart +No issues found +``` + +## 차트 저장소 + +차트 저장소는 한 개 이상의 패키징된 차트를 저장할 공간을 제공하는 HTTP 서버이다. +`helm` 은 로컬 차트 디렉터리를 관리하는데 사용되는 반면, 차트를 공유하려면 우선되는 +메커니즘은 차트 저장소이다. + +YAML 파일과 tar 파일을 제공하고 GET 요청에 응답할 수 있는 어떤 HTTP서버든 +저장소 서버로 사용될 수 있다. 헬름 팀은 웹 사이트 모드 활성화로 +구글 클라우드 스토리지(Google Cloud Storage) 및 S3를 포함해서 +몇몇 서버를 테스트했다. + +주로 저장소에 의해 제공되는 패키지의 모든 리스트를 가진 특별한 +`index.yaml` 파일의존재와 검색 및 패키지 검증을 허용하는 +메타데이터로 저장소를 특정한다. + +클라이언트 측면에서, 저장소는 `helm repo` 명령으로 관리된다. +그러나, 헬름은 원격 저장소 서버에 차트를 업로드하는 것에 대한 도구를 제공하지 않는다. +그렇게 하는 것이 서버를 구현하기 위해 상당한 요구사항을 추가하고, +저장소를 셋팅하는 것에 대한 장벽을 만들어내기 때문이다. + +## 차트 사용 팩 + +`helm create` 명령은 "starter chart" 임을 명시할수 있게 하는 +선택적 `--starter` 옵션을 취한다. + +스타터는 그냥 일반적인 차트지만, +`$XDG_DATA_HOME/helm/starters` 에 위치한다. 차트 개발자는 +스타터로 사용하도록 특별히 디자인된 차트를 작성할 수 있다. 이런 차트는 +다음 고려사항을 생각하고 디자인 되어야 한다. + +- `Chart.yaml`은 제너레이터에 의해 덮어쓰여진다. +- 사용자는 이 차트의 내용을 수정하기 원하므로, 문서는 어떻게 사용자가 그럴 수 있는지 알려줘야한다. +- 모든 ``의 존재는 스타터 차트가 템플릿으로 사용되기 위해 특정 차트 이름으로 수정된다. + +현재 `$XDG_DATA_HOME/helm/starters` 에 차트를 추가하기 위한 +유일한 방법은 수동으로 복사해서 넣는 것이다. +차트의 문서에서, 그 과정을 설명할 수 있다. diff --git a/content/ko/docs/topics/charts_hooks.md b/content/ko/docs/topics/charts_hooks.md new file mode 100644 index 0000000000..fe9ad8622e --- /dev/null +++ b/content/ko/docs/topics/charts_hooks.md @@ -0,0 +1,205 @@ +--- +title: "차트 훅(hooks)" +description: "차트 훅을 이용하여 작업하는 방법을 설명한다." +weight: 2 +--- + +헬름은 차트 개발자가 릴리스 수명주기의 특정 지점에 개입할 수 있도록 _hook_ 매커니즘을 제공한다. +예를 들어 다음과 같은 것들을 하기 위해 훅을 사용할 수 있다. + +- 설치 시 다른 차트가 로드되기 전에 컨피그맵이나 시크릿을 로드한다. +- 새 차트를 설치하기 전에 데이터베이스를 백업하는 작업을 실행하고, + 데이터 복원을 위해 업그레이드 후 2번째 작업을 수행한다. +- 릴리스를 제거하기 전에 서비스를 순환에서 안전하게 제거하기 위하여, + 릴리스 삭제 전에 작업을 수행한다. + +훅은 일반적인 템플릿처럼 작동하지만 헬름이 다른 방식으로 +처리하도록 하는 특수한 어노테이션이 있다. +이 섹션에서는 훅의 기본 사용 패턴을 다룬다. + +## 사용 가능한 훅 + +훅은 다음과 같이 정의되어 있다. + +| 어노테이션 값 | 설명 | +| ---------------- | ----------------------------------------------------------------------------------------------------- | +| `pre-install` | 템플릿은 렌더링되었지만, 쿠버네티스에서 아직 아무 리소스도 생성되기 전에 실행된다. | | +| `post-install` | 쿠버네티스에 모든 리소스가 로드된 후에 실행된다. | +| `pre-delete` | 삭제 요청 중에서, 쿠버네티스에서 리소스가 삭제되기 전에 실행된다. | +| `post-delete` | 삭제 요청 중에서, 릴리스의 모든 리소스가 삭제된 후 실행된다. | +| `pre-upgrade` | 업그레이드 요청 중에서, 템플릿은 렌더링되었지만 리소스는 업데이트되기 전에 실행된다. | +| `post-upgrade` | 업그레이드 요청 중에서, 모든 리소스가 업그레이드된 후 실행된다. | +| `pre-rollback` | 롤백 요청 중에서, 템플릿은 렌더링되었지만 아직 아무 리소스도 롤백되지 않은 시점에 실행된다. | +| `post-rollback` | 롤백 요청 중에서, 모든 리소스가 수정된 후에 실행된다. | +| `test` | 헬름 test 하위 명령어가 호출될 때 실행된다. ([테스트 문서 보기](/docs/chart_tests/)) | + +_헬름 3에서는 `crd-install` 훅은 제거되었고 대신 `crds/` 디렉터리를 +사용한다는 점을 잊지 말자._ + +## 훅과 릴리스 수명주기 + +훅을 사용하면 차트 개발자는 릴리스 수명주기 상의 중요 시점에서 +작업이 수행되도록 할 수 있다. 예를 들어 `helm install` 의 수명주기를 +생각해보자. 기본적으로 수명주기는 다음과 같다. + +1. 사용자가 `helm install foo` 를 실행한다. +2. 헬름 라이브러리 설치 API가 호출된다. +3. 검증 후, 라이브러리는 `foo` 템플릿을 렌더링한다. +4. 라이브러리는 결과로 나온 리소스를 쿠버네티스에 로드한다. +5. 라이브러리는 릴리스 객체(및 다른 데이터)를 클라이언트에 반환한다. +6. 클라이언트가 종료된다. + +헬름은 `install` 수명주기에 대해 `pre-install` 및 `post-install` +의 두 가지 훅을 정의한다. `foo` 차트의 개발자가 두 훅을 모두 구현하면 수명주기는 +다음과 같이 바뀐다. + +1. 사용자가 `helm install foo` 를 실행한다. +2. 헬름 라이브러리 설치 API가 호출된다. +3. `crds/` 디렉터리의 CRD가 설치된다. +4. 검증 후 라이브러리는 `foo` 템플릿을 렌더링한다. +5. 라이브러리는 `pre-install` 훅 실행을 준비한다. (쿠버네티스에 + 훅 리소스 로딩) +6. 라이브러리는 가중치(기본값으로는 0을 할당), 리소스 종류, + 이름을 기준으로 훅을 오름차순으로 정렬한다. +7. 라이브러리는 가장 낮은 가중치의 훅을 먼저 로드한다.(음수에서 + 양수로) +8. 라이브러리는 훅이 "Ready" 될 때까지 대기한다(CRD 제외). +9. 라이브러리는 결과로 나온 리소스를 쿠버네티스에 로드한다. + `--wait` 플래그가 설정된 경우 라이브러리는 모든 리소스가 "Ready" 상태가 될 때까지 대기하고, + 준비가 될 때까지 `post-install` 훅을 실행하지 않는다. +10. 라이브러리는 `post-install` 훅을 실행한다. (훅 리소스 로딩) +11. 라이브러리는 훅이 "Ready" 될 때까지 기다린다. +12. 라이브러리는 릴리스 객체(및 다른 데이터)를 클라이언트에 반환한다. +13. 클라이언트가 종료된다. + +훅이 준비될 때까지 기다린다는 것은 무엇을 의미하는가? 이것은 +훅에 선언된 리소스에 따라 다르다. 리소스가 `Job` 또는 `Pod` 종류인 경우 +헬름은 성공적으로 실행 완료될 때까지 기다린다. 훅이 실패하면 릴리스는 실패하게 된다. +이것은 _블로킹(blocking) 작업_이므로 작업이 실행되는 +동안 헬름 클라이언트는 일시정지될 것이다. + +다른 모든 종류의 경우, 쿠버네티스가 리소스를 로드(추가 또는 업데이트)하였다고 +표시하는 즉시, 리소스는 "Ready" 로 간주된다. +훅에 많은 리소스가 선언되면 리소스들은 연속적으로 실행된다. +훅 가중치(아래 참조)가 있으면, 가중치 순서대로 실행된다. +헬름 3.2.0 부터 같은 가중치를 가진 훅 리소스들은 훅이 없는 일반 리소스와 +같은 순서로 설치된다. 그밖의 경우에는 순서가 보장되지 않는다. (헬름 2.3.0 +이상에서는 알파벳순으로 정렬된다. 그러나 이 동작은 바인딩으로 간주되지 않으며 +향후 변경될 수 있다.) 여기까지가 훅 가중치 추가시 고려할 사항이며, +만약 가중치가 중요하지 않다면 `0` 으로 설정하는 것이 +좋다. + +### 해당 릴리스에 의해 관리되지 않는 훅 리소스 + +훅이 생성하는 리소스는 현재 릴리스의 일부로 추적되거나 +관리되지 않는다. 헬름은 훅이 준비 상태까지 도달했는지를 확인했다면 +훅 리소스를 그대로 남겨둔다. 향후 헬름 3에 릴리스 삭제시 +훅 리소스에 대한 가비지 수집 기능이 추가될 수 있으므로, +삭제되면 안되는 모든 훅 리소스에 `helm.sh/resource-policy: keep` 어노테이션을 +추가해야 한다. + +실질적으로, 이는 훅 리소스를 만드는 경우 `helm uninstall` 으로 +리소스를 제거할 수 없음을 의미한다. 이러한 리소스를 +삭제하려면 훅 템플릿 파일에 [사용자 지정 `helm.sh/hook-delete-policy` 어노테이션을 추가](#훅-삭제-정책)하거나 +작업(Job) 리소스의 +[time to live(TTL) 필드를 설정](https://kubernetes.io/docs/concepts/workloads/controllers/ttlafterfinished/)해야 +한다. + +## 훅 작성하기 + +훅은 `metadata` 섹션에 특별한 어노테이션이 있는 +쿠버네티스 매니페스트 파일이다. 템플릿 파일이기 때문에 +`.Values`, `.Release` 및 `.Template` 을 +읽기를 포함한 모든 일반 템플릿 기능을 사용할 수 있다. + +예를 들어 `templates/post-install-job.yaml` 에 저장된 템플릿은 +`post-install` 에서 실행할 작업을 선언한다. + +```yaml +apiVersion: batch/v1 +kind: Job +metadata: + name: "{{ .Release.Name }}" + labels: + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + annotations: + # This is what defines this resource as a hook. Without this line, the + # job is considered part of the release. + "helm.sh/hook": post-install + "helm.sh/hook-weight": "-5" + "helm.sh/hook-delete-policy": hook-succeeded +spec: + template: + metadata: + name: "{{ .Release.Name }}" + labels: + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + spec: + restartPolicy: Never + containers: + - name: post-install-job + image: "alpine:3.3" + command: ["/bin/sleep","{{ default "10" .Values.sleepyTime }}"] + +``` + +다음의 어노테이션으로 이 템플릿을 훅으로 만든다. + +```yaml +annotations: + "helm.sh/hook": post-install +``` + +하나의 리소스는 여러 개의 훅으로 구현할 수 있다. + +```yaml +annotations: + "helm.sh/hook": post-install,post-upgrade +``` + +마찬가지로, 주어진 훅을 구현하는 다양한 리소스의 수에는 +제한이 없다. 예를 들어 시크릿과 컨피그맵을 둘다 +pre-install 훅으로 선언할 수 있다. + +하위 차트에 훅이 선언되면 해당 훅도 평가된다. +최상위 차트가 하위 차트에 선언된 훅을 비활성화할 수 있는 방법은 없다. + +결정적 실행순서를 정하는데 도움이 되는 훅에 대한 가중치를 +정의할 수 있다. 가중치는 다음의 어노테이션을 사용하여 +정의한다. + +```yaml +annotations: + "helm.sh/hook-weight": "5" +``` + +훅 가중치는 양수여도 되고 음수여도 되지만 문자열로 표기해야 +한다. 헬름이 특정 종류의 훅 실행주기를 시작하면 해당 훅을 +오름차순으로 정렬한다. + +### 훅 삭제 정책 + +대상 훅 리소스를 언제 삭제할지를 결정하는 정책을 정의할 +수 있다. 훅 삭제 정책은 다음과 같은 어노테이션을 사용하여 +정의한다. + +```yaml +annotations: + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +``` + +한개 혹은 그 이상의 정의된 어노테이션 값을 선택할 수 있다. + +| 어노테이션 값 | 설명 | +| ---------------------- | -------------------------------------------------------------------- | +| `before-hook-creation` | 새 훅이 시작되기 전에 이전 리소스를 삭제한다. (기본값) | +| `hook-succeeded` | 훅이 성공적으로 실행된 후에 리소스를 삭제한다. | +| `hook-failed` | 실행 중 훅이 실패한 경우 리소스를 삭제한다. | + +훅 삭제 정책 어노테이션이 지정되지 않은 경우, 기본적으로 `before-hook-creation` 동작이 +적용된다. diff --git a/content/ko/docs/topics/kubernetes_apis.md b/content/ko/docs/topics/kubernetes_apis.md new file mode 100644 index 0000000000..f4d89914f3 --- /dev/null +++ b/content/ko/docs/topics/kubernetes_apis.md @@ -0,0 +1,163 @@ +--- +title: "사용 중단된 쿠버네티스 APIs" +description: "헬름에서 사용 중단된 쿠버네티스 API에 대해 설명한다." +--- + +쿠버네티스는 API 주도 시스템이며, 시간이 지남에 따라 +문제 공간(problem space)에 대한 이해가 깊어지면서 이를 반영하기 위해 API 도 진화한다. +이는 어떤 시스템이나 그에 따른 API에서 나타나는 일반적인 관행이다. +진화하는 API에서 중요한 것은, 적절한 지원 중단 정책과 +구현된 API의 변화를 사용자에게 알리는 프로세스이다. 다시 말해서, +API 소비자는 사전에 API 가 제거되거나 변경되는 릴리스에 대하여 알 수 있어야 한다. +그렇게 해야 소비자는 예상하지 못한 부분이나 규모가 단절적(breaking) 변화의 요소를 방지할 수 있다. + +[쿠버네티스 사용 +중단 정책](https://kubernetes.io/docs/reference/using-api/deprecation-policy/)은 +쿠버네티스가 API 버전의 변경 사항을 처리하는 방법을 담은 문서이다. +지원 중단 정책에는 지원 중단 발표 후 API +버전이 지원되는 기간이 명시되어 있다. 따라서 영향도를 최소화하려면 +지원 중단 공지를 주시하고 API 버전이 제거되는 시기를 알아두는 것이 +중요하다. + +이것은 [쿠버네티스 1.16에서 +더 이상 사용되지 않는 API +버전을 제거하기 위한](https://kubernetes.io/blog/2019/07/18/api-deprecations-in-1-16/) 발표의 예시이며 +릴리스 몇 달 전에 발표되었다. 이러한 API 버전은 +지원중단에 앞서 한번 더 안내되었다. +이는 API 버전 지원을 소비자에게 알리는 적절한 정책이 있음을 나타낸다. + +헬름 템플릿은 쿠버네티스 메니페스트 파일과 유사하게 +쿠버네티스 객체를 정의할 때 [쿠버네티스 API +그룹](https://kubernetes.io/docs/concepts/overview/kubernetes-api/#api-groups)을 지정한다. +템플릿의 `apiVersion` 필드에 지정되며 쿠버네티스 객체의 +API 버전을 식별한다. 즉, 헬름 사용자와 차트 유지관리자는 +쿠버네티스 API 버전이 언제 사용 중단(deprecated)되고 +어느 쿠버네티스 버전에서 제거되는지를 알고 있어야 한다. + +## 차트 관리자 + +차트에 있는 쿠버네티스 API 버전이 어느 쿠버네티스 버전에서 +사용중단되거나 제거되는지를 감사(audit)해야 한다. +지원 중단이 예정되어 있거나 이미 중단된 API 버전은 지원되는 버전으로 바꾸고 +출시되는 차트도 새로운 버전으로 업데이트해야 한다. API 버전은 `kind` 및 +`apiVersion` 필드로 정의된다. 예를 들어 쿠버네티스 1.16 +에서 제거된 `Deployment` 객체의 API 버전은 다음과 같다. + +```yaml +apiVersion: apps/v1beta1 +kind: Deployment +``` + +## 헬름 사용자 + +사용자는 ([차트 관리자](#차트-관리자)와 유사하게) 사용하는 +차트를 감사(audit)하고, 쿠버네티스 버전에서 API 버전이 +사용중단되거나 제거된 차트를 식별해야 한다. +식별된 차트의 경우 최신 버전의 차트(API 버전을 지원하는)가 있는지 +확인하거나 직접 차트를 업데이트해야 한다. + +또한, 배포된 모든 차트(예: 헬름 릴리스)를 감사(audit)하여 +사용중단되거나 제거된 API 버전을 다시 확인해야 한다. +`helm get manifest` 명령어를 사용하여 릴리스의 세부사항을 보면 된다. + +확인한 바에 따라, 헬름 릴리스를 지원되는 API로 업데이트하는 방법은 +다음과 같다. + +1. 지원 중단된 API 버전만을 찾는 경우, + - 지원되는 쿠버네티스 API 버전이 포함된 차트 버전으로 `helm upgrade` + 수행 + - 현재 버전 이전의 헬름 버전으로 롤백되지 않도록 + 업그레이드에 대한 설명(description) 추가 +2. 쿠버네티스 버전에서 제거된 API 버전을 찾는 + 경우, + - API 버전을 계속 사용할 수 있는 쿠버네티스 버전을 실행 중이라면(예: 쿠버네티스 1.15 에 있고, 쿠버네티스 1.16 에서 제거될 API를 사용하는 경우): + - 1 단계 절차를 수행한다. + - 그렇지 않다면(예: `helm get manifest` 에서 나온 API 버전을 + 더 이상 사용할 수 없는 쿠버네티스 버전을 사용 중인 경우): + - API 버전을 지원되는 API로 업데이트하려면 클러스터에 + 저장된 릴리스 매니페스트를 편집해야 한다. + 자세한 내용은 [릴리스 매니페스트의 api 버전 업데이트](#릴리스-매니페스트의-api-버전-업데이트)를 + 참조하자. + +> 참고: 지원되는 API로 헬름 릴리스를 업데이트하는 모든 경우에, +지원되는 API 가 있는 릴리스 버전 이전 버전으로 릴리스를 +롤백해서는 안된다. + +> 권고: 해당 API 버전이 제거되는 쿠버네티스 클러스터 업그레이드 작업 전에, +사용중단된 API 버전을 사용하는 릴리스를 +지원되는 API 버전으로 업그레이드하는 것이 모범사례이다. + +위와 같이 릴리스를 업데이트하지 않으면, API 버전이 +제거된 쿠버네티스 버전에서 릴리스를 업그레이드하려고 할 때 +다음과 유사한 오류가 발생할 수 있다. + +``` +Error: UPGRADE FAILED: current release manifest contains removed kubernetes api(s) +for this kubernetes version and it is therefore unable to build the kubernetes +objects for performing the diff. error from kubernetes: unable to recognize "": +no matches for kind "Deployment" in version "apps/v1beta1" +``` + +헬름은 업데이트/지원되는 API 버전과 함께 +전달받은 차트를 가지고, 현재 배포된 릴리스간의 +diff 패치(이 쿠버네티스 버전에서 제거된 쿠버네티스 API를 포함)를 +만드려고 하기 때문에 이 시나리오는 실패하게 된다. +실패의 근본적인 이유는, 쿠버네티스가 API 버전을 제거하면 +쿠버네티스 Go 클라이언트 라이브러리가 더 이상 지원 중단된 +객체를 파싱할 수 없기 때문에 헬름이 라이브러리를 +호출할 수 없기 때문이다. 헬름은 안타깝게도 이 상황을 +복구할 수 없으며 더 이상 이러한 릴리스는 관리할 수 없다. 이 시나리오에서 복구하는 방법에 대한 자세한 내용은 +[릴리스 매니페스트의 api 버전 업데이트](#릴리스-매니페스트의-api-버전-업데이트)를 참조하자. + +## 릴리스 매니페스트의 api 버전 업데이트 + +매니페스트는 클러스터에서 시크릿(기본값) 또는 컨피그맵의 데이터 필드에 저장되는 +헬름 릴리스 객체의 속성이다. 데이터 필드에는 base 64 로 인코딩되어 +gzip 으로 압축된 객체가 담겨 있다. (시크릿에는 추가적인 base 64 인코딩이 +적용된다.) 릴리스의 네임스페이스에는 릴리스 버전/리비전마다의 +시크릿/컨피그맵들이 있게 된다. + +사용자는 헬름 [mapkubeapis](https://github.com/helm/helm-mapkubeapis) 플러그인을 +사용하여 지원되는 API에 대한 릴리스 업데이트를 +수행할 수 있다. 자세한 내용은 readme 를 확인하자. + +또는 다음의 단계에 따라 수동으로 릴리스 매니페스트의 API 버전 +업데이트를 수행할 수 있다. 구성에 따라 시크릿 또는 컨피그맵 백엔드에 대한 +작업단계를 따라야 한다. + +- 배포된 최신 릴리스와 관련된 시크릿 또는 컨피그맵의 이름을 + 가져온다. + - 시크릿 백엔드: `kubectl get secret -l + owner=helm,status=deployed,name= --namespace + | awk '{print $1}' | grep -v NAME` + - 컨피그맵 백엔드: `kubectl get configmap -l + owner=helm,status=deployed,name= --namespace + | awk '{print $1}' | grep -v NAME` +- 배포된 최신 릴리스 정보를 가져온다. + - 시크릿 백엔드: `kubectl get secret -n + -o yaml > release.yaml` + - 컨피그맵 백엔드: `kubectl get configmap -n + -o yaml > release.yaml` +- 문제가 발생하여 복원해야 하는 경우 릴리스를 백업한다.: + - `cp release.yaml release.bak` + - 비상시에 복구해야 할 경우: `kubectl apply -f release.bak -n + ` +- 릴리스 객체를 디코딩한다: + - 시크릿 백엔드:`cat release.yaml | grep -oP '(?<=release: ).*' | base64 -d + | base64 -d | gzip -d > release.data.decoded` + - 컨피그맵 백엔드: `cat release.yaml | grep -oP '(?<=release: ).*' | base64 + -d | gzip -d > release.data.decoded` +- 매니페스트의 API 버전을 변경한다. 모든 도구(예: 편집기)를 사용하여 + 변경할 수 있다. 이것은 디코딩 된 릴리스 + 객체의 (`release.data.decoded`)의 `manifest` 필드에 존재한다. +- 릴리스 객체를 인코딩한다: + - 시크릿 백엔드: `cat release.data.decoded | gzip | base64 | base64` + - 컨피그맵 백엔드: `cat release.data.decoded | gzip | base64` +- 배포된 릴리스 파일(`release.yaml`)의 + `data.release` 속성 값을 인코딩 된 새 릴리스 객체로 변경한다. +- 파일을 네임스페이스에 적용한다: `kubectl apply -f release.yaml -n + ` +- 지원되는 쿠버네티스 API 버전이 있는 차트 버전으로 `helm upgrade` 를 + 수행한다. +- 현재 버전 이전의 헬름 버전으로 롤백하지 않도록 업그레이드에 + 설명을 추가한다. diff --git a/content/ko/docs/topics/kubernetes_distros.md b/content/ko/docs/topics/kubernetes_distros.md new file mode 100644 index 0000000000..9f86c36745 --- /dev/null +++ b/content/ko/docs/topics/kubernetes_distros.md @@ -0,0 +1,96 @@ +--- +title: "쿠버네티스 배포판 가이드" +description: "특정 쿠버네티스 환경에서 헬름 사용에 대한 정보 정리." +weight: 10 +--- + +헬름은 ([인증 여부](https://www.cncf.io/certification/software-conformance/)와 +관계 없이) 모든 [쿠버네티스 적합 버전](https://github.com/cncf/k8s-conformance)에서 +작동해야 한다. + +이 문서는 특정 쿠버네티스 환경에서 헬름을 사용하는 방법에 대한 정보를 정리한다. +원한다면, 특정 배포판(알파벳순 정렬)에 +대한 추가 내용을 기여하자. + + +## AKS + +헬름은 [Azure 쿠버네티스 서비스](https://docs.microsoft.com/en-us/azure/aks/kubernetes-helm)에서 +동작한다. + +## DC/OS + +헬름은 Mesospheres DC/OS 1.11 쿠버네티스 플랫폼에서 테스트를 거쳤고 동작하며, +추가 구성이 필요치 않다. + +## EKS + +헬름은 Amazon Elastic 쿠버네티스 서비스 (Amazon EKS)에서 동작한다. +[Amazon EKS에서 +헬름 사용](https://docs.aws.amazon.com/eks/latest/userguide/helm.html). + +## GKE + +구글의 GKE 호스팅 쿠버네티스 플랫폼은 헬름이 동작하는 것으로 +알려져 있으며, 추가 구성이 필요치 않다. + +## `scripts/local-cluster` 와 Hyperkube + +`scripts/local-cluster.sh` 를 통해 구성된 Hyperkube 에서 동작하는 것으로 알려져 있다. +원시(raw) Hyperkube 는 몇 가지 수동 구성이 필요할 수도 있다. + +## IKS + +헬름은 [IBM 클라우드 쿠버네티스 서비스](https://cloud.ibm.com/docs/containers?topic=containers-helm)에서 +동작한다. + +## KIND (Kubernetes IN Docker) + +헬름은 [KIND](https://github.com/kubernetes-sigs/kind)에서 정기적으로 테스트된다. + +## KubeOne + +헬름은 별다른 특이사항 없이 KubeOne 으로 구성된 클러스터에서 동작한다. + +## Kubermatic + +헬름은 별다른 특이사항 없이 Kubermatic 으로 생성된 사용자 클러스터에서 동작한다. +시드(seed) 클러스터는 다양한 방식으로 설정될 수 있으므로 헬름 지원은 +그 설정에 따라 달라진다. + +## MicroK8s + +[MicroK8s](https://microk8s.io) 에서는 명령어 `microk8s.enable helm3`를 사용하여 헬름을 활성화할 수 있다. + +## Minikube + +헬름은 [Minikube](https://github.com/kubernetes/minikube) 에서 테스트를 거쳤고 +동작하는 것으로 알려져 있다. +추가적인 구성이 필요하지 않다. + +## Openshift + +헬름은 OpenShift Online, OpenShift Dedicated, OpenShift Container Platform (버전 3.6 이상) 또는 +OpenShift Origin (버전 3.6 이상)에서 동작한다. +자세한 내용은 +[이 블로그](https://blog.openshift.com/getting-started-helm-openshift/) 의 게시물을 참조하자. + +## Platform9 + +헬름은 [Platform9 Managed +Kubernetes](https://platform9.com/managed-kubernetes/?utm_source=helm_distro_notes)와 함께 사전 설치된다. +Platform9 은 앱 카탈로그 UI 및 기본 쿠버네티스 CLI를 통해 +모든 공식 헬름 차트에 대한 접근을 제공한다. 추가적인 레포지토리들도 수동으로 추가할 수 있다. +상세한 내용은 [Platform9 App Catalog +article](https://platform9.com/support/deploying-kubernetes-apps-platform9-managed-kubernetes/?utm_source=helm_distro_notes)에서 확인할 수 있다. + +## 우분투와 `kubeadm` + +`kubeadm` 으로 구성된(bootstrapped) 쿠버네티스는 다음 리눅스 배포판에서 +동작하는 것으로 알려져 있다. + +- 우분투 16.04 +- 페도라 릴리스 25 + +헬름 일부 버전(v2.0.0-beta2)은 `export KUBECONFIG=/etc/kubernetes/admin.conf` 를 수행하거나 +`~/.kube/config` 를 생성해야 한다. diff --git a/content/ko/docs/topics/library_charts.md b/content/ko/docs/topics/library_charts.md new file mode 100644 index 0000000000..f6d1b322a9 --- /dev/null +++ b/content/ko/docs/topics/library_charts.md @@ -0,0 +1,385 @@ +--- +title: "라이브러리 차트" +description: "Explains library charts and examples of usage" +weight: 4 +--- + +A library chart is a type of [Helm chart]({{< ref "/docs/topics/charts.md" >}}) +that defines chart primitives or definitions which can be shared by Helm +templates in other charts. This allows users to share snippets of code that can +be re-used across charts, avoiding repetition and keeping charts +[DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself). + +The library chart was introduced in Helm 3 to formally recognize common or +helper charts that have been used by chart maintainers since Helm 2. By +including it as a chart type, it provides: +- A means to explicitly distinguish between common and application charts +- Logic to prevent installation of a common chart +- No rendering of templates in a common chart which may contain release + artifacts + +A chart maintainer can define a common chart as a library chart and now be +confident that Helm will handle the chart in a standard consistent fashion. It +also means that definitions in an application chart can be shared by changing +the chart type. + +## 간단한 라이브러리 차트 만들기 + +As mentioned previously, a library chart is a type of [Helm chart]({{< ref +"/docs/topics/charts.md" >}}). This means that you can start off by creating a +scaffold chart: + +```console +$ helm create mylibchart +Creating mylibchart +``` + +You will first remove all the files in `templates` directory as we will create +our own templates definitions in this example. + +```console +$ rm -rf mylibchart/templates/* +``` + +The values file will not be required either. + +```console +$ rm -f mylibchart/values.yaml +``` + +Before we jump into creating common code, lets do a quick review of some +relevant Helm concepts. A [named template]({{< ref +"/docs/chart_template_guide/named_templates.md" >}}) (sometimes called a partial +or a subtemplate) is simply a template defined inside of a file, and given a +name. In the `templates/` directory, any file that begins with an underscore(_) +is not expected to output a Kubernetes manifest file. So by convention, helper +templates and partials are placed in a `_*.tpl` or `_*.yaml` files. + +In this example, we will code a common ConfigMap which creates an empty +ConfigMap resource. We will define the common ConfigMap in file +`mylibchart/templates/_configmap.yaml` as follows: + +```yaml +{{- define "mylibchart.configmap.tpl" -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name | printf "%s-%s" .Chart.Name }} +data: {} +{{- end -}} +{{- define "mylibchart.configmap" -}} +{{- include "mylibchart.util.merge" (append . "mylibchart.configmap.tpl") -}} +{{- end -}} +``` + +The ConfigMap construct is defined in named template `mylibchart.configmap.tpl`. +It is a simple ConfigMap with an empty resource, `data`. Within this file there +is another named template called `mylibchart.configmap`. This named template +includes another named template `mylibchart.util.merge` which will take 2 named +templates as arguments, the template calling `mylibchart.configmap` and +`mylibchart.configmap.tpl`. + +The helper function `mylibchart.util.merge` is a named template in +`mylibchart/templates/_util.yaml`. It is a handy util from [The Common Helm +Helper Chart](#공용-헬름-헬퍼-차트) because it merges the 2 templates +and overrides any common parts in both: + +```yaml +{{- /* +mylibchart.util.merge will merge two YAML templates and output the result. +This takes an array of three values: +- the top context +- the template name of the overrides (destination) +- the template name of the base (source) +*/}} +{{- define "mylibchart.util.merge" -}} +{{- $top := first . -}} +{{- $overrides := fromYaml (include (index . 1) $top) | default (dict ) -}} +{{- $tpl := fromYaml (include (index . 2) $top) | default (dict ) -}} +{{- toYaml (merge $overrides $tpl) -}} +{{- end -}} +``` + +This is important when a chart wants to use common code that it needs to +customize with its configuration. + +Finally, lets change the chart type to `library`. This requires editing +`mylibchart/Chart.yaml` as follows: + +```yaml +apiVersion: v2 +name: mylibchart +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +# type: application +type: library + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. +appVersion: 1.16.0 +``` + +The library chart is now ready to be shared and its ConfigMap definition to be +re-used. + +Before moving on, it is worth checking if Helm recognizes the chart as a library +chart: + +```console +$ helm install mylibchart mylibchart/ +Error: library charts are not installable +``` + +## 간단한 라이브러리 차트 사용하기 + +It is time to use the library chart. This means creating a scaffold chart again: + +```console +$ helm create mychart +Creating mychart +``` + +Lets clean out the template files again as we want to create a ConfigMap only: + +```console +$ rm -rf mychart/templates/* +``` + +When we want to create a simple ConfigMap in a Helm template, it could look +similar to the following: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name | printf "%s-%s" .Chart.Name }} +data: + myvalue: "Hello World" +``` + +We are however going to re-use the common code already created in `mylibchart`. +The ConfigMap can be created in the file `mychart/templates/configmap.yaml` as +follows: + +```yaml +{{- include "mylibchart.configmap" (list . "mychart.configmap") -}} +{{- define "mychart.configmap" -}} +data: + myvalue: "Hello World" +{{- end -}} +``` + +You can see that it simplifies the work we have to do by inheriting the common +ConfigMap definition which adds standard properties for ConfigMap. In our +template we add the configuration, in this case the data key `myvalue` and its +value. The configuration override the empty resource of the common ConfigMap. +This is feasible because of the helper function `mylibchart.util.merge` we +mentioned in the previous section. + +To be able to use the common code, we need to add `mylibchart` as a dependency. +Add the following to the end of the file `mychart/Chart.yaml`: + +```yaml +# My common code in my library chart +dependencies: +- name: mylibchart + version: 0.1.0 + repository: file://../mylibchart +``` + +This includes the library chart as a dynamic dependency from the filesystem +which is at the same parent path as our application chart. As we are including +the library chart as a dynamic dependency, we need to run `helm dependency +update`. It will copy the library chart into your `charts/` directory. + +```console +$ helm dependency update mychart/ +Hang tight while we grab the latest from your chart repositories... +...Successfully got an update from the "stable" chart repository +Update Complete. ⎈Happy Helming!⎈ +Saving 1 charts +Deleting outdated charts +``` + +We are now ready to deploy our chart. Before installing, it is worth checking +the rendered template first. + +```console +$ helm install mydemo mychart/ --debug --dry-run +install.go:159: [debug] Original chart version: "" +install.go:176: [debug] CHART PATH: /root/test/helm-charts/mychart + +NAME: mydemo +LAST DEPLOYED: Tue Mar 3 17:48:47 2020 +NAMESPACE: default +STATUS: pending-install +REVISION: 1 +TEST SUITE: None +USER-SUPPLIED VALUES: +{} + +COMPUTED VALUES: +affinity: {} +fullnameOverride: "" +image: + pullPolicy: IfNotPresent + repository: nginx +imagePullSecrets: [] +ingress: + annotations: {} + enabled: false + hosts: + - host: chart-example.local + paths: [] + tls: [] +mylibchart: + global: {} +nameOverride: "" +nodeSelector: {} +podSecurityContext: {} +replicaCount: 1 +resources: {} +securityContext: {} +service: + port: 80 + type: ClusterIP +serviceAccount: + annotations: {} + create: true + name: null +tolerations: [] + +HOOKS: +MANIFEST: +--- +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +data: + myvalue: Hello World +kind: ConfigMap +metadata: + labels: + app: mychart + chart: mychart-0.1.0 + release: mydemo + name: mychart-mydemo +``` + +This looks like the ConfigMap we want with data override of `myvalue: Hello +World`. Lets install it: + +```console +$ helm install mydemo mychart/ +NAME: mydemo +LAST DEPLOYED: Tue Mar 3 17:52:40 2020 +NAMESPACE: default +STATUS: deployed +REVISION: 1 +TEST SUITE: None +``` + +We can retrieve the release and see that the actual template was loaded. + +```console +$ helm get manifest mydemo +--- +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +data: + myvalue: Hello World +kind: ConfigMap +metadata: + labels: + app: mychart + chart: mychart-0.1.0 + release: mydemo + name: mychart-mydemo + ``` + +## 공용 헬름 헬퍼 차트 + +Bit of a mouth full of a title but this +[chart](https://github.com/helm/charts/tree/master/incubator/common) is the +original pattern for common charts. It provides utilities that reflect best +practices of Kubernetes chart development. Best of all it can be used off the +bat by you when developing your charts to give you handy shared code. + +Here is a quick way to use it. For more details, have a look at the +[README](https://github.com/helm/charts/blob/master/incubator/common/README.md). + +Create a scaffold chart again: + +```console +$ helm create demo +Creating demo +``` + +Lets use the common code from the helper chart. First, edit deployment +`demo/templates/deployment.yaml` as follows: + +```yaml +{{- template "common.deployment" (list . "demo.deployment") -}} +{{- define "demo.deployment" -}} +## Define overrides for your Deployment resource here, e.g. +spec: + replicas: {{ .Values.replicaCount }} +{{- end -}} +``` + +And now the service file, `demo/templates/service.yaml` as follows: + +```yaml +{{- template "common.service" (list . "demo.service") -}} +{{- define "demo.service" -}} +## Define overrides for your Service resource here, e.g. +# metadata: +# labels: +# custom: label +# spec: +# ports: +# - port: 8080 +{{- end -}} +``` + +These templates show how inheriting the common code from the helper chart +simplifies your coding down to your configuration or customization of the +resources. + +To be able to use the common code, we need to add `common` as a dependency. Add +the following to the end of the file `demo/Chart.yaml`: + +```yaml +dependencies: +- name: common + version: "^0.0.5" + repository: "https://charts.helm.sh/incubator" +``` + +Note: You will need to add the `incubator` repo to the Helm repository list +(`helm repo add`). + +As we are including the chart as a dynamic dependency, we need to run `helm +dependency update`. It will copy the helper chart into your `charts/` directory. + +As helper chart is using some Helm 2 constructs, you will need to add the +following to `demo/values.yaml` to enable the `nginx` image to be loaded as this +was updated in Helm 3 scaffold chart: + +```yaml +image: + tag: 1.16.0 +``` + +It is good to go now, so deploy away! diff --git a/content/ko/docs/topics/permissions_sql_storage_backend.md b/content/ko/docs/topics/permissions_sql_storage_backend.md new file mode 100644 index 0000000000..cb963ff7f9 --- /dev/null +++ b/content/ko/docs/topics/permissions_sql_storage_backend.md @@ -0,0 +1,64 @@ +--- +title: "SQL 스토리지 백엔드에 대한 권한 관리" +description: "SQL 스토리지 백엔드를 사용할 때 권한을 설정하는 방법을 알아본다." + +--- + +이 문서는 SQL 스토리지 백엔드를 사용할 때 권한을 설정하고 관리하기 위한 +지침을 사용자에게 제공하는 것을 목표로 한다. + +## 소개 + +권한을 처리하기 위해 헬름은 쿠버네티스의 RBAC 기능을 사용한다. SQL 스토리지 +백엔드를 사용할 때 쿠버네티스의 역할을 사용하여 사용자가 주어진 +리소스에 액세스 할 수 있는지 여부를 결정할 수 없다. 이 문서는 이러한 권한을 +생성하고 관리하는 방법을 보여준다. + +## 초기화 + +헬름 CLI 가 처음으로 데이터베이스에 연결되면, 클라이언트는 이전에 초기화 되었는지 +확인한다. 그렇지 않은 경우 필요한 설정을 자동으로 처리한다. +이 초기화에는 공용 스키마에 대한 관리자 권한이 필요하거나 최소한 +다음을 수행할 수 있어야 한다. + +* 테이블 생성 +* 공개 스키마에 대한 권한 부여 + +사용자 데이터베이스에 대한 마이그레이션이 실행 된 후, 다른 모든 역할은 +클라이언트를 사용할 수 있다. + +## PostgreSQL 에서 관리자가 아닌 사용자에게 권한 부여 + +권한을 관리하기 위해 SQL 백엔드 드라이버는 PostgreSQL의 +[RLS](https://www.postgresql.org/docs/9.5/ddl-rowsecurity.html) (행 보안 +수준) 기능을 활용한다. RLS는 모든 사용자가 명시적으로 +허용되지 않는 경우 동일한 행을 조작하지 않고도 동일한 +테이블에서 읽거나 쓸 수 있도록 허용한다. 기본적으로 올바른 +권한이 명시적으로 부여되지 않은 모든 역할은 `helm list` 를 +실행할 때 항상 빈 목록을 반환하며 클러스터의 리소스를 +검색하거나 수정할 수 없다. + +지정된 역할에 특정 네임스페이스에 대한 액세스 권한을 부여하는 방법을 알아보자: + +```sql +CREATE POLICY ON releases_v1 FOR ALL TO USING (namespace = 'default'); +``` + +이 명령어는 `namespace = 'default'` 조건을 +충족하는 모든 리소스를 읽고 쓸 수 있는 권한을 `role` +역할에 부여한다. 이 정책을 만든 후 `role` 역할을 대신하여 +데이터베이스에 연결된 사용자는 `helm list` 를 실행할 때 +`default` 네임스페이스에 있는 모든 릴리스를 볼 수 있으며 수정 및 삭제할 수 있다. + +권한은 RLS를 사용하여 세분화하여 관리 할 수 있으며, 테이블의 주어진 다른 열의 +접근을 제한할 수도 있다. +* key +* type +* body +* name +* namespace +* version +* status +* owner +* createdAt +* modifiedAt diff --git a/content/ko/docs/topics/plugins.md b/content/ko/docs/topics/plugins.md new file mode 100644 index 0000000000..cbabc9bf8d --- /dev/null +++ b/content/ko/docs/topics/plugins.md @@ -0,0 +1,359 @@ +--- +title: "헬름 플러그인 가이드" +description: "헬름의 기능을 확장하기 위해 플러그인을 사용하고 만드는 방법을 소개한다." +weight: 12 +--- + +헬름 플러그인은 `helm` CLI를 통해 액세스할 수 있는 도구이지만 +기본 제공 헬름 코드 베이스에 포함되지는 않는다. + +기존 플러그인은 +[관련]({{< ref "related.md#helm-plugins">}}) 섹션 또는 +[GitHub](https://github.com/search?q=topic%3Ahelm-plugin&type=Repositories)을 검색하여 찾을 수 있다. + +이 가이드에서는 플러그인을 사용하고 만드는 방법을 설명한다. + +## 개요 + +헬름 플러그인은 헬름과 원활하게 연계되는 애드온 도구이다. +새로운 모든 기능을 Go로 작성하거나 코어 도구에 추가하지 않더라도, +헬름 플러그인을 사용하여 코어 기능 세트를 확장하는 방법을 제공한다. + +헬름 플러그인에는 다음과 같은 기능들이 있다. + +- 코어 헬름 도구에 영향을 주지 않고 헬름 설치에서 추가하거나 + 제거할 수 있다. +- 어느 프로그래밍 언어로도 작성할 수 있다. +- 헬름과 연계되며 `helm help` 및 그 외의 위치에서 조회될 수 있다. + +헬름 플러그인은 `$HELM_PLUGINS` 에 있다. +`helm env` 명령어를 사용하여 환경설정되지 않은 경우 기본값을 포함하여 현재 값을 찾을 수 있다. + +헬름 플러그인 모델은 부분적으로 Git의 플러그인 모델에서 모델링되었다. +이런 이유로 간혹 헬름을 _porcelain_ 레이어로, 플러그인은 _plumbing_ 로 불리는 경우도 있다. +이것은 헬름이 바깥으로 보이는 사용자 경험과 최상위 수준의 처리 로직을 제공하는 반면, 플러그인은 원하는 작업을 수행하는 "세부 작업"을 제공하기 때문이다. + +## 플러그인 설치하기 + +플러그인은 `$ helm plugin install ` 명령어를 사용하여 설치된다. +로컬 파일 시스템의 플러그인 경로 또는 원격 VCS 레포지터리의 URL을 전달할 수 있다. +`helm plugin install` 명령은 `$HELM_PLUGINS` 에 지정된 경로/URL 에서 플러그인을 복제하거나 복사한다. + +```console +$ helm plugin install https://github.com/adamreese/helm-env +``` + +플러그인 tar 배포판이 있는 경우 `$HELM_PLUGINS` 디렉터리에 플러그인 압축을 해제한다. +`helm plugin install https://domain/path/to/plugin.tar.gz` 을 실행하여 +URL에서 직접 tarball 플러그인을 설치할 수도 있다. + +## 플러그인 구축하기 + +여러 가지 측면에서 플러그인은 차트와 유사하다. +각 플러그인에는 최상위 디렉토리와 `plugin.yaml` 파일이 있다. + +``` +$HELM_PLUGINS/ + |- keybase/ + | + |- plugin.yaml + |- keybase.sh + +``` + +위의 예에서 `keybase` 플러그인은 `keybase` 라는 디렉터리에 포함되어 있다. +여기에는 `plugin.yaml`(필수) 파일과 실행 가능한 스크립트 `keybase.sh`(선택사항)이 있다. + +플러그인의 핵심은 `plugin.yaml` 이라는 간단한 YAML 파일이다. +다음은 keybase 작업에 대한 지원을 추가하는 플러그인용 YAML이다. + +```yaml +name: "last" +version: "0.1.0" +usage: "get the last release name" +description: "get the last release name"" +ignoreFlags: false +command: "$HELM_BIN --host $TILLER_HOST list --short --max 1 --date -r" +platformCommand: + - os: linux + arch: i386 + command: "$HELM_BIN list --short --max 1 --date -r" + - os: linux + arch: amd64 + command: "$HELM_BIN list --short --max 1 --date -r" + - os: windows + arch: amd64 + command: "$HELM_BIN list --short --max 1 --date -r" +``` + +`name` 은 플러그인의 이름이다. +헬름은 이 플러그인을 실행할 때 이 이름을 사용한다.(예: `helm NAME` 이 이 플러그인을 호출) + +_`name` 은 디렉토리 이름과 일치해야 한다._ +위의 예시에서는 `name: keybase` 가 있는 플러그인이 `keybase` 라는 디렉터리에 포함되어야 한다. + +`name`에 대한 제한: + +- `name` 은 기존의 `helm` 최상위 명령어와 중복될 수 없다. +- `name` 은 ASCII 문자 a-z, A-Z, 0-9, `_`, `-` 로 제한된다. + +`version` 은 플러그인의 SemVer 2 버전이다. +`usage` 및 `description` 은 모두 명령의 도움말 텍스트를 생성하는데 사용된다. + +`ignoreFlags` 스위치는 헬름에 플래그를 플러그인에게 전달하지 _않도록_ 한다. +따라서 플러그인이 `helm myplugin --foo` 및 `ignoreFlag: true` 로 호출되면 `--foo` 는 자동으로 삭제된다. + +마지막으로 가장 중요한 것은 `platformCommand` 또는 `command` 가 플러그인이 호출될 때 실행할 명령어이다. +`platformCommand` 섹션은 명령어의 OS/아키텍처에 따른 변형을 정의한다. +사용할 명령어를 결정할 때는 다음의 규칙이 적용된다. + +- `platformCommand` 가 있으면 우선 검색한다. +- `os` 와 `arch` 가 현재 플랫폼과 일치하면, + 검색을 중지하고 명령어를 사용한다. +- `os` 가 일치하고 `arch` 가 일치하지 않으면 + 명령어를 사용한다. +- 일치하는 `platformCommand` 가 없으면 기본 `command` 를 사용한다. +- `platformCommand` 에 일치하는 항목이 없고 `command` 가 없는 경우 + 헬름은 오류와 함께 종료된다. + +플러그인이 실행되기 전에 환경 변수가 보간된다. +위의 패턴은 플러그인 프로그램이 있는 위치를 나타내기 위해 선호되는 방식이다. + +플러그인 명령어 작업을 위한 몇 가지 전략이 있다. + +- 플러그인에 실행 파일이 포함된 경우 `platformCommand :` 또는 `command :`에 해당하는 + 실행 파일이 플러그인 디렉토리에 패키징되어야 한다. +- `platformCommand :`또는`command :` 행은 + 실행 전에 확장된 환경 변수를 가진다. + `$ HELM_PLUGIN_DIR`은 플러그인 디렉토리를 가리킨다. +- 명령어 자체는 쉘에서 실행되지 않는다. + 따라서 쉘 스크립트를 한줄로 작성할 수는 없다. +- 헬름은 수많은 설정들을 환경 변수로 주입한다. + 사용 가능한 정보가 무엇인지 그 환경을 확인해보자. +- 헬름은 플러그인의 언어를 가리지 않는다. + 원하는 것을 선택하여 작성하면 된다. +- 각 명령어에는`-h` 및`--help` 에 대한 도움말 텍스트가 구현되어야 한다. + Helm은 `helm help` 및 `helm help myplugin` 에 `usage` 및 `description`을 사용하지만 + `helm myplugin --help`는 처리하지 않는다. + +## 다운로더 플러그인 +기본적으로 헬름은 HTTP/S 를 사용하여 차트를 가져올 수 있다. +헬름 2.4.0부터 플러그인은 임의의 소스에서 차트를 다운로드하는 특별한 기능을 갖는다. + +플러그인은 `plugin.yaml` 파일(최상위수준)에서 이 특수기능을 +선언해야 한다. + +```yaml +downloaders: +- command: "bin/mydownloader" + protocols: + - "myprotocol" + - "myprotocols" +``` + +이러한 플러그인이 설치된 경우 Helm은 `command` 를 호출하여, 지정된 프로토콜 체계를 사용하여 레포지터리와 상호 작용할 수 있다. +`helm repo add favorite myprotocol://example.com/` 와 같은 특별한 레포지터리도 일반 레포지터리와 유사하게 추가된다. +특별한 레포지터리에 대한 규칙은 일반 레포지터리와 동일하다. 사용가능한 차트 목록을 검색하고 캐시하려면 +헬름이 `index.yaml` 파일을 다운로드할 수 있어야 한다. + +정의된 명령어는 `command certFile keyFile caFile full-URL` 형식에 따라 호출된다. +SSL 자격 증명은 `$HELM_REPOSITORY_CONFIG`(예를 들어, `$HELM_CONFIG_HOME/repositories.yaml`)에 저장된 레포지터리 정의에서 가져온다. +다운로더 플러그인은 원시 콘텐츠를 stdout 에 덤프하고 stderr에 오류를 보고해야 한다. + +다운로더 명령어는 하위 명령어 또는 인수도 지원하며, 예를 들어 `plugin.yaml` 에 `bin/mydownloader 하위명령어 -d` 를 지정할 수 있다. +이는 기본 플러그인 명령어와 다운로더 명령어에 대해 동일한 실행 파일을 사용하지만 각각에 대해 다른 하위명령어를 사용하려는 경우에 유용하다. + +## 환경 변수 + +Helm은 플러그인을 실행할 때, 외부 환경을 플러그인에 전달하고 추가 환경 변수도 삽입한다. + +`KUBECONFIG`와 같은 변수는 외부 환경에서 설정한 경우 플러그인에 대해 설정된다. + +다음의 변수들은 자동으로 설정된다. + +- `HELM_PLUGINS`: 플러그인 디렉토리 경로 +- `HELM_PLUGIN_NAME`: `helm`에 의해 호출되는 플러그인의 이름 + 즉, `helm myplug`는 `myplug` 라는 짧은 이름을 갖게 된다. +- `HELM_PLUGIN_DIR`: 플러그인이 포함된 디렉토리 +- `HELM_BIN`: (사용자에 의해 실행되는) `helm` 명령어의 경로 +- `HELM_DEBUG`: helm에 의해 디버그 플래그가 설정되었는지 여부를 표시한다. +- `HELM_REGISTRY_CONFIG`: (사용하는 경우) 레지스트리 설정 위치 + 레지스트리와 함께 헬름을 사용하는 것은 실험적인 기능임을 알아두자. +- `HELM_REPOSITORY_CACHE`: 저장소 캐시 파일의 경로 +- `HELM_REPOSITORY_CONFIG`: 저장소 설정 파일의 경로 +- `HELM_NAMESPACE`: `helm` 명령어에 지정된 네임스페이스 + (일반적으로 `-n` 플래그 사용) +- `HELM_KUBECONTEXT`: `helm` 명령어에 제공된 쿠버네티스 + 설정 컨텍스트의 이름 + +또한 쿠버네티스 설정 파일이 명시적으로 지정된 경우 'KUBECONFIG' 변수로 설정된다. + +## 플래그 구문 분석에 대한 유의 사항 + +플러그인을 실행할 때 헬름은 자체 사용을 위해 전역 플래그를 구문 분석한다. +이러한 플래그는 플러그인에 전달되지 않는다. + +- `--debug`: 지정하면`$ HELM_DEBUG`가`1`로 설정된다. +- `--registry-config`: 이 플래그는 `$ HELM_REGISTRY_CONFIG` 로 변환된다. +- `--repository-cache`: 이 플래그는 `$ HELM_REPOSITORY_CACHE` 로 변환된다. +- `--repository-config`: 이 플래그는 `$ HELM_REPOSITORY_CONFIG` 로 변환된다. +- `--namespace` and `-n`: 이 플래그는 `$ HELM_NAMESPACE` 로 변환된다. +- `--kube-context`: 이 플래그는 `$ HELM_KUBECONTEXT` 로 변환된다. +- `--kubeconfig`: 이 플래그는 `$KUBECONFIG` 로 변환된다. + +플러그인은 도움말 텍스트를 표시한 다음 `-h` 및 `--help` 를 위해 _종료해야 한다_. +다른 모든 경우에는, 플러그인은 적절하게 플래그를 사용할 수 있다. + +## 쉘 자동-완성 제공 + +헬름 3.2부터, 플러그인은 헬름의 기존 자동 완성 메커니즘의 일부로 쉘 자동 완성에 대한 지원을 선택적으로 제공할 수 있다. + +### 정적 자동-완성 + +플러그인이 자체 플래그 및/또는 하위 명령어를 제공하는 경우, 플러그인의 루트 디렉토리에 `completion.yaml` 파일을 두어 헬름에 알릴 수 있다. +`completion.yaml` 파일의 형식은 다음과 같다. + +```yaml +name: +flags: +- +- +validArgs: +- +- +commands: + name: + flags: + - + - + validArgs: + - + - + commands: + +``` + +유의사항: +1. 모든 섹션은 선택 사항이지만 해당되는 경우에는 제공해야 한다. +1. 플래그에는 `-` 또는`--` 접두사가 포함되지 않아야 한다. +1. 짧은 플래그와 긴 플래그 모두 지정해야 한다. + 짧은 플래그는 해당하는 긴 형식과 연결될 필요는 없지만, 두 형식 모두 나열되어야 한다. +1. 플래그는 어떤 방식으로도 정렬할 필요는 없지만 파일의 하위 명령어 계층 구조에서 올바른 위치에 나열되어야 한다. +1. 헬름의 기존 전역 플래그는 이미 헬름의 자동완성 메커니즘에 의해 처리되므로 플러그인은 `--debug`, `--namespace` 또는`-n`, `--kube-context` 플래그나 다른 기타 전역 플래그를 지정할 필요가 없다. +1. `validArgs` 목록은 하위 명령어 다음의 첫 번째 매개 변수에 대해 가능한 완성의 정적 목록을 제공한다. + 이러한 목록을 미리(하단의 [동적 완성](#동적-완성)을 참조) 제공하는 것이 항상 가능한 것은 아니다. + 이 경우`validArgs` 섹션을 생략할 수 있다. + +`completion.yaml` 파일은 전적으로 선택 사항이다. +제공되지 않는 경우 Helm은 플러그인(플러그인에서 [동적 완성] (#동적-완성)을 지원하지 않는 경우)에 대한 쉘 자동 완성 기능을 제공하지 않는다. +또한`completion.yaml` 파일을 추가하면 이전 버전과 호환되며 이전 헬름 버전을 사용할 때 플러그인 동작에 영향을 주지 않는다. + +예를 들어 하위 명령어는 없지만 `helm status` 명령어와 동일한 플래그를 허용하는 [`풀스테이터스 플러그인`] (https://github.com/marckhouzam/helm-fullstatus)의 경우 `completion. yaml` 파일은 다음과 같다. + +```yaml +name: fullstatus +flags: +- o +- output +- revision +``` + +[`헬름 버전 2에서 버전3으로의 플러그인`] (https://github.com/helm/helm-2to3)과 같은 더 복잡한 예시로, 다음과 같은`completion.yaml` 파일이 있다. + +```yaml +name: 2to3 +commands: +- name: cleanup + flags: + - config-cleanup + - dry-run + - l + - label + - release-cleanup + - s + - release-storage + - tiller-cleanup + - t + - tiller-ns + - tiller-out-cluster +- name: convert + flags: + - delete-v2-releases + - dry-run + - l + - label + - s + - release-storage + - release-versions-max + - t + - tiller-ns + - tiller-out-cluster +- name: move + commands: + - name: config + flags: + - dry-run +``` + +### 동적 완성 + +또한 헬름 3.2부터 플러그인은 자체 동적 쉘 자동완성 기능을 제공할 수 있다. +동적 쉘 자동완성은 미리 정의할 수 없는 매개 변수 값 또는 플래그 값의 완성이다. +예를 들면, 현재 클러스터에서 사용할 수 있는 헬름 릴리스의 이름 완성이 있다. + +플러그인이 동적 자동 완성을 지원하려면 루트 디렉토리에는 `plugin.complete` 라는 **실행** 파일을 제공해야 한다. +헬름 완성 스크립트에 플러그인에 대한 동적 완성이 필요한 경우 `plugin.complete` 파일을 실행하여 완성해야 하는 명령줄에 전달해야 한다. +`plugin.complete` 실행 파일에는 적절한 완성 선택이 무엇인지 결정하고 헬름 완성 스크립트에서 사용할 표준 출력으로 출력하는 로직이 있어야 한다. + +`plugin.complete` 파일은 전적으로 선택 사항이다. +제공되지 않으면 헬름은 플러그인에 대한 동적 자동완성 기능을 제공하지 않는다. +또한 `plugin.complete` 파일을 추가하는 것은 이전 버전과 호환되어 이전 헬름 버전을 사용할 때 플러그인의 동작에 영향을 주지 않는다. + +`plugin.complete` 스크립트의 출력은 다음과 같이 줄바꿈으로 구분된 목록이어야 한다. + +``` +rel1 +rel2 +rel3 +``` + +`plugin.complete` 가 호출되면 플러그인의 메인 스크립트가 호출될 때와 마찬가지로 플러그인 환경이 설정된다. +따라서 변수 `$ HELM_NAMESPACE`, `$ HELM_KUBECONTEXT` 및 기타 모든 플러그인 변수가 이미 설정되어 있으며 해당 전역 플래그가 제거된다. + +`plugin.complete` 파일은 모든 실행가능 형식일 수 있다. +쉘 스크립트, Go 프로그램 또는 헬름이 실행할 수 있는 다른 유형의 프로그램이 될 수 있다. +`plugin.complete` 파일에는 ***반드시*** 사용자에 대한 실행 권한이 있어야 한다. +`plugin.complete` 파일은 *** 반드시 *** 성공 코드(값 0)와 함께 종료되어야 한다. + +경우에 따라서는 동적 완성은 쿠버네티스 클러스터에서 정보를 가져와야 한다. +예를 들어 `helm fullstatus` 플러그인에는 릴리스 이름이 입력으로 필요하다. +`fullstatus` 플러그인에서 `plugin.complete` 스크립트가 현재 릴리스 이름에 대한 완성 기능을 제공하려면 `helm list -q` 를 실행하고 결과를 출력하면 된다. + +플러그인 실행과 플러그인 완성을 위해 동일한 실행 파일을 사용하려면 `plugin.complete` 스크립트를 만들어 특별한 매개변수나 플래그를 사용하여 메인 플러그인 실행파일을 호출할 수 있다. +메인 플러그인 실행파일이 특별한 매개변수나 플래그를 감지하면, 자동완성을 실행하는 것을 알게 된다. +이 예에서 `plugin.complete` 는 다음과 같이 구현될 수 있다. + +```sh +#!/usr/bin/env sh + +# "$@" 는 완성이 필요한 전체 명령줄이다. +# 빈 마지막 매개변수를 유지하려면 "$@" 변수를 겹따옴표로 묶는 것이 중요하다. +$HELM_PLUGIN_DIR/status.sh --complete "$@" +``` + +`fullstatus` 플러그인의 실제 스크립트 (`status.sh`)는 `--complete` 플래그를 찾아야 하며, 발견될 경우 적절한 완성을 출력해야 한다. + +### 팁과 요령 + +1. 쉘은 사용자 입력과 일치하지 않는 완성 선택항목을 자동으로 필터링한다. + 따라서 플러그인은 사용자 입력과 일치하지 않는 완성을 제거하지 않고 관련된 모든 완성을 반환할 수 있다. + 예를 들어, 명령줄이 `helm fullstatus ngin ` 인 경우, + `plugin.complete` 스크립트는 `ngin` 으로 시작하는 이름뿐 아니라 *모든* 릴리스 이름 (`default` 네임스페이스에 있는 것)을 출력할 수 있다. + 쉘은 'ngin'으로 시작하는 것만을 유지한다. +1. 특별히 복잡한 플러그인이 있는 경우 동적 완성 지원을 단순화하기 위해 `plugin.complete` 스크립트가 기본 플러그인 스크립트를 호출하고 완성 선택을 요청하도록 할 수 있다. + 예제는 위의 [동적 완성](#동적-완성) 섹션을 참조하자. +1. 동적 완성 및 `plugin.complete` 파일을 디버깅하기 위해, + 다음을 실행하여 완성되는 결과를 확인할 수 있다. + - `helm __complete `. 예를 들면, + - `helm __complete fullstatus --output js`, + - `helm __complete fullstatus -o json ""` diff --git a/content/ko/docs/topics/provenance.md b/content/ko/docs/topics/provenance.md new file mode 100644 index 0000000000..802b8f284a --- /dev/null +++ b/content/ko/docs/topics/provenance.md @@ -0,0 +1,293 @@ +--- +title: "헬름 출처 및 무결성" +description: "차트의 무결성과 출처를 검증하는 방법을 설명한다." +weight: 5 +--- + +헬름에는 차트 사용자가 패키지의 무결성과 출처를 검증하는 데 도움이 되는 출처 도구가 있다. +헬름은 PKI, GnuPG 및 평판이 좋은 패키지 관리자에 기반한 업계 표준 도구를 사용하여 +서명 파일을 생성하고 검증할 수 있다. + +## 개요 + +무결성은 차트를 출처기록과 비교하여 설정된다. 출처 레코드는 +패키지 차트와 함께 저장되는 _출처 파일_에 저장되며 패키지 +차트와 함께 저장된다. 예를 들어 차트 이름이 `myapp-1.2.3.tgz` 인 경우 +출처 파일은 `myapp-1.2.3.tgz.prov` 이 된다. + +출처 파일은 패키징 시 (`helm package --sign ...`) 에 생성되며, 여러 가지 명령어로 +확인할 수 있는데 흔히 `helm install --verify` 를 사용한다. + +## 작업흐름 + +이 섹션에서는 출처 데이터를 효과적으로 사용하기 위한 작업흐름 예시를 +설명한다. + +전제 조건: + +- (ASCII-armored가 아닌) 바이너리 형식의 유효한 PGP 키페어 +- `헬름` 명령줄 도구 +- GnuPG 명령줄 도구 (선택사항) +- 키베이스(Keybase) 명령줄 도구 (선택사항) + +**참고:** PGP 개인 키에 암호가 있을 경우 `--sign` 옵션을 지원하는 +명령어에 대해 해당 암호를 입력하라는 메시지가 표시된다. + +새 차트를 만드는 방법은 이전과 동일하다. + +```console +$ helm create mychart +Creating mychart +``` + +패키징할 준비가 되면 `--sign` 플래그를 `helm package` 에 +추가해야 한다. 또한 서명 키가 알려진 이름과 해당 개인 키를 포함하는 +키링을 지정해야 한다. + +```console +$ helm package --sign --key 'John Smith' --keyring path/to/keyring.secret mychart +``` + +**참고:** `--key` 인수의 값은 이름 또는 이메일과 같이 원하는 키의 +`uid` (`gpg --list-keys` 출력에 존재)의 +하위 문자여야 한다. **지문(fingerprint)은 사용할 수 _없다_** + +**팁:** GnuPG 사용자의 경우 비밀 키링은 `~/.gnupg/secring.gpg` 에 존재한다. +`gpg --list-secret-keys` 를 사용하여 보유한 키를 나열할 수 있다. + +**경고:** GnuPG v2는 기본 위치 `~/.gnupg/pubring.kbx` 에 +새로운 형식 `kbx` 를 사용하여 비밀 키링을 저장한다. +다음 명령어를 사용하여 키링을 레거시 gpg 형식으로 변환한다. + +```console +$ gpg --export-secret-keys >~/.gnupg/secring.gpg +``` + +이 시점에서, `mychart-0.1.0.tgz` 와 +`mychart-0.1.0.tgz.prov` 가 모두 표시되어야 한다. 결국 두 파일 모두 +원하는 차트 저장소에 업로드되어야 한다. + +`helm verify` 를 사용하여 차트를 검증할 수 있다. + +```console +$ helm verify mychart-0.1.0.tgz +``` + +검증에 실패한 경우 다음과 같다. + +```console +$ helm verify topchart-0.1.0.tgz +Error: sha256 sum does not match for topchart-0.1.0.tgz: "sha256:1939fbf7c1023d2f6b865d137bbb600e0c42061c3235528b1e8c82f4450c12a7" != "sha256:5a391a90de56778dd3274e47d789a2c84e0e106e1a37ef8cfa51fd60ac9e623a" +``` + +설치 중에 검증하려면 `--verify` 플래그를 사용한다. + +```console +$ helm install --generate-name --verify mychart-0.1.0.tgz +``` + +서명된 차트와 연결된 공개키와 포함된 키링이 기본 위치에 없으면 +`helm pakcage` 예제에서와 같이 사용자가 `--keyring PATH`로 +키링의 위치를 지정해야 할 수 있다. + +검증에 실패하면 차트가 렌더링되기 전에 설치가 +중단된다. + +### Keybase.io 자격증명 사용하기 + +[Keybase.io](https://keybase.io) 서비스를 사용하면 암호화 ID에 대한 +신뢰 체인을 쉽게 설정할 수 있다. keybase 자격 증명은 차트에 서명하는데 +사용될 수 있다. + +전제 조건: + +- 구성된 Keybase.io 계정 +- 로컬에 설치된 GnuPG +- 로컬에 설치된 `keybase` CLI + +#### 패키지 서명하기 + +첫 번째 단계는 keybase 키를 로컬 GnuPG 키링으로 가져오는 것이다. + +```console +$ keybase pgp export -s | gpg --import +``` + +이렇게 하면 Kyebase 키가 OpenPGP 형식으로 변환된 다음 +`~/.gnupg/secring.gpg` 파일로 로컬에 저장한다. + +`gpg --list-secret-keys` 를 실행하여 다시 확인할 수 있다. + +```console +$ gpg --list-secret-keys +/Users/mattbutcher/.gnupg/secring.gpg +------------------------------------- +sec 2048R/1FC18762 2016-07-25 +uid technosophos (keybase.io/technosophos) +ssb 2048R/D125E546 2016-07-25 +``` + +비밀 키에는 식별자 문자열이 있다. + +``` +technosophos (keybase.io/technosophos) +``` + +이것이 키의 전체 이름이다. + +다음으로 `helm package` 로 차트를 패키징하고 서명할 수 있다. +최소한 `--key` 에서 해당 이름 문자열의 일부는 사용해야 한다. + +```console +$ helm package --sign --key technosophos --keyring ~/.gnupg/secring.gpg mychart +``` + +결과적으로, `package` 명령어는 `.tgz` 파일과 `.tgz.prov` 파일 모두를 +생성해야 한다. + +#### 패키지 검증하기 + +유사한 기술을 사용하여 다른 사람의 keybase 키로 서명된 차트를 검증할 수 있다. +`keybase.io/technosophos` 로 서명된 패키지를 검증하려는 경우를 생각해보자. +그런 경우 `keybase` 도구를 사용해야 한다. + +```console +$ keybase follow technosophos +$ keybase pgp pull +``` + +위의 첫 번째 명령어는 `technosophos` 사용자를 추적한다. 다음으로 +`keybase pgp pull` 은 팔로우하는 모든 계정의 OpenPGP 키를 다운로드하여 +GnuPG 키링(`~/.gnupg/pubring.gpg`)에 배치한다. + +이 시점에서 이제 `helm verify` 또는 `--verify` 플래그가 있는 명령어를 사용할 +수 있다. + +```console +$ helm verify somechart-1.2.3.tgz +``` + +### 차트가 검증되지 않는 이유 + +실패하는 이유는 주로 다음과 같다. + +- `.prov` 파일이 없거나 손상된 경우다. 이것은 무언가가 + 잘못 구성되었거나 기존 관리자가 출처 파일을 + 만들지 않은 경우이다. +- 파일 서명에 사용된 키가 키링에 없는 경우이다. + 이는 차트에 서명한 엔티티가 사용자가 + 신뢰한다고 신호를 보낸 사람이 아님을 의미한다. +- `.prov` 파일 검증에 실패한 경우다. 이는 차트 또는 출처 데이터에 문제가 있음을 + 나타낸다. +- 출처 파일의 파일 해시가 아카이브 파일의 해시와 일치하지 않는 경우이다. + 이는 아카이브가 변조되었음을 나타낸다. + +검증이 실패한다면 그 패키지를 신뢰할 수 없는 이유가 된다. + +## 출처 파일 + +출처 파일에는 차트의 YAML 파일과 몇 가지 +검증 정보가 포함되어 있다. +출처 파일은 자동으로 생성되도록 설계되어 있다. + +다음과 같은 출처 데이터가 추가된다. + +* 차트 파일(`Chart.yaml`) 이 포함되어 있어 사람과 도구 모두 차트 내용을 쉽게 + 볼 수 있다. +* 차트 패키지(`.tgz` 파일)의 서명(도커와 마찬가지로 SHA256)이 포함되어 있으며 + 차트 패키지의 무결성을 검증하는 데 + 사용할 수 있다. +* 전체 본문은 OpenPGP 에서 사용하는 + 알고리즘을 사용하여 서명된다(암호화 서명 및 + 검증을 쉽게 하는 새로운 방법은 [Keybase.io](https://keybase.io) 참고하자). + +이러한 조합은 사용자에게 다음과 같은 보증을 제공한다. + +* 패키지 자체가 변경되지 않았다. (체크섬 패키지 `.tgz`) +* 이 패키지를 출시한 엔티티가 (GnuPG/PGP 서명을 통해) 알려져 있다. + +파일 형식은 다음과 같다. + +``` +Hash: SHA512 + +apiVersion: v2 +appVersion: 1.16.0 +description: Sample chart +name: mychart +type: application +version: 0.1.0 + +... +files: + mychart-0.1.0.tgz: sha256:d31d2f08b885ec696c37c7f7ef106709aaf5e8575b6d3dc5d52112ed29a9cb92 +-----BEGIN PGP SIGNATURE----- + +wsBcBAEBCgAQBQJdy0ReCRCEO7+YH8GHYgAAfhUIADx3pHHLLINv0MFkiEYpX/Kd +nvHFBNps7hXqSocsg0a9Fi1LRAc3OpVh3knjPfHNGOy8+xOdhbqpdnB+5ty8YopI +mYMWp6cP/Mwpkt7/gP1ecWFMevicbaFH5AmJCBihBaKJE4R1IX49/wTIaLKiWkv2 +cR64bmZruQPSW83UTNULtdD7kuTZXeAdTMjAK0NECsCz9/eK5AFggP4CDf7r2zNi +hZsNrzloIlBZlGGns6mUOTO42J/+JojnOLIhI3Psd0HBD2bTlsm/rSfty4yZUs7D +qtgooNdohoyGSzR5oapd7fEvauRQswJxOA0m0V+u9/eyLR0+JcYB8Udi1prnWf8= +=aHfz +-----END PGP SIGNATURE----- +``` + +YAML 섹션에는 (`...\n` 로 구분되는) 두 개의 문서가 포함되어 있다. +첫 번째 파일은 `Chart.yaml` 의 내용이다. +두 번째는 패키징 시 해당 파일 콘텐츠의 SHA-256 다이제스트에 대한 파일 이름 맵인 체크섬 파일이다. + +서명 블록은 [변조 방지](https://www.rossde.com/PGP/pgp_signatures.html)를 +제공하는 표준 PGP 서명이다. + +## 차트 저장소 + +차트 저장소는 헬름 차트의 중앙 집중식 콜렉션 역할을 한다. + +차트 저장소는 특정 요청을 통해 HTTP를 통해 +출처 파일을 제공할 수 있도록 해야 하며 차트와 +동일하게 URI 경로에서 사용할 수 있도록 해야 한다. + +예를 들어 패키지의 기본 URL이 +`https://example.com/charts/mychart-1.2.3.tgz` 일 때 +출처 파일이 있는 경우에는, +`https://example.com/charts/mychart-1.2.3.tgz.prov` 에서 접근할 수 있어야 한다. + +최종 사용자의 관점에서 `helm install --verify myrepo/mychart-1.2.3` 은 +추가 사용자 구성이나 작업없이 차트와 출처 파일을 모두 +다운로드해야 한다. + +## 권한 및 인증 확립하기 + +신뢰 체인 시스템을 다룰 때는 서명자의 권한을 수립할 수 있게 +하는 것이 중요하다. 쉽게 말하면, 이 체계는 +차트에 서명한 사람을 신뢰할 수 있는지에 달려 있다. +바꿔 말하면, 서명자의 공개키를 신뢰할 필요가 있다는 것을 의미한다. + +헬름의 디자인 철학 중 하나는, 헬름 프로젝트가 신뢰 체인에 +필요한 당사자로 자기 자신을 포함시키지 않는다는 것이다. +우리는 모든 차트 서명자의 "인증기관"이 되고 싶지 않다. +대신 우리는 탈중앙화 모델을 선호하며, +OpenPGP를 기반 기술로 선택한 이유 중 하나이다. +따라서 권한 수립에 관한 진행단계는 헬름 2(헬름 3로 넘김)에서 +정의되지 않은 채로 남아 있다 . + +하지만, 출처 시스템 사용에 관심이 있는 분들을 위한 몇 가지 조언과 +권장 사항은 있다. + +- [Keybase](https://keybase.io) 플랫폼은 신뢰 정보를 위한 공개 중앙 + 저장소를 제공한다. + - Keybase를 사용하여 키를 저장하거나 다른 사람의 공개 키를 가져올 수 있다. + - Keybase 에는 사용 가능한 훌륭한 문서도 존재한다. + - 테스트되진 않았지만, Keybase 의 "보안 웹사이트" 기능을 사용하여 + 헬름 차트를 제공할 수도 있다. +- [공식 헬름 차트 프로젝트](https://github.com/helm/charts) 는 공식 차트 저장소를 위해 + 이 문제를 해결하기 위해 노력하고 있다. + - [현재의 생각을 자세히 설명하는](https://github.com/helm/charts/issues/23) + 긴 이슈가 존재한다. + - 기본 아이디어는 공식 "차트 리뷰어"가 자신의 키로 차트에 서명하고 + 생성된 출처 파일을 차트 저장소에 + 업로드하는 것이다. + - 저장소의 `index.yaml` 파일에 유효한 서명 키 목록이 포함될 수 있다는 + 아이디어에 대한 몇 가지 작업이 있었다. + diff --git a/content/ko/docs/topics/rbac.md b/content/ko/docs/topics/rbac.md new file mode 100644 index 0000000000..738ddc8aed --- /dev/null +++ b/content/ko/docs/topics/rbac.md @@ -0,0 +1,208 @@ +--- +title: "역할 기반 접근 제어" +description: "헬름이 쿠버네티스의 역할 기반 접근 제어와 상호 작용하는 방법을 설명한다." +weight: 11 +--- + +쿠버네티스에서 사용자 또는 애플리케이션별 서비스 계정에 +역할을 부여하는 것은 애플리케이션이 지정한 권한범위 내에서 작동하도록 +하는 모범 사례이다. [공식 쿠버네티스 +문서에서](https://kubernetes.io/docs/admin/authorization/rbac/#service-account-permissions) 서비스 계정 권한에 대해 +자세히 알아보도록 하자. + +쿠버네티스 1.6 부터는 역할 기반 접근 제어(RBAC)가 기본적으로 활성화된다. +RBAC을 사용하면 조직에서 사용자와 역할에 따라 허용되는 +작업유형을 지정할 수 있다. + +RBAC을 사용하여, 사용자는 다음을 수행할 수 있다. + +- 관리자에게 특별 작업권한(새 역할과 같은 클러스터 전체 리소스 생성)을 + 부여한다. +- 리소스(파드, 퍼시스턴트 볼륨, + 디플로이먼트)를 생성하는 사용자의 권한을 특정 네임스페이스 또는 클러스터 전체 범위(리소스 + 할당량, 역할, 사용자 지정 리소스 정의)로 제한한다. +- 특정 네임스페이스 또는 클러스터 전체 범위에서 리소스를 볼 수 있는 사용자의 + 권한을 제한한다. + +이 가이드는 사용자와 쿠버네티스 API 의 상호작용 범위를 제한하려는 +관리자를 위한 것이다. + +## 사용자 계정 관리 + +모든 쿠버네티스 클러스터에는 2가지 사용자 카테고리가 있다: 일반 사용자와 쿠버네티스가 관리하는 +서비스 계정 + +일반 사용자는 외부의 독립적인 서비스에 의해 관리되는 것으로 간주한다. 관리자가 개인키를 +발급해주면, 사용자는 키스톤이나 구글 어카운트(Google Accounts)에 보관하거나 그냥 +사용자 이름 및 비밀번호 목록을 파일에 보관할 수도 있다. 이와 관련하여 쿠버네티스에는 +일반 사용자 계정을 나타내는 객체가 없다. 일반 사용자는 +API 호출을 통해 클러스터에 추가될 수 없다. + +반대로 서비스 계정은 쿠버네티스 API로 관리되는 사용자이다. 특정 +네임스페이스에 바인딩 되며 API 서버에 의해 자동으로 생성되거나 +API 호출을 통해 수동으로 생성된다. 서비스 계정은 시크릿으로 +저장된 자격증명 집합에 연결되어 있으며, 파드에 마운트되어 클러스터 +내 프로세스가 쿠버네티스 API와 통신할 수 있도록 한다. + +API 요청은 일반 사용자 또는 서비스 계정에 연결되거나 +익명의 요청으로 처리된다. 즉, 워크스테이션에서 `kubectl` 을 +입력하는 실제 사용자, 노드의 kubelet, 컨트롤 플레인의 구성원에 +이르기까지 클러스터 내부 또는 외부의 모든 프로세스는 API 서버에 요청할 때 +인증을 받거나 익명의 사용자로 취급되어야 한다는 것을 의미한다. + +## 롤, 클러스터롤, 롤바인딩, 클러스터롤바인딩 + +쿠버네티스에서 사용자 계정 및 서비스 계정은 +접근 권한이 부여된 리소스만을 보고 편집할 수 있다. +이 접근은 롤 및 롤바인딩을 통해 부여된다. 롤 및 롤바인딩은 +특정 네임스페이스에 바인딩되어 롤이 사용자에게 접근을 제공하는 +동안 네임스페이스 내의 리소스를 보거나 편집할 수 있는 권한이 부여된다. + +클러스터 범위에서는 이를 클러스터롤 및 클러스터롤바인딩이라고 한다. +사용자에게 클러스터롤을 부여하면 전체 클러스터에서 리소스를 보거나 +편집할 수 있는 접근 권한이 부여된다. 또한 클러스터 범위(네임스페이스, +리소스 할당량, 노드)에서 리소스를 보거나 편집할 수 있다. + +클러스터롤은 롤바인딩의 참조를 통해 특정 네임스페이스에 바인딩 +될 수 있다. `admin`, `edit` 및 `view` 기본 클러스터롤은 +일반적으로 이러한 방식으로 사용된다. + +쿠버네티스에서 기본적으로 사용할 수 있는 몇가지 클러스터롤들이 있다. 이는 +사용자와 직접 연계하기 위해서이다. 여기에는 super-user 롤 +(`cluster-admin`)과 더 세분화된 접근 권한(`admin`, `edit`, +`view`)이 포함된다. + +| 기본 클러스터롤 | 기본 클러스터롤바인딩 | 설명 +|---------------------|----------------------------|------------- +| `cluster-admin` | `system:masters` group | super-user를 허용하여 모든 리소스에서 작업을 수행할 수 있다. 클러스터롤바인딩에서 사용하면 클러스터 및 모든 네임스페이스의 모든 리소스를 완전히 제어할 수 있다. 롤바인딩에서 사용하면 네임스페이스 자체를 포함하여 롤바인딩의 네임스페이스에 있는 모든 리소스에 대한 모든 권한을 제공한다. +| `admin` | None | 롤바인딩을 사용하여 네임스페이스 내에서 부여되도록 의도된 관리자 접근을 허용한다. 롤바인딩에서 사용되는 경우 네임스페이스 내에서 롤 및 롤바인딩을 만드는 기능을 포함하여 네임스페이스의 대부분의 리소스에 대한 읽기/쓰기 접근을 허용한다. 리소스 할당량 또는 네임스페이스 자체에 대한 쓰기 접근은 허용하지 않는다. +| `edit` | None | 네임스페이스에 있는 대부분의 오브젝트에 대한 읽기/쓰기 접근을 허용한다. 롤 및 롤바인딩을 보거나 수정할수는 없다. +| `view` | None | 읽기 전용 접근을 허용하여 네임스페이스에 있는 대부분의 오브젝트를 볼 수 있다. 롤 및 롤바인딩을 보는 것은 허용되지 않는다. 마찬가지로 시크릿을 보는 것은 허용되지 않는다. + +## RBAC을 사용하여 사용자 계정의 접근 제한하기 + +이제 역할 기반 접근의 기본 사항을 이해했으므로, 관리자가 사용자의 접근 범위를 +제한하는 방법에 대해 알아보자. + +### 예: 사용자에게 특정 네임스페이스에 대한 읽기/쓰기 접근 권한 부여하기 + +특정 네임스페이스에 대한 사용자의 접근을 제한하려면 `edit` 또는 `admin` +롤을 사용할 수 있다. 차트가 롤 및 롤바인딩을 생성하거나 상호작용하는 경우 +`admin` 클러스터롤을 사용하는 것이 좋다. + +또한 `cluster-admin` 접근 권한으로 롤바인딩을 만들 수도 있다. +네임스페이스 범위에서 사용자에게 `cluster-admin` 접근 권한을 부여하면 +네임스페이스 자체를 포함하여 네임스페이스의 모든 리소스를 완전히 제어할 수 있다. + +이 예시에서는 `edit` 역할을 가진 사용자를 생성한다. 먼저 네임스페이스를 +만든다. + +```console +$ kubectl create namespace foo +``` + +이제 해당 네임스페이스에 롤바인딩을 만들어서 사용자에게 `edit` 롤을 부여한다. + +```console +$ kubectl create rolebinding sam-edit + --clusterrole edit \​ + --user sam \​ + --namespace foo +``` + +### 예: 사용자에게 클러스터 범위에서 읽기/쓰기 접근 권한 부여하기 + +사용자가 클러스터 범위 리소스 +(네임스페이스, 롤, 사용자 지정 리소스 정의 등)를 +설치하는 차트를 설치하려는 경우, 클러스터 범위의 쓰기 접근이 필요하다. + +이를 위해 사용자에게 `admin` 또는 `cluster-admin` 접근 권한을 부여한다. + +사용자에게 `cluster-admin` 접근 권한을 부여하면 +`kubectl drain` 을 사용한 노드 접근 및 기타 관리 작업을 +포함하여 쿠버네티스에서 사용할 수 있는 모든 리소스에 대한 접근 권한이 +부여된다. 이 방식보다는 사용자에 `admin` 접근을 제공하거나 필요에 +맞는 사용자 지정 클러스터롤을 생성하는 것을 권장한다. + +```console +$ kubectl create clusterrolebinding sam-view + --clusterrole view \​ + --user sam + +$ kubectl create clusterrolebinding sam-secret-reader + --clusterrole secret-reader \​ + --user sam +``` + +### 예: 사용자에게 특정 네임스페이스에 대한 읽기 전용 접근 권한 부여하기 + +시크릿을 볼 수 있는 클러스터롤이 없다는 것을 알아챘을지도 모르겠다. +`view` 클러스터롤은 에스컬레이션 문제로 인해 사용자에게 시크릿에 +대한 읽기 접근 권한을 부여하지 않는다. 헬름은 기본적으로 릴리스 메타 데이터를 시크릿으로 저장한다. + +사용자가 `helm list` 를 실행하려면 이러한 시크릿을 읽을 수 있어야 한다. 이를 위해 +특별한 `secret-reader` 클러스터롤을 생성한다. + +`cluster-role-secret-reader.yaml` 파일을 만들고 아래의 +내용을 파일에 작성한다. + +```yaml +apiVersion: rbac.authorization.k8s.io/v1​ +kind: ClusterRole​ +metadata:​ + name: secret-reader​ +rules:​ +- apiGroups: [""]​ + resources: ["secrets"]​ + verbs: ["get", "watch", "list"] +``` + +그러고 나서, 다음을 사용하여 클러스터롤을 만든다. + +```console +$ kubectl create -f clusterrole-secret-reader.yaml​ +``` + +완료되면 사용자에게 대부분의 리소스에 대한 접근 권한을 부여한 다음 시크릿에 대한 +읽기 접근 권한을 부여할 수 있다. + +```console +$ kubectl create namespace foo + +$ kubectl create rolebinding sam-view + --clusterrole view \​ + --user sam \​ + --namespace foo + +$ kubectl create rolebinding sam-secret-reader + --clusterrole secret-reader \​ + --user sam \​ + --namespace foo +``` + +### 예: 클러스터 범위에서 사용자에게 읽기전용 접근 권한 부여하기 + +특정 시나리오에서는 사용자에게 클러스터 범위 접근 권한을 부여하는 것이 유용할 수 있다. +예를 들어 사용자가 `helm list --all-namespaces` 명령을 +실행하려는 경우 API는 사용자에게 클러스터 범위 읽기 접근 권한이 있어야 한다. + +그렇게 하려면 위에서 설명한대로 사용자에게 `view` 및 `secret-reader` 접근 권한을 +부여하되, 클러스터롤바인딩을 사용한다. + +```console +$ kubectl create clusterrolebinding sam-view + --clusterrole view \​ + --user sam + +$ kubectl create clusterrolebinding sam-secret-reader + --clusterrole secret-reader \​ + --user sam +``` + +## 추가적인 고려사항 + +위에 표시된 예는 쿠버네티스와 함께 제공되는 기본 클러스터롤을 +활용한다. 사용자에게 접근 권한이 부여된 리소스를 더 세밀하게 +제어하려면 고유한 사용자 지정 역할 및 클러스터롤 생성에 대한 +[쿠버네티스 문서](https://kubernetes.io/docs/reference/access-authn-authz/rbac/)를 +참조하자. diff --git a/content/ko/docs/topics/registries.md b/content/ko/docs/topics/registries.md new file mode 100644 index 0000000000..eccaf516ce --- /dev/null +++ b/content/ko/docs/topics/registries.md @@ -0,0 +1,236 @@ +--- +title: "레지스트리" +description: "차트 배포를 위한 OCI 사용법을 설명한다." +weight: 7 +--- + +헬름 3는 패키지 배포를 위해 OCI를 지원한다. 차트 패키지는 OCI 기반 레지스트리 간에 +저장 및 공유할 수 있다. + +## OCI 지원 활성화 + +현재 OCI 지원은 *실험적(experimental)* 으로 간주되고 있다. + +아래에서 기술된 명령들을 사용하려면 환경에서 `HELM_EXPERIMENTAL_OCI` 변수를 설정하자: + +```console +export HELM_EXPERIMENTAL_OCI=1 +``` + +## 레지스트리 실행 + +테스트 목적으로 레지스트리를 시작하는 것은 간단하다. 도커를 설치한 경우, 다음 명령어를 +실행하자. + +```console +docker run -dp 5000:5000 --restart=always --name registry registry +``` + +이렇게 하면 `localhost:5000`에서 레지스트리 서버가 시작될 것이다. + +`docker logs -f registry`를 사용하여 로그를 확인하고 `docker rm -f registry`를 +사용하여 중지하자. + +스토리지를 보존하려면 위의 명령에 `-v $(pwd)/registry:/var/lib/registry`를 +추가하자. + +자세한 설정 옵션은 [해당 문서](https://docs.docker.com/registry/deploying/)를 +참조하자. + +### 인증 + +레지스트리에 인증을 활성화하려면, 다음과 같이 해보자. + +먼저 사용자 이름과 비밀번호로 `auth.htpasswd` 파일을 만들자. + +```console +htpasswd -cB -b auth.htpasswd myuser mypass +``` + +그런 다음, 서버를 시작하여 해당 파일을 마운트하고 `REGISTRY_AUTH` 환경 변수를 +지정하자. + +```console +docker run -dp 5000:5000 --restart=always --name registry \ + -v $(pwd)/auth.htpasswd:/etc/docker/registry/auth.htpasswd \ + -e REGISTRY_AUTH="{htpasswd: {realm: localhost, path: /etc/docker/registry/auth.htpasswd}}" \ + registry +``` + +## 레지스트리 작업 명령어 + +`helm registry`와 `helm chart` 명령어로 레지스트리와 로컬 캐시에 대한 작업을 할 수 있다. + +### `registry` 하위 명령어 + +#### `login` + +레지스트리에 로그인 (암호 수동 입력) + +```console +$ helm registry login -u myuser localhost:5000 +Password: +Login succeeded +``` + +#### `logout` + +레지스트리에서 로그아웃 + +```console +$ helm registry logout localhost:5000 +Logout succeeded +``` + +### `chart` 하위 명령어 + +#### `save` + +로컬 캐시에 차트 디렉토리를 저장 + +```console +$ helm chart save mychart/ localhost:5000/myrepo/mychart:2.7.0 +ref: localhost:5000/myrepo/mychart:2.7.0 +digest: 1b251d38cfe948dfc0a5745b7af5ca574ecb61e52aed10b19039db39af6e1617 +size: 2.4 KiB +name: mychart +version: 0.1.0 +2.7.0: saved +``` + +#### `list` + +저장된 모든 차트 나열 + +```console +$ helm chart list +REF NAME VERSION DIGEST SIZE CREATED +localhost:5000/myrepo/mychart:2.7.0 mychart 2.7.0 84059d7 454 B 27 seconds +localhost:5000/stable/acs-engine-autoscaler:2.2.2 acs-engine-autoscaler 2.2.2 d8d6762 4.3 KiB 2 hours +localhost:5000/stable/aerospike:0.2.1 aerospike 0.2.1 4aff638 3.7 KiB 2 hours +localhost:5000/stable/airflow:0.13.0 airflow 0.13.0 c46cc43 28.1 KiB 2 hours +localhost:5000/stable/anchore-engine:0.10.0 anchore-engine 0.10.0 3f3dcd7 34.3 KiB 2 hours +... +``` + +#### `export` + +디렉토리로 차트 내보내기 + +```console +$ helm chart export localhost:5000/myrepo/mychart:2.7.0 +ref: localhost:5000/myrepo/mychart:2.7.0 +digest: 1b251d38cfe948dfc0a5745b7af5ca574ecb61e52aed10b19039db39af6e1617 +size: 2.4 KiB +name: mychart +version: 0.1.0 +Exported chart to mychart/ +``` + +#### `push` + +원격지로 차트 밀어주기(push) + +```console +$ helm chart push localhost:5000/myrepo/mychart:2.7.0 +The push refers to repository [localhost:5000/myrepo/mychart] +ref: localhost:5000/myrepo/mychart:2.7.0 +digest: 1b251d38cfe948dfc0a5745b7af5ca574ecb61e52aed10b19039db39af6e1617 +size: 2.4 KiB +name: mychart +version: 0.1.0 +2.7.0: pushed to remote (1 layer, 2.4 KiB total) +``` + +#### `remove` + +캐시에서 차트 제거하기 + +```console +$ helm chart remove localhost:5000/myrepo/mychart:2.7.0 +2.7.0: removed +``` + +#### `pull` + +원격지에서 차트 가져오기(pull) + +```console +$ helm chart pull localhost:5000/myrepo/mychart:2.7.0 +2.7.0: Pulling from localhost:5000/myrepo/mychart +ref: localhost:5000/myrepo/mychart:2.7.0 +digest: 1b251d38cfe948dfc0a5745b7af5ca574ecb61e52aed10b19039db39af6e1617 +size: 2.4 KiB +name: mychart +version: 0.1.0 +Status: Downloaded newer chart for localhost:5000/myrepo/mychart:2.7.0 +``` + +## 내 차트는 어디 있나? + +위의 명령어들을 사용하여 저장된 차트는 파일 시스템에 캐시될 것이다. + +[OCI 이미지 레이아웃 +사양](https://github.com/opencontainers/image-spec/blob/main/image-layout.md)은 +파일시스템 레이아웃에 엄격하게 적용되는데, 예를 들면 다음과 같다. +```console +$ tree ~/Library/Caches/helm/ +/Users/myuser/Library/Caches/helm/ +└── registry + ├── cache + │   ├── blobs + │   │   └── sha256 + │   │   ├── 1b251d38cfe948dfc0a5745b7af5ca574ecb61e52aed10b19039db39af6e1617 + │   │   ├── 31fb454efb3c69fafe53672598006790122269a1b3b458607dbe106aba7059ef + │   │   └── 8ec7c0f2f6860037c19b54c3cfbab48d9b4b21b485a93d87b64690fdb68c2111 + │   ├── index.json + │   ├── ingest + │   └── oci-layout + └── config.json +``` + +모든 헬름 차트 매니페스트에 대한 참조(ref)를 포함하는 예시 index.json: + +```console +$ cat ~/Library/Caches/helm/registry/cache/index.json | jq +{ + "schemaVersion": 2, + "manifests": [ + { + "mediaType": "application/vnd.oci.image.manifest.v1+json", + "digest": "sha256:31fb454efb3c69fafe53672598006790122269a1b3b458607dbe106aba7059ef", + "size": 354, + "annotations": { + "org.opencontainers.image.ref.name": "localhost:5000/myrepo/mychart:2.7.0" + } + } + ] +} +``` + +헬름 차트 매니페스트 예시 ('mediaType' 필드를 주목하자): + +```console +$ cat ~/Library/Caches/helm/registry/cache/blobs/sha256/31fb454efb3c69fafe53672598006790122269a1b3b458607dbe106aba7059ef | jq +{ + "schemaVersion": 2, + "config": { + "mediaType": "application/vnd.cncf.helm.config.v1+json", + "digest": "sha256:8ec7c0f2f6860037c19b54c3cfbab48d9b4b21b485a93d87b64690fdb68c2111", + "size": 117 + }, + "layers": [ + { + "mediaType": "application/tar+gzip", + "digest": "sha256:1b251d38cfe948dfc0a5745b7af5ca574ecb61e52aed10b19039db39af6e1617", + "size": 2487 + } + ] +} +``` + +## 차트 저장소에서 마이그레이션 + +클래식 [차트 저장소]({{< ref path="chart_repository.md" lang="ko" >}}) (index.yaml 기반 저장소)에서 마이그레이션하는 작업은 `helm fetch` (헬름 2 CLI), `helm +chart save`, `helm chart push` 정도로 간단하다. diff --git a/content/ko/docs/topics/release_policy.md b/content/ko/docs/topics/release_policy.md new file mode 100644 index 0000000000..f46d41b24d --- /dev/null +++ b/content/ko/docs/topics/release_policy.md @@ -0,0 +1,52 @@ +--- +title: "릴리스 스케줄 정책" +description: "헬름의 출시 스케줄 정책을 설명한다." +--- + +사용자를 위해 헬름은 사전에 출시 날짜를 정의하고 발표한다. +이 문서는 헬름의 출시 스케줄을 관리하는 정책을 설명한다. + +## 유의적 버전 + +헬름 버전은 `x.y.z` 로 표시된다. 여기서 `x` 는 주 버전, `y` 는 +부 버전, `z` 는 패치 버전으로서 [유의적 버전](https://semver.org/spec/v2.0.0.html)을 +따른 것이다. + +## 패치 릴리스 + +패치 릴리스는 사용자에게 버그 수정 및 보안 수정을 제공한다. 새로운 기능은 포함되어 +있지 않다. + +최신 부/주 릴리스와 관련된 새 패치 릴리스는 일반적으로 한 달에 한 번, +각 달의 두 번째 수요일에 나온다. + +우선순위가 높은 회귀 또는 보안 문제를 수정하는 패치 릴리스는 필요시마다 +나올 수 있다. + +이전 릴리스 이후 새 콘텐츠가 없는 경우 그 달에는 릴리스가 나오지 +않는다. + +## 부 릴리스 + +부 릴리스에는 보안 및 버그 수정과 새로운 기능이 포함되어 있다. +API 및 CLI 사용법에 대해서는 하위호환된다. + +쿠버네티스 릴리스에 맞추기 위해 부 헬름 릴리스는 4개월마다 나온다. +(1년에 릴리스 3개) + +필요한 경우 추가 부 릴리스가 나올 수도 있지만 발표된 릴리스가 +7일 이내가 아니라면 발표된 향후 릴리스의 일정에 영향을 주지는 +않는다. + +릴리스가 게시됨과 동시에 다음 부 릴리스 날짜가 발표되고 헬름 메인 웹페이지에 +게시된다. + +## 주 릴리스 + +주 릴리스에는 단절적(breaking) 변경이 포함되어 있다. 이러한 출시는 드물지만 +때로는 새로운 방향으로 헬름을 계속 진화시켜 나가기 위해 +필요하다. + +주 릴리스는 계획하기 어려울 수 있다. 이를 염두에 두고 최종 릴리스 +날짜는 해당 릴리스의 첫 번째 베타 버전이 제공될 때만 +선택되고 발표된다. diff --git a/content/ko/docs/topics/v2_v3_migration.md b/content/ko/docs/topics/v2_v3_migration.md new file mode 100644 index 0000000000..9d443b7c59 --- /dev/null +++ b/content/ko/docs/topics/v2_v3_migration.md @@ -0,0 +1,128 @@ +--- +title: "헬름 v2를 v3로 마이그레이션" +description: "헬름 v2를 v3로 마이그레이션하는 방법을 배운다." +weight: 13 +--- + +이 가이드에서는 헬름 v2를 v3로 마이그레이션하는 방법을 보여준다. +헬름 v2가 설치되어 있어야 하며, 하나 이상의 클러스터에서 릴리스가 관리되어야 한다. + +## 헬름 3 변경사항 개요 + +헬름 2 에서 3로의 변경사항 전체 목록은 [FAQ](https://v3.helm.sh/docs/faq/#changes-since-helm-2) +에 작성되어 있다. 다음은 +마이그레이션 준비 및 작업간에 사용자가 알아야 할 몇 가지 변경 사항에 +대한 요약이다: + +1. Tiller 제거: + - 클라이언트/서버 구조는 클라이언트/라이브러리 아키텍처로 대체됨 (`helm` 바이너리만 + 해당) + - 보안 서비스는 이제 사용자 단위로 제공됨 (쿠버네티스 사용자 클러스터 보안에 + 위임) + - 릴리스는 이제 클러스터 내의 시크릿으로 저장되고 릴리스 객체 메타 + 데이터도 변경됨 + - 릴리스는 더 이상 Tiller 네임스페이스가 아니라 릴리스 네임스페이스 + 기반으로 유지됨 +2. 차트 저장소 업데이트: + - `helm search` 는 이제 로컬 저장소 검색과 헬름 허브에 대한 검색 쿼리를 + 모두 지원함 +3. 다음의 사양 변경에 대하여 차트 apiVersion 이 "v2"로 증가: + - 동적으로 연결된 차트 의존성이 `Chart.yaml` 로 이동됨 + (`requirements.yaml` 제거되고, 요구사항(requirements) --> 의존성(dependencies)으로 변경) + - 라이브러리 차트(헬퍼/공통 차트)를 동적으로 연결된 차트 + 의존성으로 추가 가능 + - 차트를 `application` 또는 `library` 차트로 + 정의하는 `type` 메타 데이터 필드를 가짐. + 기본값은 application이며 렌더링 및 설치 가능하다는 의미 + - 헬름 2 차트 (apiVersion=v1) 도 여전히 설치 가능함 +4. XDG 디렉토리 사양 추가: + - 헬름 홈이 제거되고 구성 파일 저장을 위한 XDG 디렉토리 + 사양으로 대체 + - 헬름 초기화 불필요 + - `helm init` 와 `helm home` 명령어 제거 +5. 추가 변경 사항: + - Helm 설치/설정 단순화: + - 헬름 클라이언트 (헬름 바이너리) 만 있으면 됨 (Tiller 불필요) + - Run-as-is 패러다임 + - `local` 또는 `stable` 저장소는 기본적으로 미설정 + - `crd-install` 훅은 제거되고, + 차트 내 모든 CRD가 정의되어 있고 차트 렌더링 전에 설치되는 + `crds` 디렉토리로 대체됨 + - `test-failure` 훅 어노테이션 값은 제거되고, `test-success`는 + 사용 중단(deprecated). 대신 `test` 를 사용하자 + - 제거/교체/추가 된 명령어: + - delete --> uninstall : 기본적으로 모든 릴리스 기록 제거 + (예전에는 `--purge` 옵션이 필요했음) + - fetch --> pull + - home (제거됨) + - init (제거됨) + - install: 릴리스 이름 또는 `--generate-name` 인수 필요 + - inspect --> show + - reset (제거됨) + - serve (제거됨) + - template: `-x`/`--execute` 인수의 이름이 `-s`/`--show-only` 로 변경 + - upgrade: 릴리스당 저장되는 최대 리비젼 수를 제한하는 인수 `--history-max` 추가됨 + (0은 무제한) + - 헬름 3 Go 라이브러리는 많은 변경을 거쳤으며, 헬름 2 라이브러리와는 + 호환되지 않음 + - 릴리스 바이너리가 이제 `get.helm.sh` 에서 호스팅됨 + +## 마이그레이션 사용 사례 + +마이그레이션 사용 사례는 다음과 같다: + +1. 동일 클러스터를 관리하는 헬름 v2 및 v3: + - 이 사용 사례는 헬름 v2 를 단계적으로 제거하려는 경우에만 권장되며 + v2로 배포한 릴리스를 관리하는 데 v3가 필요한 것은 아니다. + 배포되는 모든 새 릴리스는 v3 에서 수행해야 하며, + 기존에 v2 로 배포된 릴리스는 v2 에서만 업데이트/제거된다. + - 헬름 v2 와 v3 는 같은 클러스터를 원활하게 관리할 수 있다. + 헬름 버전들은 동일 또는 개별 시스템에 설치될 수 있다. + - 만약 동일한 시스템에 헬름 v3를 설치하는 경우, 헬름 v2 + 클라이언트를 제거할 준비가 될 때까지 두 클라이언트 버전이 공존할 수 있도록 추가 + 작업을 수행해야 한다. 충돌을 피하기 위해 + 헬름 v3 바이너리의 이름을 바꾸거나 다른 폴더에 넣도록 한다. + - 그밖에는 다음과 같은 구별에 따라 + 두 버전 간에 충돌이 발생하지 않는다. + - v2 및 v3 릴리스 (이력) 저장소는 서로 독립적이다. 변경 사항으로는 + 스토리지용 쿠버네티스 리소스와, 리소스에 포함된 릴리스 객체 메타 데이터가 있다. + 릴리스는 또한 Tiller 네임스페이스를 사용하는 대신 사용자별 네임스페이스에 + 있게 된다 (예: v2의 기본 Tiller 네임스페이스는 kube-system). + v2는 Tiller 네임스페이스 및 `TILLER` 소유권 아래의 "ConfigMaps" + 또는 "Secrets" 를 사용한다. + v3는 사용자 네임스페이스에 있는 "Secrets" 과 `helm` 소유권을 사용한다. + 릴리스는 v2 및 v3에서 모두 증가한다. + - 유일한 문제는 쿠버네티스 클러스터 범위의 + 리소스(예: `clusterroles.rbac`)가 차트에 정의된 경우이다. + 이런 경우 리소스가 충돌할 수 있으므로 네임스페이스에서 고유하더라도 v3 배포는 실패하게 된다. + - v3 구성은 더이상 `$HELM_HOME` 을 사용하지 않고 대신 XDG 디렉토리 사양을 + 사용한다. 또한 필요에 따라 즉시 생성된다. 따라서 v2 구성과는 + 독립적이다. 이것은 동일한 시스템에 두 버전이 + 설치된 경우에만 적용된다. + +2. 헬름 v2 에서 Helm v3 로 마이그레이션: + - 이 사용 사례는 헬름 v3 에서 기존 헬름 v2 릴리스를 관리하려는 경우에 + 적용된다. + - 헬름 v2 클라이언트에 대해서는 다음과 같은 부분에 유의해야 한다: + - 헬름 v2 클라이언트 1개에서 다수의 쿠버네티스 클러스터 관리 가능 + - 클러스터에 대해 헬름 v2 클라이언트 1 개가 여러 개의 Tiller 인스턴스에 연결 가능 + - 이는 릴리스가 Tiller 및 해당 네임스페이스에 의해 클러스터에 + 배치되므로 마이그레이션 할 때 이를 알고 있어야 한다는 것을 의미한다. + 따라서 헬름 v2 클라이언트 인스턴스에서 관리하는 각 클러스터 + 및 각 Tiller 인스턴스에 대한 마이그레이션을 알고 있어야 한다. + - 권장되는 데이터 마이그레이션 절차는 다음과 같다: + 1. v2 데이터 백업 + 2. 헬름 v2 구성 마이그레이션 + 3. 헬름 v2 릴리스 마이그레이션 + 4. 헬름 v3가 모든 헬름 v2 데이터(헬름 v2 클라이언트 인스턴스의 모든 + 클러스터 및 Tiller 인스턴스에 대한)를 예상한대로 잘 관리한다고 확신할 경우, + 헬름 v2 데이터 소거 + - 마이그레이션 과정은 헬름 v3 [2to3](https://github.com/helm/helm-2to3) 플러그인으로 + 자동화된다. + +## 참조 + + - 헬름 v3 [2to3](https://github.com/helm/helm-2to3) 플러그인 + - `2to3` 플러그인 사용법을 예제와 함께 설명하는 + 블로그 [게시글](https://helm.sh/blog/migrate-from-helm-v2-to-helm-v3/) + diff --git a/content/ko/docs/topics/version_skew.md b/content/ko/docs/topics/version_skew.md new file mode 100644 index 0000000000..189b22a0ec --- /dev/null +++ b/content/ko/docs/topics/version_skew.md @@ -0,0 +1,69 @@ +--- +title: "헬름 버전 지원 정책" +description: "헬름의 패치 릴리스 정책과 헬름, 헬름과 쿠버네티스 간에 지원되는 최대의 버전 차이를 설명" +--- + +이 문서는 헬름과 쿠버네티스 간에 지원되는 최대의 버전 차이를 +설명한다. + +## 지원되는 버전 + +헬름 버전들은 `x.y.z` 로 표현된다. 여기서 `x` 는 주 버전, +`y` 는 부 버전, z는 패치 버전으로 [유의적 +버전](https://semver.org/spec/v2.0.0.html) 을 따른다. + +헬름 프로젝트는 최신 부 릴리스에 대한 릴리스 브랜치를 유지한다. +보안 픽스를 포함하여 적용가능한 픽스는 심각도와 타당성에 따라 +릴리스 브랜치로 선별 적용된다. 패치 릴리스는 필요한 경우 해당 브랜치에서 +제외된다. 이 결정은 릴리스 관리자가 담당한다. + +## 지원되는 버전 차이(skew) + +헬름의 새 버전이 출시 되면, 쿠버네티스의 특정 부 버전에 +대해 컴파일된다. 예를 들어 헬름 3.0.0은 쿠버네티스 1.16.2 클라이언트를 사용하여 +쿠버네티스와 상호작용하므로 쿠버네티스 1.16 과 호환된다고 할 수 있다. + +헬름 3부터는, 헬름은 그에 대응하여 컴파일되는 쿠버네티스 `n-3` 버전과 호환되는 +것으로 간주된다. 쿠버네티스 마이너 버전 간의 차이로 인해 헬름 2의 +지원 정책은 약간 더 엄격한데, 쿠버네티스의 `n-1` 버전과 호환되는 것으로 +간주한다. + +예를 들어, 쿠버네티스 1.17 클라이언트 API 에 대응하여 컴파일된 +헬름 3 버전을 사용하는 경우, 쿠버네티스 1.17, 1.16, 1.15 +및 1.14 와 함께 사용하는 것이 안전할 것이다. 쿠버네티스 1.16 클라이언트 +API 에 대해 컴파일 된 헬름 2 버전을 사용하는 경우, +쿠버네티스 1.16 및 1.15 와 함께 사용하는 것이 안전할 것이다. + +헬름은 상위호환성을 보장하지 않으므로, 대응하여 컴파일된 +버전보다 더 높은 쿠버네티스 버전에서 +헬름을 사용하는 것은 권장되지 않는다. + +만약 지원하지 않는 쿠버네티스 버전에서 헬름을 사용하고자 하는 경우, +사용자는 위험을 감수하고 사용하게 된다. + +클러스터와 호환되는 헬름 버전을 확인하려면 아래의 표를 +참조하자. + +| 헬름 버전 | 지원하는 쿠버네티스 버전 | +|--------------|-------------------------------| +| 3.3.x | 1.18.x - 1.15.x | +| 3.2.x | 1.18.x - 1.15.x | +| 3.1.x | 1.17.x - 1.14.x | +| 3.0.x | 1.16.x - 1.13.x | +| 2.16.x | 1.16.x - 1.15.x | +| 2.15.x | 1.15.x - 1.14.x | +| 2.14.x | 1.14.x - 1.13.x | +| 2.13.x | 1.13.x - 1.12.x | +| 2.12.x | 1.12.x - 1.11.x | +| 2.11.x | 1.11.x - 1.10.x | +| 2.10.x | 1.10.x - 1.9.x | +| 2.9.x | 1.10.x - 1.9.x | +| 2.8.x | 1.9.x - 1.8.x | +| 2.7.x | 1.8.x - 1.7.x | +| 2.6.x | 1.7.x - 1.6.x | +| 2.5.x | 1.6.x - 1.5.x | +| 2.4.x | 1.6.x - 1.5.x | +| 2.3.x | 1.5.x - 1.4.x | +| 2.2.x | 1.5.x - 1.4.x | +| 2.1.x | 1.5.x - 1.4.x | +| 2.0.x | 1.4.x - 1.3.x | diff --git a/content/pt/docs/_index.md b/content/pt/docs/_index.md new file mode 100644 index 0000000000..62cca27973 --- /dev/null +++ b/content/pt/docs/_index.md @@ -0,0 +1,27 @@ +--- +title: "Início da Documentação" +description: "Tudo o que você precisa saber em como essa documentação é organizada." +--- + +# Bem-vindo + +Bem-vindo a documentação do [Helm](https://helm.sh/). Helm é um gerenciador de +pacotes para o Kubernetes, e você pode ler mais sobre o seu contexto detalhado no +[Relatório da Jornada do Projeto Helm +na CNCF](https://www.cncf.io/cncf-helm-project-journey/). + +# Como essa documentação é organizada? + +O Helm tem uma vasta documentação. Uma visão geral em alto nível de como ela é organizada +lhe ajudará por onde procurar certas informações: + +- [Tutoriais](intro) pegam na sua mão e lhe guiam por uma série de passos para criar + seu primeiro Chart no Helm. Comece por aqui se você é novo no Helm. +- [Guias Temáticos](topics) abordam os principais tópicos e conceitos em alto nível, + além de prover contexto e explicações utéis sobre o Helm. +- [Guias da Comunidade](community) abordam tópicos centrados ao redor + da comunidade do Helm. Comece por aqui se você quiser se informar sobre o + processo de desenvolvimento do Helm em si e como contribuir com o projeto. +- [Guias de Instruções](howto) são receitas prontas. Eles lhe guiam através dos passos + envolvidos na resolução dos principais problemas e casos de uso. São mais avançados + que tutoriais e demandam conhecimento prévio de como o Helm funciona. diff --git a/content/pt/docs/community/_index.md b/content/pt/docs/community/_index.md new file mode 100644 index 0000000000..c989f17f12 --- /dev/null +++ b/content/pt/docs/community/_index.md @@ -0,0 +1,9 @@ +--- +title: "Comunidade" +weight: 7 +--- + +# Guias da Comunidade + +Aprenda aqui sobre o processo de desenvolvimento do projeto Helm em si +e como você pode contribuir. diff --git a/content/pt/docs/glossary/_index.md b/content/pt/docs/glossary/_index.md new file mode 100644 index 0000000000..1ad3aeca17 --- /dev/null +++ b/content/pt/docs/glossary/_index.md @@ -0,0 +1,166 @@ +--- +title: "Glossário" +description: "Termos utilizados para descrever a arquitetura do Helm." +weight: 9 +--- + +# Glossário + +## Chart + +É um pacote Helm que contém as informações necessárias para instalar +uma série de recursos e manifestos do Kubernetes em um cluster. + +Os Charts contém um arquivo `Chart.yaml` bem como _templates_ dos manifestos, +valores padrão (`values.yaml`), e outras dependêncas. + +Os Charts são desenvolvidos dentro de uma estrutura de diretório bem definida, +e depois empacotados em um formato de arquivo chamado _chart archive_. + +## Chart Archive + +Um _chart archive_ é um Chart compactado, em tar e gzip, (e opcionalmente +assinado). + +## Dependência de Charts (Subcharts) + +Charts podem depender de outros Charts. Há duas maneiras que dependência de Charts +podem ocorrer: + +- _Soft dependency_: Um Chart pode não funcionar se um outro Chart não estiver instalado + no cluster. O Helm não fornece ferramental para resolver esse caso. Nesse + cenário as dependências são gerenciadas separadamente. +- _Hard dependency_: Um Chart pode conter (dentro do diretório `charts/`) + outro Chart no qual seja dependente. Nesse caso, ao instalar o Chart também + será instalado todas as suas dependências. Os Charts e suas dependências são gerenciadas + como uma coleção. + +Quando um Chart é empacotado (via `helm package`) todas as suas +_hard dependencies_ são agrupadas com ele. + +## Versão do Chart + +Charts são versionados de acordo com as [especificações da SemVer 2](https://semver.org). +Um número de versão é necessário para cada Chart. + +## Chart.yaml + +Informações sobre o Chart são armazenadas num arquivo específico chamado `Chart.yaml`. +Cada Chart deve ter esse arquivo. + +## Helm (e o cliente helm) + +Helm é o gerenciador de pacotes para o Kubernetes. Assim como gerenciadores de +pacotes facilitam a instalação de ferramentas para sistemas operacionais, o Helm +facilita a instalação de aplicações nos clusters Kubernetes. + +Enquanto _Helm_ (em maiúsculo) é o nome do projeto, a ferramenta de linha de comando +também se chama `helm`. Por convenção utiliza-se _Helm_ em maiúsculo ao falar do +projeto. Quando se faz referência ao cliente utiliza-se _helm_ em mínusculo. + +## Arquivos de configuração do Helm (XDG) + +O Helm armazena suas configurações em arquivos de diretórios XDG. Esses diretórios +são criados quando o `helm` é executado pela primeira vez. + +## Kube Config (KUBECONFIG) + +O cliente helm tenta encontrar as configurações do cluster Kubernetes utilizando +como base o arquivo no formato _Kube config_. Por padrão o helm tentará localizá-lo +no mesmo local que o `kubectl` o cria (`$HOME/.kube/config`). + +## Lint (Formatação de Charts) + +Formatar um Chart significa validar se este segue as converções e requerimentos +padrões de um Chart do Helm. O Helm tem ferramentas de formatação através do comando +`helm lint`. + +## Linhagem (Arquivo de Linhagem) + +Os Charts Helm podem ser acompanhados de _arquivos de linhagem_ o qual provêm informações +a cerca da origem do Chart e o que ele contém. + +Arquivos de Linhagem fazem parte do histórico de segurança do Helm. Uma linhagem +contém um hash criptografado do arquivo _chart archive_, dados do Chart.yaml, e, +um bloco de assinatura (um bloco "clearsign" OpenPGP). Quando utilizados em conjuto +com uma chave habilita o usuário a: + +- Validar se o Chart foi assinado por uma entidade acreditada +- Validar se o arquivo do Chart não foi modificado +- Validar o conteúdo dos metadados do Chart (`Chart.yaml`) +- Correlacionar rapidamente o Chart com os seus dados de linhagem + +Arquivos de linhagem tem a extensão `.prov`, e podem ser servidos a partir de um +_repositório de Charts_ ou qualquer outro servidor HTTP. + +## Release + +Quando um Chart é instalado, a biblioteca do Helm cria uma _release_ para monitorar +aquela instalação em particular. + +Um mesmo Chart pode ser instalado diversas vezes em um mesmo cluster e criar _releases_ +diferentes. Por exemplo, uma pessoa pode instalar três bancos de dados PostgreSQL, +a partir de um mesmo Chart, rodando o comando `helm install` três vezes com diferentes +nomes para cada _release_. + +## Número da _Release_ (Versão da _Release_) + +Uma única _release_ pode ser atualizada diversas vezes. Um contador sequencial +é utilizado para monitorar as alterações da _release_. Após o primerio `helm install` +do Chart, a _release_ terá um número de _release_ igual a 1. A cada vez que uma release +for atualizada ou regredida, a versão da release será **incrementada**. + +## Regressão (Rollback) + +Uma _release_ pode ser atualizada para uma nova configuração do chart. Contudo é +possível regredir a uma versão anterior da release, uma vez que o histórico de +_releases_ é armazenado. Essa operação é realizada com o comando `helm rollback`. + +Importante: uma _release_ regredida recebe um novo número de _release_. + +| Operação | Número da Release | +|------------|------------------------------------------------------| +| install | release 1 | +| upgrade | release 2 | +| upgrade | release 3 | +| rollback 1 | release 4 (mantendo a configuração da release 1) | + +A tabela acima ilustra como as versões de release são incrementadas entre as +operações de instalação, atualização e regressão. + +## Biblioteca do Helm (SDK) + +A biblioteca do Helm (SDK) refere-se ao código em Go que interage diretamente com +o API Server do Kubernetes para instalar, atualizar, buscar e remover recursos +do Kubernetes. Ela pode ser importada em um projeto para utilizar o Helm como cliente +ao invés da CLI. + +## Repositório (Repo, Repositório de Charts) + +Os Charts do Helm podem ser armazenados em servidores dedicados HTTP chamados +_repositório de Charts_ (_repositórios_, ou somente _repos_). + +Um repositório de Charts é simplesmente um servidor HTTP que retorna um arquivo `index.yaml` +o qual descreve um grupo de Charts e identifica onde cada Chart pode ser baixado. +(Muitos repositórios também hospedam os Charts para serem baixados, além do arquivo +`index.yaml`.) + +O cliente helm pode apontar para zero ou mais repositórios de Charts. Por padrão +o cliente helm não é pré-configurado com nenhum repositório. Um repositório pode +ser adicionado a qualquer momento através do comando `helm repo add`. + +## Valores de Configuração (values.yaml) + +Valores de configuração são uma forma de sobrescrever valores padrão dos templates +com seu próprio conteúdo. + +Os Charts do Helm são "parametrizados", o que significa dizer que um desenvolvedor +pode expôr configurações padrão que podem ser sobrescritas durante a instalação. +Por exemplo, um chart pode expôr o campo `username` que permite configurar um nome +de usuário para um serviço. + +Essas variáveis expostas são chamados de _values_ no linguajar do Helm. + +Os valores podem ser configurados durante as operações de `helm install` e +`helm upgrade`, tanto passando-as diretamente como argumentos de linha de comando, +ou, usando um arquivo `values.yaml`. diff --git a/content/pt/docs/helm/_index.md b/content/pt/docs/helm/_index.md new file mode 100644 index 0000000000..fcc5188e93 --- /dev/null +++ b/content/pt/docs/helm/_index.md @@ -0,0 +1,11 @@ +--- +title: "Comandos Helm" +description: "Documentação para a lista completa de comandos da CLI do helm." +weight: 6 +slug: helm +--- + +# Comandos Helm + +Aqui você encontrará uma lista de comandos da CLI do helm, com informações sobre +seu uso. diff --git a/content/pt/docs/helm/helm.md b/content/pt/docs/helm/helm.md new file mode 100644 index 0000000000..6d1c7a1ae6 --- /dev/null +++ b/content/pt/docs/helm/helm.md @@ -0,0 +1,101 @@ +--- +title: "Helm" +--- + +## helm + +O gerenciador de pacotes para o Kubernetes. + +### Sinopse + +O gerenciador de pacotes para o Kubernetes. + +Comandos comuns para o Helm: + +- helm search: busca por Charts +- helm pull: baixa um Chart em seu diretório local +- helm install: aplica um Chart no Kubernetes +- helm list: lista as _releases_ dos Charts + +Variáveis de ambiente: + +| Nome | Descrição | +|------------------------------------|------------------------------------------------------------------------------------------------------------| +| $HELM_CACHE_HOME | configura um local alternativo para armazenamento dos arquivos de cache. | +| $HELM_CONFIG_HOME | configura um local alternativo para armazenamento para as configurações do Helm. | +| $HELM_DATA_HOME | configura um local alternativo para armazenamento os dados do Helm. | +| $HELM_DEBUG | indica se o Helm rodará ou não em modo debug | +| $HELM_DRIVER | configura o driver de armazenamento backend. Valores usados: configmap, secret, memory, postgres. | +| $HELM_DRIVER_SQL_CONNECTION_STRING | configura a string de conexão a ser utilizada pelo driver de armazenamento SQL. | +| $HELM_MAX_HISTORY | configura o número máximo de _releases_ armazenadas no histórico do helm. | +| $HELM_NAMESPACE | configura o namespace usado para as operações do helm. | +| $HELM_NO_PLUGINS | desabilita os plugins. Configure HELM_NO_PLUGINS=1 para desabilitar os plugins. | +| $HELM_PLUGINS | configura o caminho para o diretório dos plugins. | +| $HELM_REGISTRY_CONFIG | configura o caminho para o arquivo de configuração do container registry. | +| $HELM_REPOSITORY_CACHE | configura o caminho para o diretório do repositório de cache. | +| $HELM_REPOSITORY_CONFIG | configura o caminho para o arquivo de repositórios. | +| $KUBECONFIG | configura um arquivo de configuração alternativo para o Kubernetes (por padrão "~/.kube/config"). | +| $HELM_KUBEAPISERVER | configura o Endpoint de Autenticação do Kubernetes API Server. | +| $HELM_KUBECAFILE | configura o arquivo do certificado de autoridade para o Kubernetes. | +| $HELM_KUBEASGROUPS | configura os Grupos que representarão as operações, sendo esta uma lista com itens separados por vírgula. | +| $HELM_KUBEASUSER | configura o Nome de Usuário que representará a operação. | +| $HELM_KUBECONTEXT | configura o nó do contexto do kubeconfig. | +| $HELM_KUBETOKEN | configura o Bearer KubeToken usado para autenticação. | + +O Helm armazena arquivos de cache, configuração, e dados de acordo com a seguinte ordem: + +- Se uma variável de ambiente HELM_*_HOME é configurada, ela será utilizada. +- Se não, os sistemas que suportam a especificação de diretório XDG utilizarão as variáveis XDG. +- Quando nenhum outro local é configurado como padrão, será utilizado um caminho baseado pelo sistema operacional. + +Por padrão, os diretórios padrões dependem do Sistema Operacional. Abaixo seguem os caminhos em diferentes SOs: + +| Sistema Operacional | Caminho do Cache | Caminho de Configuração | Caminho para os Dados | +|---------------------|---------------------------------|-------------------------------------|-------------------------------------| +| Linux | $HOME/.cache/helm | $HOME/.config/helm | $HOME/.local/share/helm | +| macOS | $HOME/Library/Caches/helm | $HOME/Library/Preferences/helm | $HOME/Library/helm | +| Windows | %TEMP%\helm | %APPDATA%\helm | %APPDATA%\helm | + + +### Opções + +``` + --debug exibe uma saída verbosa + -h, --help exibe ajuda para um comando do helm + --kube-apiserver string o endereço e porta do Kubernetes API server + --kube-as-group stringArray o grupo que representará essa operação, esse argumento pode ser repetido para indicar múltiplos grupos + --kube-as-user string o usuário que representará essa operação + --kube-ca-file string caminho para o certificado para conexão com o Kubernetes API server + --kube-context string nome do contexto do kubeconfig a ser usado + --kube-token string bearer token usado para autenticação + --kubeconfig string caminho para o arquivo kubeconfig + -n, --namespace string namespace para essa requisição + --registry-config string caminho para o arquivo de configuração do registry (default "~/.config/helm/registry.json") + --repository-cache string caminho para os índices "cacheados" no repositório (default "~/.cache/helm/repository") + --repository-config string caminho para o arquivo path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### Veja Também +* [helm completion](helm_completion.md) - gera os scripts de preenchimento automático (_autocompletion_) para o shell especificado. +* [helm create](helm_create.md) - cria um novo chart com um nome. +* [helm dependency]({{< relref path="/docs/helm/helm_dependency.md" lang="en" >}}) - gerencia as dependências dos Charts. +* [helm env]({{< relref path="/docs/helm/helm_env.md" lang="en" >}}) - exibe as informações de variáveis de ambiente do cliente helm. +* [helm get](helm_get.md) - recupera mais informações de uma dada _release_. +* [helm history]({{< relref path="/docs/helm/helm_history.md" lang="en" >}}) - recupera o histórico de uma _release_. +* [helm install](helm_install.md) - instala um Chart. +* [helm lint]({{< relref path="/docs/helm/helm_lint.md" lang="en" >}}) - verifica o Chart por potenciais problemas. +* [helm list]({{< relref path="/docs/helm/helm_list.md" lang="en" >}}) - lista as _releases_. +* [helm package]({{< relref path="/docs/helm/helm_package.md" lang="en" >}}) - empacota um diretório de um Chart em um Chart Archive. +* [helm plugin]({{< relref path="/docs/helm/helm_plugin.md" lang="en" >}}) - instala, lista, ou desinstala plugins do Helm. +* [helm pull]({{< relref path="/docs/helm/helm_pull.md" lang="en" >}}) - baixa um Chart de um repositório, e opcionalmente, descompacta-o em um diretório local. +* [helm repo]({{< relref path="/docs/helm/helm_repo.md" lang="en" >}}) - adiciona, lista, remove, atualiza, e indexa um repositório de Chart. +* [helm rollback]({{< relref path="/docs/helm/helm_rollback.md" lang="en" >}}) - faz a regressão (_roll back_) de uma _release_ para uma versão anterior. +* [helm search]({{< relref path="/docs/helm/helm_search.md" lang="en" >}}) - busca por uma palavra-chave entre os Charts. +* [helm show]({{< relref path="/docs/helm/helm_show.md" lang="en" >}}) - exibe as informações de um Chart. +* [helm status]({{< relref path="/docs/helm/helm_status.md" lang="en" >}}) - exibe o status de uma dada _release_. +* [helm template]({{< relref path="/docs/helm/helm_template.md" lang="en" >}}) - renderiza localmente os templates dos manifestos com os valores de configuração. +* [helm test]({{< relref path="/docs/helm/helm_test.md" lang="en" >}}) - roda os testes para uma _release_. +* [helm uninstall]({{< relref path="/docs/helm/helm_uninstall.md" lang="en" >}}) - desinstala uma _release_. +* [helm upgrade]({{< relref path="/docs/helm/helm_upgrade.md" lang="en" >}}) - atualiza uma _release_. +* [helm verify]({{< relref path="/docs/helm/helm_verify.md" lang="en" >}}) - verifica se um Chart em um dado caminho foi assinado e está válido. +* [helm version]({{< relref path="/docs/helm/helm_version.md" lang="en" >}}) - exibe as informações sobre a versão do cliente helm. \ No newline at end of file diff --git a/content/pt/docs/helm/helm_completion.md b/content/pt/docs/helm/helm_completion.md new file mode 100644 index 0000000000..c73973506b --- /dev/null +++ b/content/pt/docs/helm/helm_completion.md @@ -0,0 +1,42 @@ +--- +title: "Helm Completion (Preenchimento automático)" +--- + +## helm completion + +Gera scripts de preenchimento automático para um shell específico + +### Synopsis + +Gera scripts de preenchimento automático do Helm para um shell específico. + +### Options + +``` + -h, --help ajuda para o preenchimento automático +``` + +### Opções gerais + +``` + --debug exibe uma saída verbosa + -h, --help exibe ajuda para um comando do helm + --kube-apiserver string o endereço e porta do Kubernetes API server + --kube-as-group stringArray o grupo que representará essa operação, esse argumento pode ser repetido para indicar múltiplos grupos + --kube-as-user string o usuário que representará essa operação + --kube-ca-file string caminho para o certificado para conexão com o Kubernetes API server + --kube-context string nome do contexto do kubeconfig a ser usado + --kube-token string bearer token usado para autenticação + --kubeconfig string caminho para o arquivo kubeconfig + -n, --namespace string namespace para essa requisição + --registry-config string caminho para o arquivo de configuração do registry (padrão "~/.config/helm/registry.json") + --repository-cache string caminho para os índices "cacheados" no repositório (padrão "~/.cache/helm/repository") + --repository-config string caminho para o arquivo path to the file containing repository names and URLs (padrão "~/.config/helm/repositories.yaml") +``` + +### Veja Também + +* [helm](helm.md) - Helm, o gerenciador de pacotes para o Kubernetes. +* [helm completion bash](helm_completion_bash.md) - gera o script de preenchimento automático para o bash +* [helm completion fish](helm_completion_fish.md) - gera o script de preenchimento automático para o fish +* [helm completion zsh](helm_completion_zsh.md) - gera o script de preenchimento automático para o zsh diff --git a/content/pt/docs/helm/helm_completion_bash.md b/content/pt/docs/helm/helm_completion_bash.md new file mode 100644 index 0000000000..b0233fbb87 --- /dev/null +++ b/content/pt/docs/helm/helm_completion_bash.md @@ -0,0 +1,63 @@ +--- +title: "Helm Completion Bash" +--- + +## helm completion bash + +Gera scripts de preenchimento automático para o bash + +### Sinopse + +Gera scripts de preenchimento automático do Helm para o bash shell. + +Para carregar o script de preenchimento automático na sessão ativa do bash: + +``` +source < (helm completion bash) +``` + +Para carregar o script para cada nova sessão, execute uma vez: + +Linux: + +``` +helm completion bash > /etc/bash_completion.d/helm +``` +MacOS: + +``` +helm completion bash > /usr/local/etc/bash_completion.d/helm +``` + +Comando +``` +helm completion bash [argumentos] +``` + +### Opções + +``` + -h, --help ajuda para o preenchimento automático do bash +``` + +### Opções gerais + +``` + --debug exibe uma saída verbosa + -h, --help exibe ajuda para um comando do helm + --kube-apiserver string o endereço e porta do Kubernetes API server + --kube-as-group stringArray o grupo que representará essa operação, esse argumento pode ser repetido para indicar múltiplos grupos + --kube-as-user string o usuário que representará essa operação + --kube-ca-file string caminho para o certificado para conexão com o Kubernetes API server + --kube-context string nome do contexto do kubeconfig a ser usado + --kube-token string bearer token usado para autenticação + --kubeconfig string caminho para o arquivo kubeconfig + -n, --namespace string namespace para essa requisição + --registry-config string caminho para o arquivo de configuração do registry (padrão "~/.config/helm/registry.json") + --repository-cache string caminho para os índices "cacheados" no repositório (padrão "~/.cache/helm/repository") + --repository-config string caminho para o arquivo path to the file containing repository names and URLs (padrão "~/.config/helm/repositories.yaml") +``` + +### Veja também + +* [helm completion](helm_completion.md) - gera scripts de preenchimento automático para um shell específico diff --git a/content/pt/docs/helm/helm_completion_fish.md b/content/pt/docs/helm/helm_completion_fish.md new file mode 100644 index 0000000000..ace10463cb --- /dev/null +++ b/content/pt/docs/helm/helm_completion_fish.md @@ -0,0 +1,59 @@ +--- +title: "Helm Completion Fish" +--- + +## helm completion fish + +Gera scripts de preenchimento automático para o fish + +### Sinopse + +Gera scripts de preenchimento automático do Helm para o fish shell. + +Para carregar o script de preenchimento automático na sessão ativa do fish: + +``` +helm completion fish | source +``` + +Para carregar o script para cada nova sessão, execute uma vez: + +``` +helm completion fish > ~/.config/fish/completions/helm.fish +``` + +Será necessário iniciar um novo shell para que as modificações tenham efeito. + +Comando +``` +helm completion fish [argumentos] +``` + +### Opções + +``` + -h, --help ajuda para o preenchimento automático do fish + --no-descriptions desabilita descrições do preenchimento automático +``` + +### Opções gerais + +``` + --debug exibe uma saída verbosa + -h, --help exibe ajuda para um comando do helm + --kube-apiserver string o endereço e porta do Kubernetes API server + --kube-as-group stringArray o grupo que representará essa operação, esse argumento pode ser repetido para indicar múltiplos grupos + --kube-as-user string o usuário que representará essa operação + --kube-ca-file string caminho para o certificado para conexão com o Kubernetes API server + --kube-context string nome do contexto do kubeconfig a ser usado + --kube-token string bearer token usado para autenticação + --kubeconfig string caminho para o arquivo kubeconfig + -n, --namespace string namespace para essa requisição + --registry-config string caminho para o arquivo de configuração do registry (padrão "~/.config/helm/registry.json") + --repository-cache string caminho para os índices "cacheados" no repositório (padrão "~/.cache/helm/repository") + --repository-config string caminho para o arquivo path to the file containing repository names and URLs (padrão "~/.config/helm/repositories.yaml") +``` + +### Veja Também + +* [helm completion](helm_completion.md) - gera scripts de preenchimento automático para um shell específico diff --git a/content/pt/docs/helm/helm_completion_zsh.md b/content/pt/docs/helm/helm_completion_zsh.md new file mode 100644 index 0000000000..dd74a81f82 --- /dev/null +++ b/content/pt/docs/helm/helm_completion_zsh.md @@ -0,0 +1,57 @@ +--- +title: "Helm Completion Zsh" +--- + +## helm completion zsh + +Gera scripts de preenchimento automático para o zsh + +### Sinopse + +Gera scripts de preenchimento automático do Helm para o zsh shell. + +Para carregar o script de preenchimento automático na sessão ativa do zsh: + +``` +$ source < (helm completion zsh) +``` + +Para carregar o script para cada nova sessão, execute uma vez: + +``` +$ helm completion zsh > "${fpath[1]}/_helm" +``` + +Comando +``` +helm completion zsh [argumentos] +``` + +### Opções + +``` + -h, --help ajuda para o preenchimento automático do zsh + --no-descriptions desabilita descrições do preenchimento automático +``` + +### Opções gerais + +``` + --debug exibe uma saída verbosa + -h, --help exibe ajuda para um comando do helm + --kube-apiserver string o endereço e porta do Kubernetes API server + --kube-as-group stringArray o grupo que representará essa operação, esse argumento pode ser repetido para indicar múltiplos grupos + --kube-as-user string o usuário que representará essa operação + --kube-ca-file string caminho para o certificado para conexão com o Kubernetes API server + --kube-context string nome do contexto do kubeconfig a ser usado + --kube-token string bearer token usado para autenticação + --kubeconfig string caminho para o arquivo kubeconfig + -n, --namespace string namespace para essa requisição + --registry-config string caminho para o arquivo de configuração do registry (padrão "~/.config/helm/registry.json") + --repository-cache string caminho para os índices "cacheados" no repositório (padrão "~/.cache/helm/repository") + --repository-config string caminho para o arquivo path to the file containing repository names and URLs (padrão "~/.config/helm/repositories.yaml") +``` + +### Veja também + +* [helm completion](helm_completion.md) - gera scripts de preenchimento automático para um shell específico diff --git a/content/pt/docs/helm/helm_create.md b/content/pt/docs/helm/helm_create.md new file mode 100644 index 0000000000..e5905730bf --- /dev/null +++ b/content/pt/docs/helm/helm_create.md @@ -0,0 +1,58 @@ +--- +title: "Helm Create" +--- + +## helm create + +Cria um novo Chart com um dado nome + +### Sinopse + +Esse comando cria um diretório para o Chart, bem como os arquivos comuns +necessários para o Chart. + +Por exemplo, `helm create foo` criará uma estrutura de diretório como: + + foo/ + ├── .helmignore # Descreve os arquivos a serem ignorados durante o empacotamento do Chart. + ├── Chart.yaml # Informação sobre o seu Chart + ├── values.yaml # Valores padrão para os seus templates + ├── charts/ # Charts que este Chart depende + └── templates/ # Arquivos de template: deployment, service e outros manifestos + └── tests/ # Arquivos de teste + +`helm create` cria um diretório a partir do argumento passado. Se o diretório não +existir o helm tentará criá-lo. Se o destino já existir e tiver arquivos dentro +do diretório, os arquivos conflitantes serão sobrescritos e os demais serão mantidos. +``` +helm create NOME [argumentos] +``` + +### Opções + +``` + -h, --help ajuda para criação do Chart + -p, --starter string nome ou caminho absoluto para a base inicial do Helm +``` + +### Opções gerais + +``` + --debug exibe uma saída verbosa + -h, --help exibe ajuda para um comando do helm + --kube-apiserver string o endereço e porta do Kubernetes API server + --kube-as-group stringArray o grupo que representará essa operação, esse argumento pode ser repetido para indicar múltiplos grupos + --kube-as-user string o usuário que representará essa operação + --kube-ca-file string caminho para o certificado para conexão com o Kubernetes API server + --kube-context string nome do contexto do kubeconfig a ser usado + --kube-token string bearer token usado para autenticação + --kubeconfig string caminho para o arquivo kubeconfig + -n, --namespace string namespace para essa requisição + --registry-config string caminho para o arquivo de configuração do registry (default "~/.config/helm/registry.json") + --repository-cache string caminho para os índices "cacheados" no repositório (default "~/.cache/helm/repository") + --repository-config string caminho para o arquivo path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### Veja Também + +* [helm](helm.md) - Helm, o gerenciador de pacotes para o Kubernetes. \ No newline at end of file diff --git a/content/pt/docs/helm/helm_get.md b/content/pt/docs/helm/helm_get.md new file mode 100644 index 0000000000..37e459854e --- /dev/null +++ b/content/pt/docs/helm/helm_get.md @@ -0,0 +1,51 @@ +--- +title: "Helm Get" +--- + +## helm get + +Baixa informações adicionais de uma dada _release_ + +### Sinopse + +Esse comando consiste em múltiplos subcomandos utilizados para recuperar informações +adicionais sobre uma dada _release_, incluindo: + +- Os valores utilizados para gerar a _release_ +- O arquivo de manifesto gerado +- As notas advindas do Chart da _release_ +- Os _hooks_ associados a uma _release_ + + +### Opções + +``` + -h, --help ajuda para o comando get +``` + +### Opções gerais + +``` + --debug exibe uma saída verbosa + -h, --help exibe ajuda para um comando do helm + --kube-apiserver string o endereço e porta do Kubernetes API server + --kube-as-group stringArray o grupo que representará essa operação, esse argumento pode ser repetido para indicar múltiplos grupos + --kube-as-user string o usuário que representará essa operação + --kube-ca-file string caminho para o certificado para conexão com o Kubernetes API server + --kube-context string nome do contexto do kubeconfig a ser usado + --kube-token string bearer token usado para autenticação + --kubeconfig string caminho para o arquivo kubeconfig + -n, --namespace string namespace para essa requisição + --registry-config string caminho para o arquivo de configuração do registry (padrão "~/.config/helm/registry.json") + --repository-cache string caminho para os índices "cacheados" no repositório (padrão "~/.cache/helm/repository") + --repository-config string caminho para o arquivo path to the file containing repository names and URLs (padrão "~/.config/helm/repositories.yaml") +``` + +### Veja Também + +* [helm](helm.md) - Helm, o gerenciador de pacotes para o Kubernetes. +* [helm get all](helm_get_all.md) - baixa todas as informações de uma dada _release_ +* [helm get hooks](helm_get_hooks.md) - baixa todos os _hooks_ de uma dada _release_ +* [helm get manifest](helm_get_manifest.md) - baixa o manifesto de uma dada _release_ +* [helm get notes](helm_get_notes.md) - baixa as notas de uma dada _release_ +* [helm get values](helm_get_values.md) - baixa o arquivo de valores de uma dada _release_ diff --git a/content/pt/docs/helm/helm_get_all.md b/content/pt/docs/helm/helm_get_all.md new file mode 100644 index 0000000000..d892fdddb2 --- /dev/null +++ b/content/pt/docs/helm/helm_get_all.md @@ -0,0 +1,47 @@ +--- +title: "Helm Get All" +--- + +## helm get all + +Baixa toda informação sobre uma dada _release_ + +### Sinopse + +Esse comando exibe um conjunto de informações, legíveis para o ser humano, sobre +as notas, _hooks_, valores passados e o manifesto gerado para uma dada _release_. + + +``` +helm get all NOME_DA_RELEASE [argumentos] +``` + +### Opções + +``` + -h, --help ajuda para recuperar um manifesto + --revision int recupera uma revisão específica de uma release + --template string template em go para formatar a saída do comando, ex: {{.Release.Name}} +``` + +### Opções gerais + +``` + --debug exibe uma saída verbosa + -h, --help exibe ajuda para um comando do helm + --kube-apiserver string o endereço e porta do Kubernetes API server + --kube-as-group stringArray o grupo que representará essa operação, esse argumento pode ser repetido para indicar múltiplos grupos + --kube-as-user string o usuário que representará essa operação + --kube-ca-file string caminho para o certificado para conexão com o Kubernetes API server + --kube-context string nome do contexto do kubeconfig a ser usado + --kube-token string bearer token usado para autenticação + --kubeconfig string caminho para o arquivo kubeconfig + -n, --namespace string namespace para essa requisição + --registry-config string caminho para o arquivo de configuração do registry (padrão "~/.config/helm/registry.json") + --repository-cache string caminho para os índices cacheados no repositório (padrão "~/.cache/helm/repository") + --repository-config string caminho para o arquivo path to the file containing repository names and URLs (padrão "~/.config/helm/repositories.yaml") +``` + +### Veja Também + +* [helm get](helm_get.md) - baixa informações adicionais de uma dada release diff --git a/content/pt/docs/helm/helm_get_hooks.md b/content/pt/docs/helm/helm_get_hooks.md new file mode 100644 index 0000000000..7c47a353e0 --- /dev/null +++ b/content/pt/docs/helm/helm_get_hooks.md @@ -0,0 +1,47 @@ +--- +title: "Helm Get Hooks" +--- + +## helm get hooks + +Baixa todos os _hooks_ para uma dada _release_ + +### Sinopse + +Esse comando recupera os _hooks_ para uma dada _release_. + +_Hooks_ são formatados em YAML e separados pelo separador YAML '---\n'. + + +``` +helm get hooks NOME_DA_RELEASE [argumentos] +``` + +### Opções + +``` + -h, --help ajuda para recuperar um manifesto + --revision int recupera uma revisão específica de uma release +``` + +### Opções gerais + +``` + --debug exibe uma saída verbosa + -h, --help exibe ajuda para um comando do helm + --kube-apiserver string o endereço e porta do Kubernetes API server + --kube-as-group stringArray o grupo que representará essa operação, esse argumento pode ser repetido para indicar múltiplos grupos + --kube-as-user string o usuário que representará essa operação + --kube-ca-file string caminho para o certificado para conexão com o Kubernetes API server + --kube-context string nome do contexto do kubeconfig a ser usado + --kube-token string bearer token usado para autenticação + --kubeconfig string caminho para o arquivo kubeconfig + -n, --namespace string namespace para essa requisição + --registry-config string caminho para o arquivo de configuração do registry (padrão "~/.config/helm/registry.json") + --repository-cache string caminho para os índices cacheados no repositório (padrão "~/.cache/helm/repository") + --repository-config string caminho para o arquivo path to the file containing repository names and URLs (padrão "~/.config/helm/repositories.yaml") +``` + +### Veja Também + +* [helm get](helm_get.md) - baixa informações adicionais de uma dada release diff --git a/content/pt/docs/helm/helm_get_manifest.md b/content/pt/docs/helm/helm_get_manifest.md new file mode 100644 index 0000000000..ac13ba77ee --- /dev/null +++ b/content/pt/docs/helm/helm_get_manifest.md @@ -0,0 +1,48 @@ +--- +title: "Helm Get Manifest" +--- + +## helm get manifest + +Baixa o manifesto de uma dada _release_ + +### Sinopse + +Esse comando recupera o manifesto gerado de uma dada _release_. + +Um manifesto é a representação dos recursos do Kubernetes em um arquivo YAML, o qual +foi gerado a partir do Chart da _release_ em questão. Se o Chart depender de outros Charts, +os recursos Kubernetes das dependências também serão incluídos no manifesto. + +``` +helm get manifest NOME_DA_RELEASE [argumentos] +``` + +### Opções + +``` + -h, --help ajuda para recuperar um manifesto + --revision int recupera uma revisão específica de uma release +``` + +### Opções gerais + +``` + --debug exibe uma saída verbosa + -h, --help exibe ajuda para um comando do helm + --kube-apiserver string o endereço e porta do Kubernetes API server + --kube-as-group stringArray o grupo que representará essa operação, esse argumento pode ser repetido para indicar múltiplos grupos + --kube-as-user string o usuário que representará essa operação + --kube-ca-file string caminho para o certificado para conexão com o Kubernetes API server + --kube-context string nome do contexto do kubeconfig a ser usado + --kube-token string bearer token usado para autenticação + --kubeconfig string caminho para o arquivo kubeconfig + -n, --namespace string namespace para essa requisição + --registry-config string caminho para o arquivo de configuração do registry (padrão "~/.config/helm/registry.json") + --repository-cache string caminho para os índices cacheados no repositório (padrão "~/.cache/helm/repository") + --repository-config string caminho para o arquivo path to the file containing repository names and URLs (padrão "~/.config/helm/repositories.yaml") +``` + +### Veja Também + +* [helm](helm.md) - Helm, o gerenciador de pacotes para o Kubernetes. diff --git a/content/pt/docs/helm/helm_get_notes.md b/content/pt/docs/helm/helm_get_notes.md new file mode 100644 index 0000000000..2aedc37e05 --- /dev/null +++ b/content/pt/docs/helm/helm_get_notes.md @@ -0,0 +1,44 @@ +--- +title: "Helm Get Notes" +--- + +## helm get notes + +Baixa as notas de uma dada _release_ + +### Sinopse + +Esse comando exibe as notas de um Chart para uma dada _release_. + +``` +helm get notes NOME_DA_RELEASE [argumentos] +``` + +### Opções + +``` + -h, --help ajuda para recuperar um manifesto + --revision int recupera uma revisão específica de uma release +``` + +### Opções gerais + +``` + --debug exibe uma saída verbosa + -h, --help exibe ajuda para um comando do helm + --kube-apiserver string o endereço e porta do Kubernetes API server + --kube-as-group stringArray o grupo que representará essa operação, esse argumento pode ser repetido para indicar múltiplos grupos + --kube-as-user string o usuário que representará essa operação + --kube-ca-file string caminho para o certificado para conexão com o Kubernetes API server + --kube-context string nome do contexto do kubeconfig a ser usado + --kube-token string bearer token usado para autenticação + --kubeconfig string caminho para o arquivo kubeconfig + -n, --namespace string namespace para essa requisição + --registry-config string caminho para o arquivo de configuração do registry (padrão "~/.config/helm/registry.json") + --repository-cache string caminho para os índices cacheados no repositório (padrão "~/.cache/helm/repository") + --repository-config string caminho para o arquivo path to the file containing repository names and URLs (padrão "~/.config/helm/repositories.yaml") +``` + +### Veja Também + +* [helm get](helm_get.md) - baixa informações adicionais de uma dada _release_ diff --git a/content/pt/docs/helm/helm_get_values.md b/content/pt/docs/helm/helm_get_values.md new file mode 100644 index 0000000000..828d225107 --- /dev/null +++ b/content/pt/docs/helm/helm_get_values.md @@ -0,0 +1,46 @@ +--- +title: "Helm Get Values" +--- + +## helm get values + +Baixa o arquivo com os valores de uma dada _release_ + +### Sinopse + +Esse comando recupera o arquivo com os valores utilizados em uma dada _release_. + +``` +helm get values NOME_DA_RELEASE [argumentos] +``` + +### Opções + +``` + -a, --all exibe todos os valores (computados) + -h, --help ajuda para recuperar os valores + -o, --output format exibe a saída em um formato específico. Formatos: table, json, yaml (padrão table) + --revision int recupera uma revisão específica de uma release +``` + +### Opções gerais + +``` + --debug exibe uma saída verbosa + -h, --help exibe ajuda para um comando do helm + --kube-apiserver string o endereço e porta do Kubernetes API server + --kube-as-group stringArray o grupo que representará essa operação, esse argumento pode ser repetido para indicar múltiplos grupos + --kube-as-user string o usuário que representará essa operação + --kube-ca-file string caminho para o certificado para conexão com o Kubernetes API server + --kube-context string nome do contexto do kubeconfig a ser usado + --kube-token string bearer token usado para autenticação + --kubeconfig string caminho para o arquivo kubeconfig + -n, --namespace string namespace para essa requisição + --registry-config string caminho para o arquivo de configuração do registry (padrão "~/.config/helm/registry.json") + --repository-cache string caminho para os índices cacheados no repositório (padrão "~/.cache/helm/repository") + --repository-config string caminho para o arquivo path to the file containing repository names and URLs (padrão "~/.config/helm/repositories.yaml") +``` + +### Veja Também + +* [helm get](helm_get.md) - baixa informações adicionais de uma dada _release_ diff --git a/content/pt/docs/helm/helm_install.md b/content/pt/docs/helm/helm_install.md new file mode 100644 index 0000000000..3e30ae5f17 --- /dev/null +++ b/content/pt/docs/helm/helm_install.md @@ -0,0 +1,143 @@ +--- +title: "Helm Install" +--- + +## helm install + +Instala um Chart + +### Sinopse + +Esse comando instala um [_Chart Archive_](docs/glossary/_index.md#chart-archive). + +O argumento de instalação deve ser uma referência a um Chart, ou um caminho para +um Chart empacotado, ou um caminho para um Chart descompactado ou uma URL. + +Para sobrescrever os valores em um Chart use tanto o argumento `--values` indicando +um arquivo `yaml` para os valores ou o argumento `--set` passando os valores através +da linha de comando. Para forçar um valor passado no formato string use o argumento +`--set-string`. No caso de valores grandes considere utilizar o argumento `--set-file` +ao invés de `--values` ou `--set`, para ler um único grande valor a partir de um +arquivo. + + $ helm install -f myvalues.yaml myredis ./redis + +ou + + $ helm install --set name=prod myredis ./redis + +ou + + $ helm install --set-string long_int=1234567890 myredis ./redis + +ou + + $ helm install --set-file my_script=dothings.sh myredis ./redis + +É possível especificar o argumento `--values` / `-f` diversas vezes. A prioridade +será concedida para o último (mais a direita) arquivo passado. Por exemplo. se ambos +`myvalues.yaml` e `override.yaml` contém uma chave `Test`, o valor configurado em +`override.yaml` terá precedência: + + $ helm install -f myvalues.yaml -f override.yaml myredis ./redis + +É possível especificar o argumento `--set` diversas vezes. A prioridade será concedida +para o último (mais a direita) argumento passado. Por exemplo. se ambos os valores +`bar` and `newbar` são configurados para uma chave `foo`, o valor `newbar` +terá precedência: + + $ helm install --set foo=bar --set foo=newbar myredis ./redis + +Os argumentos `--debug` e `--dry-run` podem ser combinados com o comando `helm install` +para verificar os manifestos gerados de uma release sem instalar o Chart. + +Se o argumento `--verify` for utilizado, o Chart **DEVE** ter um arquivo de [linhagem](docs/glossary/_index.md#linhagem-arquivo-de-linhagem), +e este arquivo **DEVE** passar em todas as etapas de verificação. + +Há cinco maneiras diferentes de se instalar um Chart: + +1. Pela referência do Chart: `helm install mymaria example/mariadb` +2. Pelo caminho para um Chart empacotado: `helm install mynginx ./nginx-1.2.3.tgz` +3. Pelo caminho para um diretório do Chart descompactado: `helm install mynginx ./nginx` +4. Por uma URL absoluta: `helm install mynginx https://example.com/charts/nginx-1.2.3.tgz` +5. Pela referência do Chart e URL do repositório: `helm install --repo https://example.com/charts/ mynginx nginx` + +#### Referências do Chart + +Uma referência de um Chart é uma forma conveniente de apontar um Chart em um repositório +de Charts. + +Quando você utiliza uma referência a um Chart junto com o prefixo do repositório +(`exemplo/mariadb`), o Helm procurará nas configurações locais pelo repositório +`exemplo`, e dentro dele irá procurar pelo Chart `mariadb`. Assim, o Helm instalará +a última versão estável do Chart, a menos que seja passado o argumento `--devel` +a fim de considerar também versões de desenvolvimento (alfa, beta, e _release candidates_), +ou passando um número da versão de uma _release_ através do argumento `--version`. + +Para exibir uma lista de Charts contidos em um repositório use `helm repo list`. +Para pesquisar Charts específicos em um repositório use `helm search`. + +``` +helm install [NOME_DA_SUA_RELEASE] [CHART] [argumentos] +``` + +### Opções + +``` + --atomic os manifestos já aplicados serão deletados caso haja uma falha durante a instalação. O argumento --wait será configurado nesse caso + --ca-file string verifica os certificados dos servidores HTTPS utilizando o pacote CA especificado + --cert-file string identifica o cliente HTTPS utilizando o certificado SSL especificado + --create-namespace cria um namespace para a release caso ainda não exista + --dependency-update executa o comando "helm dependency update" antes da instalação do Chart + --description string adiciona uma descrição para a release + --devel também considera versões de desenvolvimento. Equivalente a versão '>0.0.0-0'. É ignorado caso o argumento --version seja passado + --disable-openapi-validation o processo de instalação não validará os templates renderizados com os valores contra o Kubernetes OpenAPI Schema + --dry-run simula uma instalação + -g, --generate-name gera um novo nome de release (e omite o parâmetro NOME_DA_SUA_RELEASE) + -h, --help exibe ajuda para a instalação da release + --insecure-skip-tls-verify ignora a verificação do certificado tls para o download do Chart + --key-file string identifica o cliente HTTPS com a chave SSL passada + --keyring string caminho das chaves públicas para verificação (padrão "~/.gnupg/pubring.gpg") + --name-template string especifica o template usado para nomear a release + --no-hooks evita que hooks sejam executados durante a instalação + -o, --output format exibe a saída da release instalada em um formato específico. Valores permitidos: table, json, yaml (padrão table) + --pass-credentials passa as credentiais para todos os domínios + --password string senha do repositório de Chart necessária para localizar o Chart em questão + --post-renderer postrenderer caminho para um executável a ser rodado após as renderização do template. Se o caminho existir em $PATH, o binário será executado, senão ele tentará buscar no caminho especificado (padrão exec) + --render-subchart-notes se configurado, renderizará notas de um subchart juntamente com o Chart principal + --replace reaproveita o nome da release, somente se o nome da release deletada ainda estiver no histórico. Essa operação não é segura em produção + --repo string endereço URL do repositório de Charts que contém o Chart a ser instalado + --set stringArray configura os valores a serem usados nos templates dos manifestos via linha de comando (pode-se configurar múltiplos valores separados por vírgula: key1=val1,key2=val2) + --set-file stringArray configura os valores a partir de arquivos especificados via linha de comando (pode-se configurar múltiplos valores separados por vírgula: key1=path1,key2=path2) + --set-string stringArray configura os valores no formato STRING via linha de comando (pode-se configurar múltiplos valores separados por vírgula: key1=val1,key2=val2) + --skip-crds se configurado nenhum CRDs será instalado. Por padrão os CRDs são instalados se já não estiverem presentes no cluster + --timeout duration timeout para qualquer operação individual do Kubernetes (como Jobs para hooks) (padrão 5m0s) + --username string usuário do repositório de Chart onde localizará o Chart + -f, --values strings especifica os valores atráves de um arquivo YAML file ou uma URL (pode especificar vários arquivos YAML) + --verify verifica o pacote antes de utilizá-lo + --version string especifica os limites de versão para um Chart utilizar. Pode ser um limite específico (ex: 1.1.1) ou uma referência para um intervalo de versões (ex: ^2.0.0). A versão mais recente será utilizada caso a versão não seja especificada + --wait se configurado, esperará até todos os Pods, PVCs, Services, e um número mínimo dos Pods de um Deployment, StatefulSet, ou ReplicaSet estejam disponíveis e prontos (ready) antes de marcar a release como pronta. Esperará até o --timeout + --wait-for-jobs se configurado e o argumento --wait for passado, esperará até todos os Jobs serem completados antes de marcar a release como pronta. Esperará até o --timeout +``` + +### Opções gerais + +``` + --debug exibe uma saída verbosa + -h, --help exibe ajuda para um comando do helm + --kube-apiserver string o endereço e porta do Kubernetes API server + --kube-as-group stringArray o grupo que representará essa operação, esse argumento pode ser repetido para indicar múltiplos grupos + --kube-as-user string o usuário que representará essa operação + --kube-ca-file string caminho para o certificado para conexão com o Kubernetes API server + --kube-context string nome do contexto do kubeconfig a ser usado + --kube-token string bearer token usado para autenticação + --kubeconfig string caminho para o arquivo kubeconfig + -n, --namespace string namespace para essa requisição + --registry-config string caminho para o arquivo de configuração do registry (padrão "~/.config/helm/registry.json") + --repository-cache string caminho para os índices "cacheados" no repositório (padrão "~/.cache/helm/repository") + --repository-config string caminho para o arquivo path to the file containing repository names and URLs (padrão "~/.config/helm/repositories.yaml") +``` + +### Veja Também + +* [helm](helm.md) - Helm, o gerenciador de pacotes para o Kubernetes. \ No newline at end of file diff --git a/content/pt/docs/howto/_index.md b/content/pt/docs/howto/_index.md new file mode 100644 index 0000000000..680a5695ec --- /dev/null +++ b/content/pt/docs/howto/_index.md @@ -0,0 +1,12 @@ +--- +title: "Guias de Instruções" +weight: 2 +--- + +# Guias de Instruções + +Nesta seção você encontrará respostas para perguntas do tipo "Como eu faço...?". +Os guias de instruções não cobrem a fundo os tópicos abordados - você encontrará +mais detalhamento desse material na seção [Guias Temáticos](../topics). Contudo, +os Guias de Instruções lhe auxiliarão em realizar tarefas comuns para um usuário +do Helm. diff --git a/content/pt/docs/intro/_index.md b/content/pt/docs/intro/_index.md new file mode 100644 index 0000000000..94b8db551b --- /dev/null +++ b/content/pt/docs/intro/_index.md @@ -0,0 +1,8 @@ +--- +title: "Introdução" +weight: 1 +--- + +# Introdução ao Helm + +Você é novo no Helm? Esse é o lugar por onde começar! diff --git a/content/pt/docs/intro/install.md b/content/pt/docs/intro/install.md new file mode 100755 index 0000000000..0910b7fd8d --- /dev/null +++ b/content/pt/docs/intro/install.md @@ -0,0 +1,156 @@ +--- +title: "Instalando o Helm" +description: "Aprenda como instalar e rodar o Helm." +weight: 2 +--- + +Esse guia ensina como instalar a CLI do Helm. O Helm pode ser instalado +a partir do código-fonte, ou mesmo de um binário pré-buildado. + +## A partir do Projeto Helm + +O projeto Helm disponibiliza duas maneiras de baixar e instalar o Helm. Essas são +as formas oficiais de se obter as versões do Helm. Além disso, a comunidade do Helm +disponibiliza alternativas de download através de diversos gerenciadores de pacotes. +A seção de instalação pelos gerenciadores de pacotes se encontra abaixo dos métodos +oficiais. + +### A partir das _Releases_ dos Binários + +Cada [_release_](https://github.com/helm/helm/releases) do Helm gera distribuições +do binário para uma gama de sistemas operacionais. Essas versões de binários podem +ser baixadas manualmente e instaladas. + +1. Baixe uma [versão desejada](https://github.com/helm/helm/releases) +2. Descompacte-a (`tar -zxvf helm-v3.0.0-linux-amd64.tar.gz`) +3. Encontre o binário `helm` no diretório descompactado e mova-o para um diretório +de destino (`mv linux-amd64/helm /usr/local/bin/helm`) + +A partir daí, você já deve conseguir rodar o cliente e [adicionar +um repositório dos Charts do Helm](https://helm.sh/docs/intro/quickstart/#initialize-a-helm-chart-repository): +`helm help`. + +**Nota:** Os testes automatizados do Helm são realizados para a plataforma Linux +AMD64 somente durante os _builds_ e _releases_ do CircleCI. Testes para outros +sistemas operacionais não estão cobertos e são de responsabilidade da comunidade +em solicitá-los. + +### A partir do _Script_ + +O Helm agora conta com um _script_ que automaticamente baixará a última versão disponível +do Helm e [instalará localmente](https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3). + +Baixe o _script_ e execute-o localmente. O _script_ está bem escrito e documentado, +podendo ser verificado e revisado antes de proceder com a instalação local. + +```console +$ curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 +$ chmod 700 get_helm.sh +$ ./get_helm.sh +``` + +Sim, você pode executar `curl +https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash` se +você gosta de viver perigosamente. + +## Através de Gerenciadores de Pacote + +A comunidade do Helm disponibiliza a instalação através de diversos gerenciadores +de pacotes para diferentes sistemas operacionais. Eles não são mantidos pelo projeto +Helm e não são considerados provedores terceiros acreditados. + +### Homebrew (macOS) + +Membros da comunidade Helm adicionaram uma formula do Helm ao Homebrew. +A fórmula geralmente está atualizada. + +```console +brew install helm +``` + +(Nota: Atenção, existe uma fórmula do emacs-helm, que é um projeto distinto!) + +### Chocolatey (Windows) + +Membros da comunidade Helm contribuíram com um build do [pacote Helm](https://chocolatey.org/packages/kubernetes-helm) +para o [Chocolatey](https://chocolatey.org/). Esse pacote geralmente está atualizado. + +```console +choco install kubernetes-helm +``` + +### Apt (Debian/Ubuntu) + +Membros da comunidade Helm contribuíram com um [pacote do Helm](https://helm.baltorepo.com/stable/debian/) +para o Apt. Esse pacote geralmente está atualizado. + +```console +curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null +sudo apt-get install apt-transport-https --yes +echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list +sudo apt-get update +sudo apt-get install helm +``` + +### Snap + +A comunidade dos [_Snapcrafters_](https://github.com/snapcrafters) mantém a versão +do [pacote Helm](https://snapcraft.io/helm) para o Snap: + +```console +sudo snap install helm --classic +``` + +### pkg (FreeBSD) + +Membros da comunidade do FreeBSD contribuíram com um [pacote Helm](https://www.freshports.org/sysutils/helm) +buildado para o [_FreeBSD Ports Collection_](https://man.freebsd.org/ports). +Esse pacote geralmente está atualizado. + +```console +pkg install helm +``` + +### _Builds_ de Desenvolvimento + +Além das releases estáveis é possíbel baixar e instalar versões de desenvolvimento +do Helm. + +### _Canary Builds_ + +_Builds "Canary"_ são versões do Helm construídas a partir das últimas atualizações +da _brach master_. Eles não são releases oficiais e podem não ser estáveis! +Contudo, oferecem a oportunidade de testar as funcionalidades mais recentes do Helm. + +Os binários _Canary_ do Helm são armazenados em [get.helm.sh](https://get.helm.sh). +Estes são alguns links de _builds_ comuns: + +- [Linux AMD64](https://get.helm.sh/helm-canary-linux-amd64.tar.gz) +- [macOS AMD64](https://get.helm.sh/helm-canary-darwin-amd64.tar.gz) +- [Experimental Windows + AMD64](https://get.helm.sh/helm-canary-windows-amd64.zip) + +### A partir do Código-Fonte (Linux, macOS) + +_Buildar_ o Helm a partir do código-fonte é mais trabalhoso, mas é a melhor forma +de testar as últimas versões (pré-release) do Helm. + +Você deve ter um ambiente de execução Go instalado em seu host. + +```console +$ git clone https://github.com/helm/helm.git +$ cd helm +$ make +``` + +Se necessário, essa abordagem irá baixar as dependências, armazená-las em cache +e validará a configuração. Irá compilar o `helm` e o mover para `bin/helm` também. + +## Conclusão + +Na maioria dos casos a instalação é simples como baixar um binário pré-buildado +do `helm`. Este documento cobre casos de pessoas que querem executar cargas de +trabalho mais sofisticadas com o Helm. + +Uma vez instalado com sucesso o cliente Helm você pode seguir com o uso do Helm +para o gerenciamento de charts [adição de um repositório estável](https://helm.sh/docs/intro/quickstart/#initialize-a-helm-chart-repository). diff --git a/content/pt/docs/intro/quickstart.md b/content/pt/docs/intro/quickstart.md new file mode 100644 index 0000000000..4105e0ba66 --- /dev/null +++ b/content/pt/docs/intro/quickstart.md @@ -0,0 +1,136 @@ +--- +title: "Guia de Início Rápido" +description: "Como instalar e começar com os primeiros passos no Helm, incluindo instruções para Distros, Perguntas Frequentes e plugins." +weight: 1 +--- + +Esse guia cobre como você rapidamente pode começar a utilizar o Helm. + +## Pré-requisitos + +Os pré-requisitos a seguir são exigidos para uma experiência bem sucedida e segura +do uso do Helm. + +1. Ter acesso a um cluster Kubernetes +2. Decidir quais configurações de segurança serão aplicadas durante a instalação, +se houver alguma +3. Instalar e configurar o Helm. + +### Instale o Kubernetes ou tenha acesso a um cluster + +- Você deve ter o Kubernetes instalado. Para a utilização da última versão do Helm, + nós recomendamos a última versão estável do Kubernetes, que geralmente é a penúltima + _minor version_. +- Você deve ter também instalado localmente a ferramenta `kubectl`. + +Consulte a [Política de Suporte de Versões do Helm](https://helm.sh/docs/topics/version_skew/) +para a máxima diferença de versões suportadas entre o Helm e o Kubernetes. + +## Instalando o Helm + +Faça o download do binário do cliente Helm. Você pode utilizar ferramentas +como o `homebrew` ou pesquisar na [página oficial de _releases_ do Helm](https://github.com/helm/helm/releases). + +Para mais detalhes ou outras opções veja o [guia de instalação](./install.md). + +## Inicialize um Repositório para os Charts do Helm + +Depois de tudo pronto com a instalação do Helm você pode adicionar um repositório +de Charts. Dê uma olhada no [Artifact Hub](https://artifacthub.io/packages/search?kind=0) +para encontrar repositórios de Charts do Helm disponíveis. + +```console +$ helm repo add bitnami https://charts.bitnami.com/bitnami +``` + +Você poderá listar os Charts que deseja instalar do repositório recém adicionado: + +```console +$ helm search repo bitnami +NAME CHART VERSION APP VERSION DESCRIPTION +bitnami/bitnami-common 0.0.9 0.0.9 DEPRECATED Chart with custom templates used in ... +bitnami/airflow 8.0.2 2.0.0 Apache Airflow is a platform to programmaticall... +bitnami/apache 8.2.3 2.4.46 Chart for Apache HTTP Server +bitnami/aspnet-core 1.2.3 3.1.9 ASP.NET Core is an open-source framework create... +# ... and many more +``` + +## Instalando um Chart de exemplo + +Para instalar um Chart você pode rodar o comando `helm install`. O Helm +tem diversas formas de encontrar e instalar Charts, porém a mais fácil é utilizar +os Charts da `bitnami`. + +```console +$ helm repo update # Make sure we get the latest list of charts +$ helm install bitnami/mysql --generate-name +NAME: mysql-1612624192 +LAST DEPLOYED: Sat Feb 6 16:09:56 2021 +NAMESPACE: default +STATUS: deployed +REVISION: 1 +TEST SUITE: None +NOTES: ... +``` + +No exemplo acima o Chart `bitnami/mysql` foi aplicado no cluster e o +nome da nossa nova _release_ é `mysql-1612624192`. + +Você pode ter uma ideia das funcionalidades deste Chart MySQL ao rodar o comando +`helm show chart bitnami/mysql`. Se você quiser ter uma visão completa execute o +comando `helm show all bitnami/mysql` para mais informações do Chart. + +Sempre que você instalar um Chart uma nova _release_ é criada. Dessa forma um mesmo +Chart pode ser instalado diversas vezes em um mesmo cluster. Assim cada Chart pode +ser gerenciado e atualizado de forma independente. + +O comando `helm install` é bem poderoso e com muitas funcionalidades. Para saber +mais acesse o [Guia de Utilização do Helm]({{< relref path="/docs/intro/using_helm.md" + lang="en" >}}) + +## Saiba mais sobre _Releases_ + +É fácil visualizar o que foi aplicado utilizando o Helm: + +```console +$ helm list +NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION +mysql-1612624192 default 1 2021-02-06 16:09:56.283059 +0100 CET deployed mysql-8.3.0 8.0.23 +``` + +O comando `helm list` (ou `helm ls`) irá lhe mostrar uma lista de todos os Charts +aplicados. + +## Desinstalando uma Release + +Para desinstalar uma _release_ utilize o comando `helm uninstall`: + +```console +$ helm uninstall mysql-1612624192 +release "mysql-1612624192" uninstalled +``` + +O comando desinstalará o Chart `mysql-1612624192` do Kubernetes, assim como +todos os recursos associados a _release_, além do histórico da _release_. + +Se o argumento `--keep-history` for passado, o histórico da _release_ será mantido. +Assim será possível recuperar informações sobre a _release_ específica: + +```console +$ helm status mysql-1612624192 +Status: UNINSTALLED +... +``` + +Pelo fato do Helm monitorar as _releases_ até mesmo depois de desinstalá-las com +o argumento `--keep-history`, é possível auditar o histórico do cluster, +sendo até mesmo capaz de recuperar a _release_ (com o comando `helm rollback`). + +## Ajuda no Cliente Helm + +Use `helm help`ou digite um comando seguido pelo argumento `-h` +para saber mais sobre os comandos disponíveis no cliente Helm: + +```console +$ helm get -h +``` diff --git a/content/pt/docs/topics/_index.md b/content/pt/docs/topics/_index.md new file mode 100644 index 0000000000..0205e127aa --- /dev/null +++ b/content/pt/docs/topics/_index.md @@ -0,0 +1,9 @@ +--- +title: "Guias Temáticos" +weight: 3 +--- + +# Guias Temáticos + +Aqui você encontrará introdução a todos os principais conceitos do Helm que você +precisará saber. diff --git a/content/ru/docs/_index.md b/content/ru/docs/_index.md new file mode 100644 index 0000000000..ffe2ad23d5 --- /dev/null +++ b/content/ru/docs/_index.md @@ -0,0 +1,25 @@ +--- +title: "Документация Главная" +description: "Все то, что вам необходимо знать о том, как организована документация." +--- + +# Добро пожаловать + +Добро пожаловать в документацию по [Helm](https://helm.sh/). Helm – это менеджер пакетов Kubernetes. Подробную справочную информацию можно прочитать в отчете +[CNCF Helm Project Journey +report](https://www.cncf.io/cncf-helm-project-journey/). + +# Как организована документация + +У Helm много документации. Обзор поможет узнать, где искать необходимую информацию + +- [Обучающие материалы](https://helm.sh/docs/intro) проведут вас за руку через ряд шагов, которые помогут создать + первый Helm chart Начните с этого, если вы новичок в Helm. +- [Тематические руководства](https://helm.sh/docs/topics) обсуждают ключевые темы и концепции на достаточно высоком уровне, + предоставляют полезную справочную информацию и разъяснения. +- [Путеводители сообщества](https://helm.sh/docs/community) обсуждают темы, сосредоточенные вокруг Helm сообщества. + Начните отсюда, если вы хотите узнать больше о процессе разработки самого Helm и о том, как вы можете внести свой вклад. +- [Инструкции по применению](https://helm.sh/docs/howto) это готовые советы по использованию. + Они проведут вас через шаги, связанные с решением ключевых проблем и вариантов их разрешения. + Инструкции по применению более продвинуты, чем [обучающие материалы](https://helm.sh/docs/intro), и предлагают некоторые расширенные знания о том, как работает Helm. +--- diff --git a/content/ru/docs/intro/_index.md b/content/ru/docs/intro/_index.md new file mode 100644 index 0000000000..98a214456e --- /dev/null +++ b/content/ru/docs/intro/_index.md @@ -0,0 +1,8 @@ +--- +title: "Введение" +weight: 1 +--- + +# Введение в Helm + +Вы новичок в Helm? Это самое подходящее место для начала! diff --git a/content/ru/docs/intro/install.md b/content/ru/docs/intro/install.md new file mode 100755 index 0000000000..02740a8d68 --- /dev/null +++ b/content/ru/docs/intro/install.md @@ -0,0 +1,151 @@ +--- +title: "Установка Helm" +description: "Узнайте, как установить и начать работать с Helm." +weight: 2 +--- + +В этом руководстве рассказывается, как установить Helm CLI. Helm может быть установлен как из +исходного кода, так и из собранных binary релизов. + +## Из Проекта Helm + +Проект Helm предоставляет два способа получения и установки Helm. Это +официальные методы получения релизов Helm. В дополнение к этому сообщество Helm +предоставляет методы установки Helm через различные менеджеры пакетов. +Установка с помощью этих методов может быть найдена ниже официальных методов. + +### Из Binary Релизов + +Каждый [релиз](https://github.com/helm/helm/releases) Helm предоставляет различные binary +сборки под разные операционные системы (OSes). Эти binary версии могут быть загружены и установлены вручную. + +1. Скачайте нужную вам [версию](https://github.com/helm/helm/releases) +2. Распакуйте её (`tar -zxvf helm-v3.0.0-linux-amd64.tar.gz`) +3. Найдите `helm` binary файл в директории из распаковки, и переместите в нужное место (`mv linux-amd64/helm /usr/local/bin/helm`) + +Сразу после этого можно запустить Helm справку [добавить stable репозиторий](https://helm.sh/docs/intro/quickstart/#initialize-a-helm-chart-repository): +`helm help`. + +**Примечание:** Автоматические тесты Helm выполняются для Linux AMD64 только во время сборки и выпуска CircleCI. +Тестирование других OSes является обязанностью сообщества, использующего Helm на их OS. + +### Из Скрипта + +У Helm теперь есть скрипт установки, которая будет автоматически загружать последнюю версию Helm и +[устанавливать его локально](https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3). + +Вы можете получить этот сценарий, а затем выполнить его локально. +Он хорошо документирован, так что вы можете прочитать его и понять, что он делает, прежде чем запускать. + +```console +$ curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 +$ chmod 700 get_helm.sh +$ ./get_helm.sh +``` + +Yes, you can `curl +https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash` if +you want to live on the edge. + +## Через Менеджеров Пакетов + +Сообщество Helm предоставляет возможность установки Helm через +менеджеры пакетов операционной системы. +Они не поддерживаются проектом Helm и не считаются проверенными. + +### Используя Homebrew (macOS) + +Члены сообщества Helm внесли свой вклад в создание formula Helm для Homebrew. +Эта formula, почти всегда, актуальна. + +```console +brew install helm +``` + +(**Примечание:**: Существует также formula для emacs-helm, являющаяся другим проектом.) + +### Используя Chocolatey (Windows) + +Члены сообщества Helm внесли свой вклад в [Helm +пакет](https://chocolatey.org/packages/kubernetes-helm) собранный под +[Chocolatey](https://chocolatey.org/). Данная сборка почти всегда актуальна + +```console +choco install kubernetes-helm +``` + +### Используя Apt (Debian/Ubuntu) + +Члены сообщества Helm внесли свой вклад в [Helm +package](https://helm.baltorepo.com/stable/debian/) для Apt. Данная сборка почти всегда актуальна + +```console +curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null +sudo apt-get install apt-transport-https --yes +echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list +sudo apt-get update +sudo apt-get install helm +``` + +### Используя Snap + +[Snapcrafters](https://github.com/snapcrafters) сообщество поддерживает Snap-версию +[Helm пакета](https://snapcraft.io/helm): + +```console +sudo snap install helm --classic +``` + +### Используя pkg (FreeBSD) + +Члены сообщества FreeBSD внесли свой вклад в создание [Helm +пакета](https://www.freshports.org/sysutils/helm) под +[FreeBSD Ports Collection](https://man.freebsd.org/ports). +Данная сборка почти всегда актуальна + +```console +pkg install helm +``` + +### Тестовые Сборки + +В дополнение к релизам вы можете скачать или установить тестовые сборки + +### Используя Canary Сборки + +Сборки Canary – это версии программного обеспечения Helm, построенные из последней +основной ветви. Они не являются официальными релизами и могут быть нестабильными. Тем не менее, +они предлагают возможность протестировать передовые функции. + +Canary Helm binaries сборки хранятся в [get.helm.sh](https://get.helm.sh). Вот несколько +ссылок на общие сборки: + +- [Linux AMD64](https://get.helm.sh/helm-canary-linux-amd64.tar.gz) +- [macOS AMD64](https://get.helm.sh/helm-canary-darwin-amd64.tar.gz) +- [Experimental Windows + AMD64](https://get.helm.sh/helm-canary-windows-amd64.zip) + +### Из Исходного Кода (Linux, macOS) + +Создание Helm из исходного кода-это немного больше работы, но это лучший способ пойти, если +вы хотите протестировать последнюю версию (pre-release) Helm. + +У вас должна быть рабочая среда Go. + +```console +$ git clone https://github.com/helm/helm.git +$ cd helm +$ make +``` + +При необходимости скрипт извлекает зависимости, кэширует их и проверяет +конфигурацию. Затем он скомпилирует `helm` и поместит его в `bin/helm`. + +## Заключение + +В большинстве случаев установка так же проста, как получение предварительно построенного binary файла `helm`. +В этом документе описаны дополнительные случаи для тех, кто хочет делать +с Helm более сложные вещи. + +После успешной установки клиента Helm вы можете перейти к использованию +Helm для управления chart-ми и [добавить stable репозиторий](https://helm.sh/docs/intro/quickstart/#initialize-a-helm-chart-repository). diff --git a/content/ru/docs/intro/quickstart.md b/content/ru/docs/intro/quickstart.md new file mode 100644 index 0000000000..8415eca6d8 --- /dev/null +++ b/content/ru/docs/intro/quickstart.md @@ -0,0 +1,126 @@ +--- +title: "Краткое Руководство" +description: "How to install and get started with Helm including instructions for distros, FAQs, and plugins." +weight: 1 +--- + +Это руководство описывает, как вы можете быстро начать использовать Helm. + +## Необходимые компоненты + +Для успешного и надежного использования Helm необходимо + +1. Kubernetes кластер +2. Принятие решения о том, какие конфигурации безопасности должны применяться к вашей установке, если таковые имеются. +3. Установка и настройка Helm + +### Установите Kubernetes или получите доступ к кластеру + +- У вас должен быть установлен Kubernetes. Для последней версии Helm мы + рекомендуем последнюю стабильную версию Kubernetes, которая в большинстве случаев является + второй последней минорной версией. +- Вы также должны иметь локально настроенную копию `kubectl`. + +Смотрите [Политику поддержки версий Helm](https://helm.sh/docs/topics/version_skew/) для того, что бы понимать максимальную версию поддержки между Helm и Kubernetes. + +## Установка Helm + +Загрузите binary релиз клиента Helm. Вы можете использовать такие инструменты, как `homebrew`, +или посмотрите на [официальную страницу релизов](https://github.com/helm/helm/releases). + +Для получения более подробной информации или других вариантов смотрите [руководство по установке]({{< ref +"install.md" >}}). + +## Инициализация Helm Chart Repository + +Как только у вас будет готов Helm, вы можете добавить chart репозиторий. Смотрите [Artifact +Hub](https://artifacthub.io/packages/search?kind=0) для проверки доступности Helm chart +репозиториев. + +```console +$ helm repo add stable https://charts.helm.sh/stable +``` + +После установки, вы сможете посмотреть charts, которые вы можете установить: + +```console +$ helm search repo stable +NAME CHART VERSION APP VERSION DESCRIPTION +stable/acs-engine-autoscaler 2.2.2 2.1.1 DEPRECATED Scales worker nodes within agent pools +stable/aerospike 0.2.8 v4.5.0.5 A Helm chart for Aerospike in Kubernetes +stable/airflow 4.1.0 1.10.4 Airflow is a platform to programmatically autho... +stable/ambassador 4.1.0 0.81.0 A Helm chart for Datawire Ambassador +# ... and many more +``` + +## Пример Установки Chart + +Чтобы установить chart, вы необходимо использовать команду `helm install`. +У Helm есть несколько способов найти и установить chart, но самый простой – это использовать один из официальных `stable` chart-ов. + +```console +$ helm repo update # Убедитесь, что мы получили последний список chart-ов +$ helm install stable/mysql --generate-name +Released smiling-penguin +``` + +В приведенном выше примере был выпущен `stable/mysql` chart, а имя нашего нового релиза: `smiling-penguin`. + +Вы получите простое представление о возможностях этого MySQL chart-а, запустив `helm show +chart stable/mysql`. +Или вы можете запустить `helm show all stable/mysql` чтобы получить всю информацию о chart-е. + +Всякий раз, когда вы устанавливаете chart, создается новая версия. +Таким образом, один chart можно установить несколько раз в один и тот же кластер. +И каждый из них может управляться и обновляться независимо. + +`helm install` очень мощная команда со многими возможностями. +Узнать больше можно в [Руководстве по эксплуатации Helm]({{< ref "using_helm.md" +>}}) + +## Подробнее О Релизах + +Всегда с легкостью можно увидеть, что было выпущено с помощью Helm: + +```console +$ helm ls +NAME VERSION UPDATED                   STATUS   CHART +smiling-penguin 1 Wed Sep 28 12:59:46 2016 DEPLOYED mysql-0.1.0 +``` + +Функция `helm list` покажет вам список всех развернутых релизов. + +## Удаление Релиза + +Чтобы деинсталлировать релиз, используйте команду `helm uninstall`: + +```console +$ helm uninstall smiling-penguin +Removed smiling-penguin +``` + +В данном случае, это удалит `smiling-penguin` из Kubernetes, +а так же удалит все ресурсы, связанные с этим релизом и саму историю релизов. + +If the flag `--keep-history` is provided, release history will be kept. You will +be able to request information about that release: +Если использовать флаг `--keep-history`, то история релизов будет сохранена. +В этом случае, у Вас остается возможность запросить информацию о удаленном ранее релизе. + +```console +$ helm status smiling-penguin +Status: UNINSTALLED +... +``` + +Так как Helm отслеживает ваши релизы даже после того, как вы их деинсталлировали, +вы можете проверить историю кластера и даже восстановить релиз используя `helm rollback`. + +## Чтение Текста Справки + +Чтобы узнать больше о доступных Helm командах, используйте `helm help` или введите +команду за которой следует флаг `-h`: + +```console +$ helm get -h +``` diff --git a/content/ru/docs/intro/using_helm.md b/content/ru/docs/intro/using_helm.md new file mode 100755 index 0000000000..01e162bbc2 --- /dev/null +++ b/content/ru/docs/intro/using_helm.md @@ -0,0 +1,482 @@ +--- +title: "Использование Helm" +description: "Объясняет основы работы с Helm." +weight: 3 +--- + +В этом руководстве объясняются основы использования Helm для управления пакетами на вашем +кластере Kubernetes. Руководство предполагает, что вы уже [установили]({{< ref +"install.md" >}}) Helm CLI. + +Если вы просто заинтересованы нескольких командам, то можете начать с [Краткого Руководства]({{< ref "quickstart.md" >}}). В этой главе +описаны особенности команд Helm. + +## Three Big Concepts + +*Chart* – это пакет Helm. +Он содержит описания ресурсов, необходимые для запуска приложения, инструмента или службы внутри кластера Kubernetes. + +*Репозиторий* это место, где можно собирать charts-ы и делиться ими. Очень похоже на +Perl's [CPAN archive](https://www.cpan.org) или [Fedora Package +Database](https://src.fedoraproject.org/), но для пакетов Kubernetes. + +*Релиз* это пример charts-а, работающего в кластере Kubernetes. +Один chart часто может быть установлен много раз в одном и том же кластере. +Каждый раз, когда он устанавливается, создается новый _release_. Рассмотрим график MySQL. +У каждого из них будет свой _release_, который, в свою очередь, будет иметь своё имя _release name_. + +Зная эти понятия, объяснить работу Helm можно так: + +Helm устанавливает _charts_ в Kubernetes, создавая новый _release_ для каждой установки. +А для поиска новых графиков можно воспользоваться поиском Helm chart _repositories_. + +## 'helm search': Поиск Charts + +Helm поставляется с мощной поисковой командой. +Он может быть использован для поиска двух различных типов источников: + +- `helm search hub` ищет в [the Artifact Hub](https://artifacthub.io), который агрегирует списки из различных хранилищ +- `helm search repo` поиск в репозиториях, которые вы добавили в свой локальный каталог helm client (используя `helm repo add`). + Этот поиск выполняется по локальным данным, не используя подключение к публичной сети. + +Вы можете найти общедоступные chart-ы, запустив `helm search hub`: + +```console +$ helm search hub wordpress +URL CHART VERSION APP VERSION DESCRIPTION +https://hub.helm.sh/charts/bitnami/wordpress 7.6.7 5.2.4 Web publishing platform for building blogs and ... +https://hub.helm.sh/charts/presslabs/wordpress-... v0.6.3 v0.6.3 Presslabs WordPress Operator Helm Chart +https://hub.helm.sh/charts/presslabs/wordpress-... v0.7.1 v0.7.1 A Helm chart for deploying a WordPress site on ... +``` + +Выше приведен поиск всех chart-ов `wordpress` на Artifact Hub. + +Поиск показывает все доступные chart-ы с определенным именем `helm search hub`. + +Используя `helm search repo`, вы можете найти названия chart-ов в +уже добавленных вами репозиториях: + + +```console +$ helm repo add brigade https://brigadecore.github.io/charts +"brigade" has been added to your repositories +$ helm search repo brigade +NAME CHART VERSION APP VERSION DESCRIPTION +brigade/brigade 1.3.2 v1.2.1 Brigade provides event-driven scripting of Kube... +brigade/brigade-github-app 0.4.1 v0.2.1 The Brigade GitHub App, an advanced gateway for... +brigade/brigade-github-oauth 0.2.0 v0.20.0 The legacy OAuth GitHub Gateway for Brigade +brigade/brigade-k8s-gateway 0.1.0 A Helm chart for Kubernetes +brigade/brigade-project 1.0.0 v1.0.0 Create a Brigade project +brigade/kashti 0.4.0 v0.4.0 A Helm chart for Kubernetes +``` + +Helm search использует приближённый поиск подстроки (fuzzy string matching), поэтому вы можете вводить части +слов или фраз: + +```console +$ helm search repo kash +NAME CHART VERSION APP VERSION DESCRIPTION +brigade/kashti 0.4.0 v0.4.0 A Helm chart for Kubernetes +``` + +Поиск – это хороший способ найти доступные пакеты. Как только вы нашли пакет +, который хотите установить, вы можете использовать `helm install` для его установки. + +## 'helm install': Установка пакета + +Чтобы установить новый пакет, используйте команду `helm install`. В самом простом случае она +ожидает два аргумента: имя выпуска `_release_name_`, и имя chart-а, который Вы +хотите установить. + +```console +$ helm install happy-panda bitnami/wordpress +NAME: happy-panda +LAST DEPLOYED: Tue Jan 26 10:27:17 2021 +NAMESPACE: default +STATUS: deployed +REVISION: 1 +NOTES: +** Please be patient while the chart is being deployed ** + +Your WordPress site can be accessed through the following DNS name from within your cluster: + + happy-panda-wordpress.default.svc.cluster.local (port 80) + +To access your WordPress site from outside the cluster follow the steps below: + +1. Get the WordPress URL by running these commands: + + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + Watch the status with: 'kubectl get svc --namespace default -w happy-panda-wordpress' + + export SERVICE_IP=$(kubectl get svc --namespace default happy-panda-wordpress --template "{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}") + echo "WordPress URL: http://$SERVICE_IP/" + echo "WordPress Admin URL: http://$SERVICE_IP/admin" + +2. Open a browser and access WordPress using the obtained URL. + +3. Login with the following credentials below to see your blog: + + echo Username: user + echo Password: $(kubectl get secret --namespace default happy-panda-wordpress -o jsonpath="{.data.wordpress-password}" | base64 --decode) +``` + +После установки `wordpress` chart-а обратите внимание, что при установке создается +новый объект _release_. Текущей релиз называется `happy-panda`. (Если вы хотите +чтобы Helm сгенерировал имя за вас, оставьте название релиза и используйте +`--generate-name`.) + +Во время установки `helm` клиент напечатает полезную информацию о том, какие +ресурсы были созданы, каково состояние релиза, а также есть ли +дополнительные шаги настройки, которые вы можете воспроизвести. + +Helm не ждет, пока все ресурсы будут запущены, прежде чем он завершит свою работу. Для многих +chart-ов требуются образ Docker-а размером более 600M, и их установка в Kubernetes кластер может занять много +времени. + +Чтобы отслеживать состояние релиза или перечитывать информацию о конфигурации, вы +можете использовать `helm status`: + +```console +$ helm status happy-panda +NAME: happy-panda +LAST DEPLOYED: Tue Jan 26 10:27:17 2021 +NAMESPACE: default +STATUS: deployed +REVISION: 1 +NOTES: +** Please be patient while the chart is being deployed ** + +Your WordPress site can be accessed through the following DNS name from within your cluster: + + happy-panda-wordpress.default.svc.cluster.local (port 80) + +To access your WordPress site from outside the cluster follow the steps below: + +1. Get the WordPress URL by running these commands: + + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + Watch the status with: 'kubectl get svc --namespace default -w happy-panda-wordpress' + + export SERVICE_IP=$(kubectl get svc --namespace default happy-panda-wordpress --template "{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}") + echo "WordPress URL: http://$SERVICE_IP/" + echo "WordPress Admin URL: http://$SERVICE_IP/admin" + +2. Open a browser and access WordPress using the obtained URL. + +3. Login with the following credentials below to see your blog: + + echo Username: user + echo Password: $(kubectl get secret --namespace default happy-panda-wordpress -o jsonpath="{.data.wordpress-password}" | base64 --decode) +``` + +Выше показано текущее состояние вашего релиза. + +### Настройка Chart-а Перед установкой + +Изначально Helm использует параметры конфигурации по умолчанию. +Но вы всегда можете настроить chart используя свою конфигурацию + +Чтобы увидеть, какие параметры есть в chart-е, используйте `helm show values`: + +```console +$ helm show values bitnami/wordpress +## Global Docker image parameters +## Please, note that this will override the image parameters, including dependencies, configured to use the global value +## Current available global Docker image parameters: imageRegistry and imagePullSecrets +## +# global: +# imageRegistry: myRegistryName +# imagePullSecrets: +# - myRegistryKeySecretName +# storageClass: myStorageClass + +## Bitnami WordPress image version +## ref: https://hub.docker.com/r/bitnami/wordpress/tags/ +## +image: + registry: docker.io + repository: bitnami/wordpress + tag: 5.6.0-debian-10-r35 + [..] +``` + +Затем вы можете переопределить любой из этих параметров в файле формата YAML, а затем передать этот файл во время установки. + +```console +$ echo '{mariadb.auth.database: user0db, mariadb.auth.username: user0}' > values.yaml +$ helm install -f values.yaml bitnami/wordpress --generate-name +``` + +Команды выше создадут пользователя для MariaDB с именем `user0` и предоставит +этому пользователю доступ к созданной базе данных `user0db`, но использует остальные значения chart-а по умолчанию. + +Существует два способа передачи конфигурационных данных во время установки: + +- `--values` (или `-f`): Укажите YAML файл с конфигурацией. Это можно сделать несколько раз, и самый правый файл будет иметь приоритет +- `--set`: переопределения в командной строке. + +Если используются оба параметра, то значения `--set` объединяются в `--values` с более высоким +приоритетом. Переопределения, указанные с помощью `--set`, сохраняются в ConfigMap. +Значения, которые были `--set`, можно просмотреть для данного выпуска с помощью `helm get +values `. Значения `--set`, можно очистить, выполнив +`helm upgrade` с `--reset-values`. + +#### Формат и Ограничения`--set` + +Параметр `--set` принимает ноль или более пар имя/значение. В самом простом случае он +используется следующим образом: `--set name=value`. Пример в YAML формате: + +```yaml +name: value +``` + +Несколько значений разделяются символами`,`. `--set a=b,c=d` в YAML формате выглядит так: + +```yaml +a: b +c: d +``` + +Поддерживаются более сложные выражения. Например, `--set outer.inner=value` + +```yaml +outer: + inner: value +``` + +Списки могут быть предоставлены путем включения значений в `{` и `}`. Например, `--set +name={a, b, c}`: + +```yaml +name: + - a + - b + - c +``` + +Начиная с Helm 2.5.0, доступ к элементам списка возможен с помощью +синтаксиса индекса массива. Например, `--set servers[0].port=80`: + +```yaml +servers: + - port: 80 +``` + +Можно задать несколько значений. Строка `--set +servers[0].port=80,servers[0].host=example` становится: + +```yaml +servers: + - port: 80 + host: example +``` + +Иногда вам нужно использовать специальные символы в `--set`. Вы можете использовать +обратную косую черту для экранирования символов; `--set name=value1\,value2`: + +```yaml +name: "value1,value2" +``` + +Точно так же вы можете экранировать точки, что может пригодиться, когда +chart-ы используют функцию `toYaml` для анализа аннотаций, меток и +селекторов узлов. Пример синтаксиса `--set nodeSelector."kubernetes\.io/role"=master`: + +```yaml +nodeSelector: + kubernetes.io/role: master +``` + +Deeply nested data structures can be difficult to express using `--set`. Chart +designers are encouraged to consider the `--set` usage when designing the format +of a `values.yaml` file (read more about [Values Files](https://helm.sh/docs/chart_template_guide/values_files/)). + +### Дополнительные Методы Установки + + `helm install` может установить один из нескольких источников: + +- Репозиторий chart-ов (как мы видели выше) +- Локальное хранилище chart-ов (`helm install foo foo-0.1.1.tgz`) +- Распакованная директория с chart-ами (`helm install foo path/to/foo`) +- Полный URL до chart-а (`helm install foo https://example.com/charts/foo-1.2.3.tgz`) + +## 'helm upgrade' и 'helm rollback': Обновление Релиза и Восстановление После Сбоя + +Когда выпускается новая версия chart-а или когда вы хотите изменить +конфигурацию своего релиза, вы можете использовать команду `helm upgrade`. + +An upgrade takes an existing release and upgrades it according to the +information you provide. Because Kubernetes charts can be large and complex, +Helm tries to perform the least invasive upgrade. It will only update things +that have changed since the last release. + +Обновление использует существующий релиз и обновляет его в соответствии с +предоставленной вами информацией. Из-за того, что chart-ы Kubernetes могут быть большими и сложными, +Helm пытается выполнить наименее инвазивное обновление. Он будет обновлять только то, что изменилось с момента последнего релиза. + +```console +$ helm upgrade -f panda.yaml happy-panda bitnami/wordpress +``` + +В приведенном выше случае релиз `happy-panda` обновляется с тем же chart, +но с новым файлом YAML: + +```yaml +mariadb.auth.username: user1 +``` + +Вы можете использовать `helm get values`, чтобы увидеть, заработа ли новая версия. + +```console +$ helm get values happy-panda +mariadb: + auth: + username: user1 +``` + +Команда `helm get` - это полезный инструмент для просмотра релизов в кластере. +И как мы видим выше, она показывает, что наши новые значения из `panda.yaml` были +развернуты в кластере. + +Теперь, если что-то идет не так, как планировалось во время выпуска, легко +откатиться к предыдущему выпуску, используя `helm rollback [RELEASE] [REVISION]`. + +```console +$ helm rollback happy-panda 1 +``` + +Пример выше возвращает happy-panda к самой первой версии выпуска. Версия +выпуска-это инкрементная версия. Каждый раз, когда происходит установка, обновление или +откат, номер версии увеличивается на 1. Первый +номер редакции всегда равен 1. Мы можем использовать `helm history [RELEASE]`, чтобы увидеть +номера версий для определенного релиза. + +## Полезные Опции для Установки/Обновлении/Отката + +Существует несколько других полезных параметров, которые вы можете указать для настройки +поведения Helm во время установки/обновления/отката. Обратите внимание, что это +не полный список флагов cli. Чтобы увидеть описание всех флагов, просто запустите `helm + --help`. + +- `--timeout`: [Go duration](https://golang.org/pkg/time/#ParseDuration) время ожидания выполнения Kubernetes команд. Стандартное время `5m0s`. +- `--wait`: Ждет, пока все Pods не будут в состоянии готовности, + Развертывания должны иметь минимум (`Desired` минус `maxUnavailable`) Pods в состоянии готовности + и Services должны иметь IP адрес (и Ingress если есть `LoadBalancer`) перед пометкой успешного релиза. + Он будет ждать до значения `--timeout`. + Если тайм - аут достигнут, то релиз будет помечен как `FAILED`. Note: In + scenarios where Deployment has `replicas` set to 1 and `maxUnavailable` is not + set to 0 as part of rolling update strategy, `--wait` will return as ready as + it has satisfied the minimum Pod in ready condition. +- `--no-hooks`: Это пропускает запуск hooks для команды +- `--recreate-pods` (доступно только для `upgrade` и `rollback`): Этот флаг + приведет к пересозданию всех pods (with the exception of pods belonging to + deployments). (УСТАРЕЛО в Helm 3) + +## 'helm uninstall': Удаление Релиза + +Когда потребуется удалить релиз из кластера, используйте команду `helm uninstall`: + +```console +$ helm uninstall happy-panda +``` + +Это приведет к удалению релиза из кластера. Вы можете просмотреть все ваши текущие +развернутые релизы с помощью команды `helm list` : + +```console +$ helm list +NAME VERSION UPDATED STATUS CHART +inky-cat 1 Wed Sep 28 12:59:46 2016 DEPLOYED alpine-0.1.0 +``` + +Из примера выше видно, что релиз `happy-panda` был удален. + +В предыдущих версиях Helm, когда релиз удалялся, запись о его +удалении оставалась. В Helm 3, Удаление удаляет записи релиза, а также. +Если вы хотите сохранить запись об удалении выпуска, используйте `helm uninstall +--keep-history`. Использование `helm list --uninstalled` покажет только те выпуски, которые +были удалены с флагом `--keep-history`. + +Флаг `helm list --all` покажет вам все релизы, +сохраненные Helm, включая записи для неудачных или удаленных элементов (если был указан параметр `--keep-history` +): + +```console +$ helm list --all +NAME VERSION UPDATED STATUS CHART +happy-panda 2 Wed Sep 28 12:47:54 2016 UNINSTALLED wordpress-10.4.5.6.0 +inky-cat 1 Wed Sep 28 12:59:46 2016 DEPLOYED alpine-0.1.0 +kindred-angelf 2 Tue Sep 27 16:16:10 2016 UNINSTALLED alpine-0.1.0 +``` + +Обратите внимание, что поскольку релизы теперь удаляются по умолчанию, откат удаленного ресурса больше невозможен. + +## 'helm repo': Работа с Репозиториями + +Helm 3 больше не поставляется со стандартным хранилищем chart-ов. Команды `helm repo` +предоставляет возможности добавления, перечисления и удаления репозиториев. + +Узнать о настроенных репозитории можно с помощью `helm repo list`: + +```console +$ helm repo list +NAME URL +stable https://charts.helm.sh/stable +mumoshu https://mumoshu.github.io/charts +``` + +Новые репозитории могут быть добавлены с помощью `helm repo add`: + +```console +$ helm repo add dev https://example.com/dev-charts +``` + +Поскольку репозитории диаграмм часто меняются, в любой момент вы можете убедиться, +что ваш клиент Helm обновлен, запустив `helm repo update`. + +Репозитории могут быть удалены с помощью `helm repo remove`. + +## Создание Собственных Chart-ов + +[Руководство по разработке Chart-ов](https://helm.sh/docs/topics/charts/) объясняет, как +создавать свои собственные chart-ы. Но вы можете быстро начать работу с помощью команды `helm +create`: + +```console +$ helm create deis-workflow +Creating deis-workflow +``` + +Теперь у вас есть chart в `./deis-workflow`. Вы можете редактировать его и создавать свои собственные +шаблоны. + + +У Helm есть линтер для проверки корректности chart-а, воспользоваться им можно с помощью `helm +lint`. + +Когда придет время упаковать chart в пакет для распространения вам поможет команда `helm +package` + +```console +$ helm package deis-workflow +deis-workflow-0.1.0.tgz +``` + +Теперь вы можете с легкостью поставить этот chart в ваш Helm с помощью `helm install` + +```console +$ helm install deis-workflow ./deis-workflow-0.1.0.tgz +... +``` + +Упакованные chart-ы могут быть загружены в репозиторий chart-ов. Смотрите документацию по +[Helm chart репозитории](https://helm.sh/docs/topics/charts/) для того, что бы узнать новые детали. + +## Заключение + +В этой главе рассмотрены основные схемы использования клиента `helm`, +включая поиск, установку, обновление и удаление. Он также +охватывает полезные служебные команды, такие как `helm status`, `helm get`, и `helm repo`. + +Для получения дополнительной информации об этих командах обратитесь к встроенной справке Helm: `helm help`. diff --git a/content/zh/docs/_index.md b/content/zh/docs/_index.md new file mode 100644 index 0000000000..243f7827d1 --- /dev/null +++ b/content/zh/docs/_index.md @@ -0,0 +1,17 @@ +--- +title: "文档首页" +description: "您需要知道的关于文档如何组织的所有内容。" +--- + +# 欢迎 + +欢迎使用 [Helm](https://helm.sh/zh/) 文档。 Helm 是 Kubernetes 的包管理器,您也可以在 [CNCF Helm 项目过程报告](https://www.cncf.io/cncf-helm-project-journey/)阅读详细的背景信息。 + +# 文档构成 + +Helm 有大量的文档。高级组织概述会让您知道在哪里查找特定内容。 + +- [教程](intro) 如果您是新手,从这里开始,手把手带您通过一系列的步骤创建您的第一个 Helm chart。 +- [主题引导](topics) 以相当高的水平讨论关键主题和概念并提供有用的背景信息和解释。 +- [社区引导](community) 讨论围绕社区的相关话题。如果您想了解更多关于 Helm 本身的开发过程以及如何参与开发,从这里开始。 +- [如何做](howto) 操作方法。 指引您按照步骤参与定位关键问题和使用案例。假定您对 Helm 工作原理有所了解的情况下,这些内容会比教程更加高级。 diff --git a/content/zh/docs/chart_best_practices/_index.md b/content/zh/docs/chart_best_practices/_index.md new file mode 100644 index 0000000000..a4aefe00cd --- /dev/null +++ b/content/zh/docs/chart_best_practices/_index.md @@ -0,0 +1,13 @@ +--- +title: "最佳实践" +sidebar: true +weight: 4 +--- + +# Chart 最佳实践指南 + +该指南覆盖了 Helm 团队能考虑到的创建 Chart 的最佳实践。 +聚焦于 Chart 应该如何构造。 + +我们首要关注 Chart 公开部署的最佳实践。 +我们知道很多 Chart 只用于内部使用,而且这些 Chart 作者会越过这些建议使用他们的内部优化。 diff --git a/content/zh/docs/chart_best_practices/conventions.md b/content/zh/docs/chart_best_practices/conventions.md new file mode 100644 index 0000000000..19040fb61e --- /dev/null +++ b/content/zh/docs/chart_best_practices/conventions.md @@ -0,0 +1,43 @@ +--- +title: "一般惯例" +description: "chart的一般惯例" +weight: 1 +--- + +最佳实践的这部分阐述了一般惯例。 + +## Chart名称 + +chart名称必须是小写字母和数字。单词之间 _可以_ 使用横杠分隔(-): + +示例: + +```yaml +drupal +nginx-lego +aws-cluster-autoscaler +``` + +chart名称中不能用大写字母也不能用下划线。点 . 符号也不行。 + +## 版本号 + +Helm尽可能使用[SemVer 2](https://semver.org)来表示版本号。(注意Docker镜像的tag不一定遵循SemVer, +因此被认为是一个不幸的例外规则。) + +当SemVer版本存储在Kubernetes标签中时,我们通常把`+`字符改成`_`,因为标签不允许使用`+`作为值进行签名。 + +## 格式化YAML + +YAML 文件应该按照 _双空格_ 缩进(绝不要使用tab键)。 + +## Helm 和 Chart的用法 + +以下是几个 _Helm_ 和 _helm_ 的惯用方法。 + +- _Helm_ 是指整个项目 +- `helm` 是指客户端命令 +- `chart` 不是专有名词,不需要首字母大写 +- 但`Chart.yaml`需要首字母大写,因为文件名大小写敏感 + +若有疑问,使用 _Helm_ ('H'大写). diff --git a/content/zh/docs/chart_best_practices/custom_resource_definitions.md b/content/zh/docs/chart_best_practices/custom_resource_definitions.md new file mode 100644 index 0000000000..e5faa8b773 --- /dev/null +++ b/content/zh/docs/chart_best_practices/custom_resource_definitions.md @@ -0,0 +1,47 @@ +--- +title: "自定义资源" +description: "如何创建和使用CRD" +weight: 7 +--- + +最佳实践的这部分处理创建和使用自定义资源。 + +当使用自定义资源时(CRD),区分两个不同的部分很重要: + +- CRD的声明。是一个具有`CustomResourceDefinition`类型的yaml文件。 +- 有些资源 _使用_ CRD. 假设CRD定义了`foo.example.com/v1`。任何有`apiVersion: example.com/v1`和 + `Foo`类的资源都可以使用CRD。 + +## 使用资源之前安装CRD声明 + +Helm被优化为尽可能快地将尽可能多的资源加载到Kubernetes中。按照设计,Kubernetes可以获取一整套清单并将其全部上线 +(称之为协调循环)。 + +但CRD与此不同。 + +对于CRD来说,声明必须在所有的CRD类型资源使用之前被注册。注册过程可能需要几秒钟。 + +### 方法1: 使用 `helm` + +随着Helm 3的到来,我们去掉了旧的`crd-install`钩子以便获取更简单的方法。现在可以在chart中创建一个名为`crds`的特殊目录来保存CRD。 +这些CRD没有模板化,但是运行`helm install`时可以为chart默认安装。如果CRD已经存在,会显示警告并跳过。如果希望跳过CRD安装步骤, +可以使用`--skip-crds`参数。 + +#### 注意事项(和说明) + +目前不支持使用Helm升级或删除CRD。由于数据意外丢失的风险,这是经过多次社区讨论后作出的明确决定。对于如何处理CRD及其生命周期, +目前社区还未达成共识。随着过程的发展,Helm会逐渐支持这些场景。 + +执行`helm install` 和 `helm upgrade`时的`--dry-run`参数目前不支持CRD。“模拟运行”的目的是检测chart的输出是否在发送到服务器时实际有效。 +但是CRD是对服务器行为的修改。Helm无法在模拟运行时安装CRD,因此客户端无法知道自定义资源(CR),验证就会失败。 +你可以将CRD移动到自己的chart中或者使用`helm template`代替。 + +在讨论CRD支持时需要考虑的另一个重要点是如何处理模板的渲染。Helm 2中使用`crd-install`的一个明显缺点是, +由于API可用性的变化导致无法有效验证chart(CRD实际上是向Kubernetes集群添加了另一个可用API)。 如果chart安装了CRD, +`helm`不再有一组有效的API版本可供使用。这也是从CRD删除模板支持的原因。有了CRD安装的新方法`crds`,我们现在可以确保`helm`拥有当前集群状态的完全有效的信息。 + +### 方法2: 分隔chart + +另一个方法是将CRD定义放入chart中,然后将所有使用该CRD的资源放到 _另一个_ chart中。 + +这个方法要将每个chart分开安装,但对于具有集群管理员访问权限的操作员,这种工作流可能更有用。 diff --git a/content/zh/docs/chart_best_practices/dependencies.md b/content/zh/docs/chart_best_practices/dependencies.md new file mode 100644 index 0000000000..c1b889c8c5 --- /dev/null +++ b/content/zh/docs/chart_best_practices/dependencies.md @@ -0,0 +1,65 @@ +--- +title: "依赖" +description: "涵盖chart依赖的最佳实践" +weight: 4 +--- + +最佳实践的这部分阐述`Chart.yaml`中声明的`dependencies`。 + +## 版本 + +如果有可能的话,使用版本范围而不是某个固定的版本。建议的默认设置时使用补丁级别版本的匹配: + +```yaml +version: ~1.2.3 +``` + +这样会匹配 `1.2.3`以及该版本的任何补丁,也就是说,`~1.2.3`相当于`>= 1.2.3, < 1.3.0` + +关于完整的版本匹配语法,请参照[语义版本文档](https://github.com/Masterminds/semver#checking-version-constraints)。 + +### 预发布版本 + +上述版本约束不适用于预发布版本。比如 `version: ~1.2.3` 可以匹配 `version: ~1.2.4` 但不能匹配 `version: ~1.2.3-1`。 +预发布及补丁级别匹配如下: + +```yaml +version: ~1.2.3-0 +``` + +### 仓库URL + +如果可能的话,使用 `https://` 仓库URL,而不是`http://` URL。 + +如果这个仓库已经被添加到仓库索引文件中,仓库名称可以作为URL的别名。使用`alias:` 或 `@` 后跟仓库名称。 + +文件URL(`file://...`) 被认为是一种有固定部署管道组装的chart的“特例”。 + +当使用[下载器插件](https://helm.sh/zh/docs/topics/plugins#下载插件)时,URL会使用特定于插件的方案。 +注意,chart的用户需要安装一个支持该方案的插件来更新或构建依赖关系。 + +当`repository`字段为空时,Helm无法对依赖项执行依赖管理操作。在这种场景下,Helm假定依赖关系位于`charts` +文件夹的子目录中,名称与依赖关系的`name`属性相同。 + +## 条件和标签 + +条件和标签可以被添加到任意 _可选的_ 依赖中。 + +条件的首先格式是: + +```yaml +condition: somechart.enabled +``` + +`somechart`是依赖的chart名称。 + +当多个子chart(依赖)一起提供可选或可交换的特性时,这些chart应该共享相同的标签。 + +比如,如果`nginx` 和 `memcached`在chart中一起提供性能优化,且需要在使用该功能时同时存在,则都应该有如下的标签部分: + +```yaml +tags: + - webaccelerator +``` + +这允许用户使用一个标签打开和关闭该功能。 diff --git a/content/zh/docs/chart_best_practices/labels.md b/content/zh/docs/chart_best_practices/labels.md new file mode 100644 index 0000000000..75d126672b --- /dev/null +++ b/content/zh/docs/chart_best_practices/labels.md @@ -0,0 +1,38 @@ +--- +title: "标签和注释" +description: "涵盖了在chart中使用标签和注释的最佳实践。" +weight: 5 +--- + +最佳实践的这部分讨论关于在chart中使用标签和注释的最佳方式。 + +## 是标签还是注释? + +在以下条件下,元数据项应该是标签: + +- Kubernetes使用它来识别这种资源 +- 为了查询系统,暴露给操作员会很有用 + +比如,我们建议使用 `helm.sh/chart: NAME-VERSION` 作为标签,以便操作员可以找到特定chart的所有实例。 + +如果元数据项不是用于查询,就应该设置为注释。 + +Helm钩子都是注释。 + +## 标准标签 + +以下表格定义了Helm chart使用的通用标签。Helm本身从不要求出现特定标签。标记为REC的是推荐标签。且 _应该_ 放置在chart之上保持全局一致性。 +标记为OPT的是可选的。 这些是惯用的和常用的,但操作时并不经常依赖。 + +名称| 状态 | 描述 +-----|-------|---------- +`app.kubernetes.io/name` | REC | app名称,反应整个app。`{{ template "name" . }}`经常用于此。很多Kubernetes清单会使用这个,但不是Helm指定的。 +`helm.sh/chart` | REC | chart的名称和版本: `{{ .Chart.Name }}-{{ .Chart.Version \| replace "+" "_" }}`。 +`app.kubernetes.io/managed-by` | REC | 此值应始终设置为 `{{ .Release.Service }}`。 用来查找被Helm管理的所有内容。 +`app.kubernetes.io/instance` | REC | 这个应该是`{{ .Release.Name }}`。 有助于在同一应用程序中区分不同的实例。 +`app.kubernetes.io/version` | OPT | app的版本,且被设置为 `{{ .Chart.AppVersion }}`. +`app.kubernetes.io/component` | OPT | 这是通用标签,用于标记块在应用程序中可能扮演的不同角色。比如 `app.kubernetes.io/component: frontend`。 +`app.kubernetes.io/part-of` | OPT | 当多个chart或块用于构建一个应用程序时。比如,应用软件和数据库生成一个网站。这可以设置为受支持的顶级应用程序。 + +你可以在[Kubernetes documentation](https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/)找到更多 +`app.kubernetes.io`作为前缀的Kubernetes标签。 diff --git a/content/zh/docs/chart_best_practices/pods.md b/content/zh/docs/chart_best_practices/pods.md new file mode 100644 index 0000000000..e155dce038 --- /dev/null +++ b/content/zh/docs/chart_best_practices/pods.md @@ -0,0 +1,68 @@ +--- +title: "pod和pod模板" +description: "讨论在chart清单中格式化Pod和Pod模板部分" +weight: 6 +--- + +最佳实践的这部分讨论在chart清单中格式化Pod和Pod模板部分。 + +以下(非详尽的)资源列表使用Pod模板: + +- Deployment +- ReplicationController +- ReplicaSet +- DaemonSet +- StatefulSet + +## 镜像 + +容器镜像应该使用固定的tag或镜像SHA。不应该使用`latest`, `head`, `canary`等标签或其他被设计为“浮动的”标签。 + +镜像 _可以_ 被定义在 `values.yaml` 文件中是的切换镜像更加容易。 + +```yaml +image: {{ .Values.redisImage | quote }} +``` + +镜像和tag _可以_ 在 `values.yaml`中定义为两个独立的字段: + +```yaml +image: "{{ .Values.redisImage }}:{{ .Values.redisTag }}" +``` + +## 镜像拉取策略 + +`helm create` 通过以下方式在`deployment.yaml`中将 `imagePullPolicy` 默认设置为 `IfNotPresent`: + +```yaml +imagePullPolicy: {{ .Values.image.pullPolicy }} +``` + +以及`values.yaml`: + +```yaml +image: + pullPolicy: IfNotPresent +``` + +类似地,如果Kubernetes根本没有定义,默认会将 `imagePullPolicy` 设置为 `IfNotPresent`。 +如果想设置一个值而不是 `IfNotPresent`,只需在 `values.yaml` 中更新为需要的值即可。 + +## Pod模板应该声明选择器 + +所有的Pod模板部分应该指定一个selector。比如: + +```yaml +selector: + matchLabels: + app.kubernetes.io/name: MyName +template: + metadata: + labels: + app.kubernetes.io/name: MyName +``` + +这是一个很好的实践,因为它建立了集合和pod之间的关系。 + +但这一点对于像工作负载这样的集合来说更加重要。如果没有,标签的 _所有_ +集合会选择匹配pod,如果你使用了改变的标签,比如版本和发布日期,这个功能会失效。 diff --git a/content/zh/docs/chart_best_practices/rbac.md b/content/zh/docs/chart_best_practices/rbac.md new file mode 100644 index 0000000000..7ed0200f85 --- /dev/null +++ b/content/zh/docs/chart_best_practices/rbac.md @@ -0,0 +1,73 @@ +--- +title: "基于角色的访问控制" +description: "讨论在chart清单中创建和格式化RBAC资源。" +weight: 8 +--- + +最佳实践的这部分讨论在chart清单中创建和格式化RBAC资源。 + +RBAC 资源有: + +- ServiceAccount (namespaced) +- Role (namespaced) +- ClusterRole +- RoleBinding (namespaced) +- ClusterRoleBinding + +## YAML 配置 + +RBAC和服务账户配置应该使用独立的key。它们是独立的内容。在YAML中将这两个概念分开可以消除歧义使其更加清晰。 + +```yaml +rbac: + # Specifies whether RBAC resources should be created + create: true + +serviceAccount: + # Specifies whether a ServiceAccount should be created + create: true + # The name of the ServiceAccount to use. + # If not set and create is true, a name is generated using the fullname template + name: +``` + +这个结构可以在更加复杂的需要多个服务账户的chart中扩展。 + +```yaml +someComponent: + serviceAccount: + create: true + name: +anotherComponent: + serviceAccount: + create: true + name: +``` + +## RBAC 资源应该默认创建 + +`rbac.create` 应该是布尔值,用于控制RBAC资源是否被创建。默认是 `true`。用户想自己管理RBAC访问控制时可以设置为`false` +(示例如下)。 + +## 使用RBAC资源 + +`serviceAccount.name` 要设置为由chart创建的访问控制资源的ServiceAccount的名称。 +如果`serviceAccount.create`是true,则使用该名称的ServiceAccount会被创建。如果没有设置名称, +则会使用`fullname`模板生成一个名称。如果`serviceAccount.create`是false,则不会被创建,但仍然会与相同的资源关联, +以便后续手动创建的引用它的RBAC资源可以正常工作。如果`serviceAccount.create`是false且没有指定名称, +会使用默认的ServiceAccount。 + +以下辅助模板应用于ServiceAccount。 + +```yaml +{{/* +Create the name of the service account to use +*/}} +{{- define "mychart.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "mychart.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} +``` diff --git a/content/zh/docs/chart_best_practices/templates.md b/content/zh/docs/chart_best_practices/templates.md new file mode 100644 index 0000000000..4cb96a3cc7 --- /dev/null +++ b/content/zh/docs/chart_best_practices/templates.md @@ -0,0 +1,196 @@ +--- +title: "模板" +description: "进一步了解围绕模板的最佳实践。" +weight: 3 +--- + +最佳实践指南的这部分聚焦于模板。 + +## `templates/`结构 + +`templates/`目录结构应该如下: + +- 如果生成YAML输出,模板文件应该有扩展名`.yaml`。 + 扩展名是`.tpl`可用于生成非格式化内容的模板文件。 +- 模板文件名称应该使用横杠符号(`my-example-configmap.yaml`),不用驼峰记法。 +- 每个资源的定义应该在它自己的模板文件中。 +- 模板文件的名称应该反映名称中的资源类型。比如:`foo-pod.yaml`, `bar-svc.yaml` + +## 定义模板的名称 + +定义的模板(在`{{ define }}`命令中定义的模板)是可全局访问的。这就意味着chart和所有的子chart都可以访问用`{{ define }}`创建的所有模板。 + +因此, _所有定义的模板名称应该被命名空间化。_ + +正确的: + +```yaml +{{- define "nginx.fullname" }} +{{/* ... */}} +{{ end -}} +``` + +不正确的: + +```yaml +{{- define "fullname" -}} +{{/* ... */}} +{{ end -}} +``` + +强烈建议通过`helm create`命令创建新chart,因为模板名称是根据此最佳实践自动定义的。 + +## 格式化模板 + +模板应该使用两个 _空格_ 缩进(永远不要用tab)。 + +模板命令的大括号前后应该使用空格: + +正确的: + +```yaml +{{ .foo }} +{{ print "foo" }} +{{- print "bar" -}} +``` + +不正确的: + +```yaml +{{.foo}} +{{print "foo"}} +{{-print "bar"-}} +``` + +模板应该尽可能多地使用空格: + +```yaml +foo: + {{- range .Values.items }} + {{ . }} + {{ end -}} +``` + +块(例如控制结构) 可以缩进表示模板代码流。 + +```yaml +{{ if $foo -}} + {{- with .Bar }}Hello{{ end -}} +{{- end -}} +``` + +然而,因为YAML是面向空格的语言,代码缩进通常不可能遵守规范。 + +## 生成模板中的空格 + +最好在生成的模板中将空格量保持在最小值。尤其是大量的空行不应该相邻出现。但偶尔有空行(尤其在逻辑块之间)是没问题的。 + +这样是最好的: + +```yaml +apiVersion: batch/v1 +kind: Job +metadata: + name: example + labels: + first: first + second: second +``` + +这样也OK: + +```yaml +apiVersion: batch/v1 +kind: Job + +metadata: + name: example + + labels: + first: first + second: second + +``` + +但避免这样: + +```yaml +apiVersion: batch/v1 +kind: Job + +metadata: + name: example + + + + + + labels: + first: first + + second: second + +``` + +## 注释 (YAML注释 vs. 模板注释) + +YAML和Helm模板都有注释标记符。 + +YAML注释: + +```yaml +# This is a comment +type: sprocket +``` + +模板注释: + +```yaml +{{- /* +This is a comment. +*/}} +type: frobnitz +``` + +描述模板的特性时应当使用模板注释,比如解释一个定义的模板: + +```yaml +{{- /* +mychart.shortname provides a 6 char truncated version of the release name. +*/}} +{{ define "mychart.shortname" -}} +{{ .Release.Name | trunc 6 }} +{{- end -}} + +``` + +在模板中,当有益于Helm用户(可能)在调试时查看注释,可以使用YAML注释。 + +```yaml +# This may cause problems if the value is more than 100Gi +memory: {{ .Values.maxMem | quote }} +``` + +以上注释在用户执行`helm install --debug`时是可见的,而在`{{- /* */}}`部分指定注释不会显示。 + +## 在模板和模板输出中使用JSON + +YAML是JSON的超集。在某些情况下,使用JSON语法比其他YAML表示更具可读性。 + +比如,这个YAML更接近表示列表的普通YAML方法: + +```yaml +arguments: + - "--dirname" + - "/foo" +``` + +但是折叠成JSON列表样式时会更易阅读: + +```yaml +arguments: ["--dirname", "/foo"] +``` + +使用JSON可以很好地提高易读性。然而,JSON语法不应用于表示更复杂的结构。 + +在处理嵌入到YAML中的纯JSON时(比如初始化容器配置),使用JSON格式当然是最合适的。 diff --git a/content/zh/docs/chart_best_practices/values.md b/content/zh/docs/chart_best_practices/values.md new file mode 100644 index 0000000000..1ae582f3b4 --- /dev/null +++ b/content/zh/docs/chart_best_practices/values.md @@ -0,0 +1,138 @@ +--- +title: "values" +description: "聚焦于如何构建和使用你的values。" +weight: 2 +--- + +最佳实践的该部分包括了values的使用。这部分指南中,我们提供了关于你如何构建和使用values的建议,以及专注于设计chart的 `values.yaml`文件。 + +## 命名规范 + +变量名称以小写字母开头,单词按驼峰区分: + +正确的: + +```yaml +chicken: true +chickenNoodleSoup: true +``` + +错误的: + +```yaml +Chicken: true # initial caps may conflict with built-ins +chicken-noodle-soup: true # do not use hyphens in the name +``` + +注意所有的Helm内置变量以大写字母开头,以便与用户定义的value进行区分:`.Release.Name`,`.Capabilities.KubeVersion`。 + +## 扁平或嵌套的Value + +YAML是一种灵活格式,值可以嵌套得很深,也可以是扁平的。 + +嵌套的: + +```yaml +server: + name: nginx + port: 80 +``` + +扁平的 + +```yaml +serverName: nginx +serverPort: 80 +``` + +大多数场景中,扁平的优于嵌套的。因为对模板开发者和用户来说更加简单。 + +为了最佳的安全性,嵌套值的每一层都必须检查: + +```yaml +{{ if .Values.server }} + {{ default "none" .Values.server.name }} +{{ end }} +``` + +对于每个嵌套层,都必须进行存在性检查。但对于扁平的配置,使得模板更易于阅读和使用,这个检查可以跳过。 + +```yaml +{{ default "none" .Values.serverName }} +``` + +当有大量的相关变量时,其中至少有一个是非选择性的,嵌套的值可以改善可读性。 + +## 搞清楚类型 + +YAML的类型强制规则有时候是很反常的。比如,`foo: false` 和 `foo: "false"` 是不一样的。大整型数如:`foo: 12345678` +有时会被转换成科学计数法。 + +避免类型强制规则错误最简单的方式是字符串明确定义,其他都是不明确的。或者,简单来讲, _给所有字符串打引号_。 + +通常,为了避免整数转换问题,将整型存储为字符串更好,并用 `{{ int $value }}` 在模板中将字符串转回整型。 + +在大多数场景中,显式的类型标记更好,所以 `foo: !!string 1234` 会将`1234`作为字符串对待。 +_但是_,YAML解析器会消耗标记,因此类型数据在一次解析后会丢失。 + +## 考虑用户如何使用你的value + +有三种潜在的value来源: + +- chart的`values.yaml`文件 +- 由`helm install -f` 或 `helm upgrade -f`提供的values文件 +- 在执行`helm install` 或 `helm upgrade` 时传递给`--set` 或 `--set-string` 参数的values + +当设计values的结构时,记得你的chart用户可能会通过`-f` 参数或`--set`选项覆盖他们。 + +由于`--set`在表现上更有限,编写你`values.yaml`文件的第一指导原则是 _确保它容易被`--set`覆盖_。 + +因此使用map构建values文件更好。 + +很难与`--set`一起使用: + +```yaml +servers: + - name: foo + port: 80 + - name: bar + port: 81 +``` + +上述在Helm `<=2.4`的版本中无法和`--set`一起表达。在Helm 2.5中,访问foo上的端口是 +`--set servers[0].port=80`。用户不仅更难理解,而且以后更改`servers`顺序之后更易出错。 + +易于使用: + +```yaml +servers: + foo: + port: 80 + bar: + port: 81 +``` + +这样访问foo的port更加明显: `--set servers.foo.port=80`。 + +## 给`values.yaml`写文档 + +`values.yaml`中每个定义的属性都应该文档化。文档字符串应该以它要描述的属性开头,并至少给出一句描述。 + +不正确的: + +```yaml +# the host name for the webserver +serverHost: example +serverPort: 9191 +``` + +正确的: + +```yaml +# serverHost is the host name for the webserver +serverHost: example +# serverPort is the HTTP listener port for the webserver +serverPort: 9191 +``` + +以它描述的参数名称开始每个注释可以很容易整理文档,并使文档工具能可靠地将文档字符串与其描述的参数关联起来。 diff --git a/content/zh/docs/chart_template_guide/_index.md b/content/zh/docs/chart_template_guide/_index.md new file mode 100644 index 0000000000..334723c08b --- /dev/null +++ b/content/zh/docs/chart_template_guide/_index.md @@ -0,0 +1,19 @@ +--- +title: "Chart 模板指南" +weight: 5 +--- + +# Chart模板开发者指南 + +该指南提供 Helm Chart 模板的介绍,重点强调模板语言。 + +模板会生成 manifest 文件,使用 Kubernetes 可以识别的 YAML 格式描述。我们会看到模板是如何结构化的, +它们如何被使用,如何编写 Go 模板,以及如何调试你们的工作内容。 + +该指南聚焦于以下概念: + +- Helm 模板语言 +- values 值的使用 +- 使用模板工作的技术点 + +该指南面向学习 Helm 模板语言的来龙去脉。其他指南提供介绍性资料,示例和最佳实践。 diff --git a/content/zh/docs/chart_template_guide/accessing_files.md b/content/zh/docs/chart_template_guide/accessing_files.md new file mode 100644 index 0000000000..49dbcf0d53 --- /dev/null +++ b/content/zh/docs/chart_template_guide/accessing_files.md @@ -0,0 +1,213 @@ +--- +title: "在模板内部访问文件" +description: "如何从模板中访问文件" +weight: 10 +--- + + +在上一节中,我们研究了几种创建和访问模板的方法。这样可以很容易从一个模板导入到另一个模板中。 +但有时想导入的是不是模板的文件并注入其内容,而无需通过模板渲染发送内容。 + +Helm 提供了通过`.Files`对象访问文件的方法。不过,在我们使用模板示例之前,有些事情需要注意: + +- 可以添加额外的文件到chart中。虽然这些文件会被绑定。但是要小心,由于Kubernetes对象的限制,Chart必须小于1M。 +- 通常处于安全考虑,一些文件无法通过`.Files`对象访问: + - 无法访问`templates/`中的文件 + - 无法访问使用`.helmignore`排除的文件 + - helm应用[subchart](https://helm.sh/zh/docs/chart_template_guide/subcharts_and_globals)之外的文件,包括父级中的,不能被访问的 +- Chart不能保留UNIX模式信息,因此当文件涉及到`.Files`对象时,文件级权限不会影响文件的可用性。 + + + + + +- [基本示例](#basic-example) +- [Path辅助对象](#path-helpers) +- [全局模式](#glob-patterns) +- [ConfigMap和密钥的实用功能](#configmap-and-secrets-utility-functions) +- [编码](#encoding) +- [文件行](#lines) + + + +## Basic example + +先不管警告,我们来写一个读取三个文件到配置映射ConfigMap的模板。开始之前,我们会在chart中添加三个文件, +直接放到`mychart/`目录中。 + +`config1.toml`: + +```toml +message = Hello from config 1 +``` + +`config2.toml`: + +```toml +message = This is config 2 +``` + +`config3.toml`: + +```toml +message = Goodbye from config 3 +``` + +每个都是简单的TOML文件(类似于windows老式的INI文件)。我们知道这些文件的名称,因此我们使用`range`功能遍历它们并将它们的内容注入到我们的ConfigMap中。 + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + {{- $files := .Files }} + {{- range tuple "config1.toml" "config2.toml" "config3.toml" }} + {{ . }}: |- + {{ $files.Get . }} + {{- end }} +``` + +这个配置映射使用了之前章节讨论过的技术。比如,我们创建了一个`$files`变量来引用`.Files`对象。我们也使用了`tuple`方法创建了一个可遍历的文件列表。 +然后我们打印每个文件的名字(`{{ . }}: |-`),然后通过`{{ $files.Get . }}`打印文件内容。 + +执行这个模板会生成包含了三个文件所有内容的单个配置映射: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: quieting-giraf-configmap +data: + config1.toml: |- + message = Hello from config 1 + + config2.toml: |- + message = This is config 2 + + config3.toml: |- + message = Goodbye from config 3 +``` + +## Path helpers + +使用文件时,对文件路径本身执行一些标准操作会很有用。为了实现这些,Helm从Go的[path](https://golang.org/pkg/path/)包中导入了一些功能。 +都使用了与Go包中一样的名称就可以访问。但是第一个字符使用了小写,比如`Base`变成了`base`等等。 + +导入的功能包括: +- Base +- Dir +- Ext +- IsAbs +- Clean + +## Glob patterns + +当你的chart不断变大时,你会发现你强烈需要组织你的文件,所以我们提供了一个 +`Files.Glob(pattern string)`方法来使用[全局模式](https://godoc.org/github.com/gobwas/glob)的灵活性读取特定文件。 + +`.Glob`返回一个`Files`类型,因此你可以在返回对象上调用任意的`Files`方法。 + +比如,假设有这样的目录结构: + +``` +foo/: + foo.txt foo.yaml + +bar/: + bar.go bar.conf baz.yaml +``` + +全局模式下您有多种选择: + + +```yaml +{{ $currentScope := .}} +{{ range $path, $_ := .Files.Glob "**.yaml" }} + {{- with $currentScope}} + {{ .Files.Get $path }} + {{- end }} +{{ end }} +``` + +Or + +```yaml +{{ range $path, $_ := .Files.Glob "**.yaml" }} + {{ $.Files.Get $path }} +{{ end }} +``` + +## ConfigMap and Secrets utility functions + +(在Helm 2.0.2及后续版本可用) + +把文件内容放入配置映射和密钥是很普遍的功能,为了运行时挂载到你的pod上。为了实现它,我们提供了一些基于`Files`类型的实用方法。 + +为了进一步组织文件,这些方法结合`Glob`方法使用时尤其有用。 + +上面的文件结构使用[Glob](#glob-patterns)时的示例如下: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: conf +data: +{{ (.Files.Glob "foo/*").AsConfig | indent 2 }} +--- +apiVersion: v1 +kind: Secret +metadata: + name: very-secret +type: Opaque +data: +{{ (.Files.Glob "bar/*").AsSecrets | indent 2 }} +``` + +## Encoding + +您可以导入一个文件并使用模板的base-64方式对其进行编码来保证成功传输: + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Release.Name }}-secret +type: Opaque +data: + token: |- + {{ .Files.Get "config1.toml" | b64enc }} +``` + +上面的内容使用我们之前使用的相同的`config1.toml`文件进行编码: + +```yaml +# Source: mychart/templates/secret.yaml +apiVersion: v1 +kind: Secret +metadata: + name: lucky-turkey-secret +type: Opaque +data: + token: |- + bWVzc2FnZSA9IEhlbGxvIGZyb20gY29uZmlnIDEK +``` + +## Lines + +有时需要访问模板中的文件的每一行。我们提供了一个方便的`Lines`方法。 + +你可以使用`range`方法遍历`Lines`: + +```yaml +data: + some-file.txt: {{ range .Files.Lines "foo/bar.txt" }} + {{ . }}{{ end }} +``` + +在`helm install`过程中无法将文件传递到chart外。因此如果你想请求用户提供数据,必须使用`helm install -f`或`helm install --set`加载。 + +该部分讨论整合了我们对编写Helm模板的工具和技术的深入研究。下个章节我们会看到如何使用特殊文件`templates/NOTES.txt`, +向chart的用户发送安装后的说明。 diff --git a/content/zh/docs/chart_template_guide/builtin_objects.md b/content/zh/docs/chart_template_guide/builtin_objects.md new file mode 100644 index 0000000000..57c4a598b2 --- /dev/null +++ b/content/zh/docs/chart_template_guide/builtin_objects.md @@ -0,0 +1,48 @@ +--- +title: "内置对象" +description: "模板可用的内置对象" +weight: 3 +--- + +对象可以通过模板引擎传递到模板中。 当然你的代码也可以传递对象。(我们在使用`with`和`range`语句时,会看到示例)。有几种方式可以在模板中创建新对象,比如说我们后面会看到的`tuple`功能。 + +对象可以是非常简单的:仅有一个值。或者可以包含其他对象或方法。比如,`Release`对象可以包含其他对象(比如:`Release.Name`)和`Files`对象有一组方法。 + +在上一部分中,我们用`{{ .Release.Name }}`在模板中插入版本名称。`Release`是你可以在模板中访问的顶层对象之一。 + +- `Release`: `Release`对象描述了版本发布本身。包含了以下对象: + - `Release.Name`: release名称 + - `Release.Namespace`: 版本中包含的命名空间(如果manifest没有覆盖的话) + - `Release.IsUpgrade`: 如果当前操作是升级或回滚的话,该值将被设置为`true` + - `Release.IsInstall`: 如果当前操作是安装的话,该值将被设置为`true` + - `Release.Revision`: 此次修订的版本号。安装时是1,每次升级或回滚都会自增 + - `Release.Service`: 该service用来渲染当前模板。Helm里始终`Helm` +- `Values`: `Values`对象是从`values.yaml`文件和用户提供的文件传进模板的。默认为空 +- `Chart`: `Chart.yaml`文件内容。 `Chart.yaml`里的所有数据在这里都可以可访问的。比如 +`{{ .Chart.Name }}-{{ .Chart.Version }}` 会打印出 `mychart-0.1.0` + - 在[Chart 指南](https://helm.sh/zh/docs/topics/charts#Chart-yaml-文件) 中列出了可获得属性 +- `Files`: 在chart中提供访问所有的非特殊文件的对象。你不能使用它访问`Template`对象,只能访问其他文件。 +请查看这个[文件访问](https://helm.sh/zh/docs/chart_template_guide/accessing_files)部分了解更多信息 + - `Files.Get` 通过文件名获取文件的方法。 (`.Files.Getconfig.ini`) + - `Files.GetBytes` 用字节数组代替字符串获取文件内容的方法。 对图片之类的文件很有用 + - `Files.Glob` 用给定的shell glob模式匹配文件名返回文件列表的方法 + - `Files.Lines` 逐行读取文件内容的方法。迭代文件中每一行时很有用 + - `Files.AsSecrets` 使用Base 64编码字符串返回文件体的方法 + - `Files.AsConfig` 使用YAML格式返回文件体的方法 +- `Capabilities`: 提供关于Kubernetes集群支持功能的信息 + - `Capabilities.APIVersions` 是一个版本列表 + - `Capabilities.APIVersions.Has $version` 说明集群中的版本 (比如,`batch/v1`) 或是资源 (比如, `apps/v1/Deployment`) 是否可用 + - `Capabilities.KubeVersion` 和`Capabilities.KubeVersion.Version` 是Kubernetes的版本号 + - `Capabilities.KubeVersion.Major` Kubernetes的主版本 + - `Capabilities.KubeVersion.Minor` Kubernetes的次版本 + - `Capabilities.HelmVersion` 包含Helm版本详细信息的对象,和 `helm version` 的输出一致 + - `Capabilities.HelmVersion.Version` 是当前Helm语义格式的版本 + - `Capabilities.HelmVersion.GitCommit` Helm的git sha1值 + - `Capabilities.HelmVersion.GitTreeState` 是Helm git树的状态 + - `Capabilities.HelmVersion.GoVersion` 是使用的Go编译器版本 +- `Template`: 包含当前被执行的当前模板信息 + - `Template.Name`: 当前模板的命名空间文件路径 (e.g. `mychart/templates/mytemplate.yaml`) + - `Template.BasePath`: 当前chart模板目录的路径 (e.g. `mychart/templates`) + +内置的值都是以大写字母开始。 这是符合Go的命名惯例。当你创建自己的名称时,可以按照团队约定自由设置。 +就像很多你在 [Artifact Hub](https://artifacthub.io/packages/search?kind=0) 中看到的chart,其团队选择使用首字母小写将本地名称与内置对象区分开,本指南中我们也遵循该惯例。 diff --git a/content/zh/docs/chart_template_guide/control_structures.md b/content/zh/docs/chart_template_guide/control_structures.md new file mode 100644 index 0000000000..551274e487 --- /dev/null +++ b/content/zh/docs/chart_template_guide/control_structures.md @@ -0,0 +1,407 @@ +--- +title: "流控制" +description: "模板中流结构的快速概述" +weight: 7 +--- + +控制结构(在模板语言中称为"actions")提供给你和模板作者控制模板迭代流的能力。 +Helm的模板语言提供了以下控制结构: + +- `if`/`else`, 用来创建条件语句 +- `with`, 用来指定范围 +- `range`, 提供"for each"类型的循环 + +除了这些之外,还提供了一些声明和使用命名模板的关键字: + +- `define` 在模板中声明一个新的命名模板 +- `template` 导入一个命名模板 +- `block` 声明一种特殊的可填充的模板块 + +该部分,我们会讨论关于`if`,`with`,和 `range`。其他部门会在该指南的“命名模板”部分说明。 + +## If/Else + +第一个控制结构是在按照条件在一个模板中包含一个块文本。即`if`/`else`块。 + +基本的条件结构看起来像这样: + +```yaml +{{ if PIPELINE }} + # Do something +{{ else if OTHER PIPELINE }} + # Do something else +{{ else }} + # Default case +{{ end }} +``` + +注意我们讨论的是 _管道_ 而不是值。这样做的原因是要清楚地说明控制结构可以执行整个管道,而不仅仅是计算一个值。 + +如果是以下值时,管道会被设置为 _false_: + +- 布尔false +- 数字0 +- 空字符串 +- `nil` (空或null) +- 空集合(`map`, `slice`, `tuple`, `dict`, `array`) + +在所有其他条件下,条件都为true。 + +让我们先在配置映射中添加一个简单的条件。如果饮品是coffee会添加另一个配置: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + drink: {{ .Values.favorite.drink | default "tea" | quote }} + food: {{ .Values.favorite.food | upper | quote }} + {{ if eq .Values.favorite.drink "coffee" }}mug: "true"{{ end }} +``` + +由于我们在最后一个例子中注释了`drink: coffee`,输出中就不会包含`mug: "true"`标识。但如果将这行添加到`values.yaml` +文件中,输入就会是这样: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: eyewitness-elk-configmap +data: + myvalue: "Hello World" + drink: "coffee" + food: "PIZZA" + mug: "true" +``` + +## 控制空格 + +查看条件时,我们需要快速了解一下模板中控制空白的方式,格式化之前的例子,使其更易于阅读: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + drink: {{ .Values.favorite.drink | default "tea" | quote }} + food: {{ .Values.favorite.food | upper | quote }} + {{ if eq .Values.favorite.drink "coffee" }} + mug: "true" + {{ end }} +``` + +初始情况下,看起来没问题。但是如果通过模板引擎运行时,我们将得到一个不幸的结果: + +```console +$ helm install --dry-run --debug ./mychart +SERVER: "localhost:44134" +CHART PATH: /Users/mattbutcher/Code/Go/src/helm.sh/helm/_scratch/mychart +Error: YAML parse error on mychart/templates/configmap.yaml: error converting YAML to JSON: yaml: line 9: did not find expected key +``` + +发生了啥?因为空格导致生成了错误的YAML。 + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: eyewitness-elk-configmap +data: + myvalue: "Hello World" + drink: "coffee" + food: "PIZZA" + mug: "true" +``` + +`mug`的缩进是不对的。取消缩进重新执行一下: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + drink: {{ .Values.favorite.drink | default "tea" | quote }} + food: {{ .Values.favorite.food | upper | quote }} + {{ if eq .Values.favorite.drink "coffee" }} + mug: "true" + {{ end }} +``` + +这个就得到了合法的YAML,但是看起来还是有点滑稽: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: telling-chimp-configmap +data: + myvalue: "Hello World" + drink: "coffee" + food: "PIZZA" + + mug: "true" + +``` + +注意在YAML中有一个空行,为什么?当模板引擎运行时,它 _移除了_ `{{` 和 `}}` 里面的内容,但是留下的空白完全保持原样。 + +YAML认为空白是有意义的,因此管理空白变得很重要。幸运的是,Helm模板有些工具可以处理此类问题。 + +首先,模板声明的大括号语法可以通过特殊的字符修改,并通知模板引擎取消空白。`{{- `(包括添加的横杠和空格)表示向左删除空白, +而` -}}`表示右边的空格应该被去掉。 _一定注意空格就是换行_ + +> 要确保`-`和其他命令之间有一个空格。 +> `{{- 3 }}` 表示“删除左边空格并打印3”,而`{{-3 }}`表示“打印-3”。 + +使用这个语法,我们就可修改我们的模板,去掉新加的空白行: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + drink: {{ .Values.favorite.drink | default "tea" | quote }} + food: {{ .Values.favorite.food | upper | quote }} + {{- if eq .Values.favorite.drink "coffee" }} + mug: "true" + {{- end }} +``` + +只是为了把这一点搞清楚,我们来调整上述内容,用一个`*`来代替每个遵循此规则被删除的空白, +在行尾的`*`表示删除新行的字符: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + drink: {{ .Values.favorite.drink | default "tea" | quote }} + food: {{ .Values.favorite.food | upper | quote }}* +**{{- if eq .Values.favorite.drink "coffee" }} + mug: "true"* +**{{- end }} + +``` + +记住这一点,我们可以通过Helm运行模板并查看结果: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: clunky-cat-configmap +data: + myvalue: "Hello World" + drink: "coffee" + food: "PIZZA" + mug: "true" +``` + +要注意这个删除字符的更改,很容易意外地出现情况: + +```yaml + food: {{ .Values.favorite.food | upper | quote }} + {{- if eq .Values.favorite.drink "coffee" -}} + mug: "true" + {{- end -}} + +``` + +这样会变成`food: "PIZZA"mug:"true"`,因为这把两边的新行都删除了。 + +> 关于模板中的空白控制,请查看[官方Go模板文档](https://godoc.org/text/template) + +最终,有时这更容易告诉模板系统如何缩进,而不是试图控制模板指令间的间距。因此,您有时会发现使用`indent`方法(`{{ indent 2 +"mug:true" }}`)会很有用。 + +## 修改使用`with`的范围 + +下一个控制结构是`with`操作。这个用来控制变量范围。回想一下,`.`是对 _当前作用域_ 的引用。因此 +`.Values`就是告诉模板在当前作用域查找`Values`对象。 + +`with`的语法与`if`语句类似: + +```yaml +{{ with PIPELINE }} + # restricted scope +{{ end }} +``` + +作用域可以被改变。`with`允许你为特定对象设定当前作用域(`.`)。比如,我们已经在使用`.Values.favorite`。 +修改配置映射中的`.`的作用域指向`.Values.favorite`: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + {{- with .Values.favorite }} + drink: {{ .drink | default "tea" | quote }} + food: {{ .food | upper | quote }} + {{- end }} +``` + +注意我们从之前的练习中移除了`if`条件,因为现在不需要了——`with`后面的块只有在 `PIPELINE` 的值不为空时才会执行。 + +注意现在我们可以引用`.drink`和`.food`了,而不必限定他们。因为`with`语句设置了`.`指向`.Values.favorite`。 +`.`被重置为`{{ end }}`之后的上一个作用域。 + +但是这里有个注意事项,在限定的作用域内,无法使用`.`访问父作用域的对象。错误示例如下: + +```yaml + {{- with .Values.favorite }} + drink: {{ .drink | default "tea" | quote }} + food: {{ .food | upper | quote }} + release: {{ .Release.Name }} + {{- end }} +``` + +这样会报错因为`Release.Name`不在`.`限定的作用域内。但是如果对调最后两行就是正常的, +因为在`{{ end }}`之后作用域被重置了。 + +```yaml + {{- with .Values.favorite }} + drink: {{ .drink | default "tea" | quote }} + food: {{ .food | upper | quote }} + {{- end }} + release: {{ .Release.Name }} +``` + +或者,我们可以使用`$`从父作用域中访问`Release.Name`对象。当模板开始执行后`$`会被映射到根作用域,且执行过程中不会更改。 +下面这种方式也可以正常工作: + +```yaml + {{- with .Values.favorite }} + drink: {{ .drink | default "tea" | quote }} + food: {{ .food | upper | quote }} + release: {{ $.Release.Name }} + {{- end }} +``` + +在介绍了`range`之后,我们会看看模板变量,提供了上述作用域问题的另一种解决方案。 + +## 使用`range`操作循环 + +很多编程语言支持使用`for`循环,`foreach`循环,或者类似的方法机制。 +在Helm的模板语言中,在一个集合中迭代的方式是使用`range`操作符。 + +开始之前,我们先在`values.yaml`文件添加一个披萨的配料列表: + +```yaml +favorite: + drink: coffee + food: pizza +pizzaToppings: + - mushrooms + - cheese + - peppers + - onions +``` + +现在我们有了一个`pizzaToppings`列表(模板中称为切片)。修改模板把这个列表打印到配置映射中: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + {{- with .Values.favorite }} + drink: {{ .drink | default "tea" | quote }} + food: {{ .food | upper | quote }} + {{- end }} + toppings: |- + {{- range .Values.pizzaToppings }} + - {{ . | title | quote }} + {{- end }} + +``` + +我可以使用`$`从父作用域访问`Values.pizzaToppings`列表。当模板开始执行后`$`会被映射到根作用域, +且执行过程中不会更改。下面这种方式也可以正常工作: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + {{- with .Values.favorite }} + drink: {{ .drink | default "tea" | quote }} + food: {{ .food | upper | quote }} + toppings: |- + {{- range $.Values.pizzaToppings }} + - {{ . | title | quote }} + {{- end }} + {{- end }} +``` + +让我们仔细看看`toppings:`列表。`range`方法“涵盖”(迭代)`pizzaToppings`列表。但现在发生了有意思的事情。 +就像`with`设置了`.`的作用域,`range`操作符也做了同样的事。每一次循环,`.`都会设置为当前的披萨配料。 +也就是说,第一次`.`设置成了`mushrooms`,第二次迭代设置成了`cheese`,等等。 + +我们可以直接发送`.`的值给管道,因此当我们执行`{{ . | title | quote }}`时,它会发送`.`到`title`然后发送到`quote`。 +如果执行这个模板,输出是这样的: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: edgy-dragonfly-configmap +data: + myvalue: "Hello World" + drink: "coffee" + food: "PIZZA" + toppings: |- + - "Mushrooms" + - "Cheese" + - "Peppers" + - "Onions" +``` + +现在,我们已经处理了一些棘手的事情。`toppings: |-`行是声明的多行字符串。所以这个配料列表实际上不是YAML列表, +是个大字符串。为什么要这样做?因为在配置映射`data`中的数据是由键值对组成,key和value都是简单的字符串。 +要理解这个示例,请查看[Kubernetes ConfigMap 文档](https://kubernetes.io/docs/user-guide/configmap/)。 +但对于我们来说,这个细节并不重要。 + +> 正如例子中所示,`|-`标识在YAML中是指多行字符串。这在清单列表中嵌入大块数据是很有用的技术。 + +有时能在模板中快速创建列表然后迭代很有用,Helm模板的`tuple`可以很容易实现该功能。在计算机科学中, +元组表示一个有固定大小的类似列表的集合,但可以是任意数据类型。这大致表达了`tuple`的用法。 + +```yaml + sizes: |- + {{- range tuple "small" "medium" "large" }} + - {{ . }} + {{- end }} +``` + +上述模板会生成以下内容: + +```yaml + sizes: |- + - small + - medium + - large +``` + +除了列表和元组,`range`可被用于迭代有键值对的集合(像`map`或`dict`)。我们会在下一部分介绍模板变量是看到它是如何应用的。 diff --git a/content/zh/docs/chart_template_guide/data_types.md b/content/zh/docs/chart_template_guide/data_types.md new file mode 100644 index 0000000000..abf2b43916 --- /dev/null +++ b/content/zh/docs/chart_template_guide/data_types.md @@ -0,0 +1,19 @@ +--- +title: "附录:Go 数据类型和模板" +description: "模板中变量的简单概述。" +weight: 17 +--- + +Helm 模板语言是用强类型Go编程语言实现的。 因此,模板中的变量是 _有类型的_。大多数情况下,变量将作为以下类型之一显示: + +- string: 文本字符串 +- bool: `true` 或 `false` +- int: 整型值(包含8位,16位,32位,和64有符号和无符号整数) +- float64: 64位浮点数(也有8位,16位,32位类型) +- 字节切片(`[]byte`),一般用于保存(可能的)二进制数据 +- struct: 有属性和方法的对象 +- 上述某种类型的切片(索引列表) +- 字符串键map (`map[string]interface{}`) 值是上述某种类型 + +Go里面有很多其他类型,有时你需要在模板里转换。调试对象类型最简便的方式是在模板中传递给`printf "%t"`,这样会打印类型。 +也可以使用 `typeOf` 和 `kindOf` 函数。 diff --git a/content/zh/docs/chart_template_guide/debugging.md b/content/zh/docs/chart_template_guide/debugging.md new file mode 100644 index 0000000000..66c06b08d5 --- /dev/null +++ b/content/zh/docs/chart_template_guide/debugging.md @@ -0,0 +1,33 @@ +--- +title: "调试模板" +description: "对部署失败的chart进行故障排除" +weight: 14 +--- + +调试模板可能很棘手,因为渲染后的模板发送给了Kubernetes API server,可能会以格式化以外的原因拒绝YAML文件。 + +以下命令有助于调试: + +- `helm lint` 是验证chart是否遵循最佳实践的首选工具。 +- `helm template --debug` 在本地测试渲染chart模板。 +- `helm install --dry-run --debug`:我们已经看到过这个技巧了,这是让服务器渲染模板的好方法,然后返回生成的清单文件。 +- `helm get manifest`: 这是查看安装在服务器上的模板的好方法。 + +当你的YAML文件解析失败,但你想知道生成了什么,检索YAML一个简单的方式是注释掉模板中有问题的部分, +然后重新运行 `helm install --dry-run --debug`: + +```yaml +apiVersion: v2 +# some: problem section +# {{ .Values.foo | quote }} +``` + +以上内容会被渲染同时返回完整的注释: + +```yaml +apiVersion: v2 +# some: problem section +# "bar" +``` + +这样就提供了一种快速查看没有被YAML错误解析阻塞的生成内容的方式。 diff --git a/content/zh/docs/chart_template_guide/function_list.md b/content/zh/docs/chart_template_guide/function_list.md new file mode 100644 index 0000000000..1cbc7430a8 --- /dev/null +++ b/content/zh/docs/chart_template_guide/function_list.md @@ -0,0 +1,1929 @@ +--- +title: "模板函数列表" +description: "Helm中模板函数变量的列表" +weight: 6 +--- + +Helm 包含了很多可以在模板中利用的模板函数。以下列出了具体分类: + +* [Cryptographic and Security](#cryptographic-and-security-functions) +* [Date](#date-functions) +* [Dictionaries](#dictionaries-and-dict-functions) +* [Encoding](#encoding-functions) +* [File Path](#file-path-functions) +* [Kubernetes and Chart](#kubernetes-and-chart-functions) +* [Logic and Flow Control](#logic-and-flow-control-functions) +* [Lists](#lists-and-list-functions) +* [Math](#math-functions) +* [Network](#network-functions) +* [Reflection](#reflection-functions) +* [Regular Expressions](#regular-expressions) +* [Semantic Versions](#semantic-version-functions) +* [String](#string-functions) +* [Type Conversion](#type-conversion-functions) +* [URL](#url-functions) +* [UUID](#uuid-functions) + +## Logic and Flow Control Functions + +Helm 包括了需要逻辑和流控制函数,包括[and](#and),[coalesce](#coalesce), [default](#default), +[empty](#empty), [eq](#eq),[fail](#fail), [ge](#ge), [gt](#gt), [le](#le), [lt](#lt), +[ne](#ne), [not](#not), and [or](#or)。 + +### and + +返回两个参数的and布尔值。 + +```yaml +and .Arg1 .Arg2 +``` + +### or + +返回两个参数的or布尔值。会返回第一个非空参数或最后一个参数。 + +```yaml +or .Arg1 .Arg2 +``` + +### not + +返回参数的布尔求反。 + +```yaml +not .Arg +``` + +### eq + +返回参数的布尔等式(比如, Arg1 == Arg2)。 + +```yaml +eq .Arg1 .Arg2 +``` + +### ne + +返回参数的布尔非等式(比如 Arg1 != Arg2)。 + +```yaml +ne .Arg1 .Arg2 +``` + +### lt + +如果第一参数小于第二参数,返回布尔真。否则返回假(比如, Arg1 < Arg2)。 + +```yaml +lt .Arg1 .Arg2 +``` + +### le + +如果第一参数小于等于第二参数,返回布尔真,否则返回假(比如, Arg1 <= Arg2)。 + +```yaml +le .Arg1 .Arg2 +``` + +### gt + +如果第一参数大于第二参数,返回布尔真,否则返回假(比如, Arg1 > Arg2)。 + +```yaml +gt .Arg1 .Arg2 +``` + +### ge + +如果第一参数大于等于第二参数,返回布尔真,否则返回假。(比如, Arg1 >= Arg2)。 + +```yaml +ge .Arg1 .Arg2 +``` + +### default + +使用`default`设置一个简单的默认值。 + +```yaml +default "foo" .Bar +``` + +上述示例中,如果`.Bar`是非空值,则使用它,否则会返回`foo`。 + +"空"定义取决于以下类型: + +* 整型: 0 +* 字符串: "" +* 列表: `[]` +* 字典: `{}` +* 布尔: `false` +* 以及所有的`nil` (或 null) + +对于结构体,没有空的定义,所以结构体从来不会返回默认值。 + +### empty + +如果给定的值被认为是空的,则`empty`函数返回`true`,否则返回`false`。空值列举在`default`部分。 + +```yaml +empty .Foo +``` + +注意在Go模板条件中,空值是为你计算出来的。这样你很少需要 `if not empty .Foo` ,仅使用 `if .Foo` 即可。 + +### fail + +无条件地返回带有指定文本的空 `string` 或者 `error`。这在其他条件已经确定而模板渲染应该失败的情况下很有用。 + +```yaml +fail "Please accept the end user license agreement" +``` + +### coalesce + +`coalesce`函数获取一个列表并返回第一个非空值。 + +```yaml +coalesce 0 1 2 +``` + +上述会返回`1`。 + +此函数用于扫描多个变量或值: + +```yaml +coalesce .name .parent.name "Matt" +``` + +上述示例会优先检查 `.name` 是否为空。如果不是,就返回值。如果 _是_ 空, 继续检查`.parent.name`。 +最终,如果 `.name` 和 `.parent.name` 都是空,就会返回 `Matt`。 + +### ternary + +`ternary`函数获取两个值和一个test值。如果test值是true,则返回第一个值。如果test值是空,则返回第二个值。 +这和C或其他编程语言中的的ternary运算符类似。 + +#### true test value + +```yaml +ternary "foo" "bar" true +``` + +或者 + +```yaml +true | ternary "foo" "bar" +``` + +上述返回 `"foo"`。 + +#### false test value + +```yaml +ternary "foo" "bar" false +``` + +或者 + +```yaml +false | ternary "foo" "bar" +``` + +上述返回 `"bar"`. + +## String Functions + +Helm 包含了一下字符串函数: [abbrev](#abbrev), +[abbrevboth](#abbrevboth), [camelcase](#camelcase), [cat](#cat), +[contains](#contains), [hasPrefix](#hasprefix-and-hassuffix), +[hasSuffix](#hasprefix-and-hassuffix), [indent](#indent), [initials](#initials), +[kebabcase](#kebabcase), [lower](#lower), [nindent](#nindent), +[nospace](#nospace), [plural](#plural), [print](#print), [printf](#printf), +[println](#println), [quote](#quote-and-squote), +[randAlpha](#randalphanum-randalpha-randnumeric-and-randascii), +[randAlphaNum](#randalphanum-randalpha-randnumeric-and-randascii), +[randAscii](#randalphanum-randalpha-randnumeric-and-randascii), +[randNumeric](#randalphanum-randalpha-randnumeric-and-randascii), +[repeat](#repeat), [replace](#replace), [shuffle](#shuffle), +[snakecase](#snakecase), [squote](#quote-and-squote), [substr](#substr), +[swapcase](#swapcase), [title](#title), [trim](#trim), [trimAll](#trimall), +[trimPrefix](#trimprefix), [trimSuffix](#trimsuffix), [trunc](#trunc), +[untitle](#untitle), [upper](#upper), [wrap](#wrap), 和 [wrapWith](#wrapwith) + +### print + +返回各部分组合的字符串。 + +```yaml +print "Matt has " .Dogs " dogs" +``` + +如果可能,非字符串类型会被转换成字符串。 + +注意,当相邻两个参数不是字符串时会在它们之间添加一个空格。 + +### println + +和[print](#print)效果一样,但会在末尾新添加一行。 + +### printf + +返回参数按顺序传递的格式化字符串。 + +```yaml +printf "%s has %d dogs." .Name .NumberDogs +``` + +占位符取决于传入的参数类型。这包括: + +一般用途: + +* `%v` 默认格式的值 + * 当打印字典时,加号参数(`%+v`)可以添加字段名称 +* `%%` 字符百分号,不使用值 + +布尔值: + +* `%t` true或false + +整型: + +* `%b` 二进制 +* `%c` the character represented by the corresponding Unicode code point +* `%d` 十进制 +* `%o` 8进制 +* `%O` 带0o前缀的8进制 +* `%q` 安全转义的单引号字符 +* `%x` 16进制,使用小写字符a-f +* `%X` 16进制,使用小写字符A-F +* `%U` Unicode格式: U+1234; 和"U+%04X"相同 + +浮点数和复杂成分 + +* `%b` 指数二次幂的无小数科学计数法,比如 -123456p-78 +* `%e` 科学计数法,比如: -1.234456e+78 +* `%E` 科学计数法,比如: -1.234456E+78 +* `%f` 无指数的小数,比如: 123.456 +* `%F` 与%f同义 +* `%g` %e的大指数,否则是%f +* `%G` %E的大指数,否则是%F +* `%x` 十六进制计数法(和两个指数的十进制幂),比如: -0x1.23abcp+20 +* `%X` 大写的十六进制计数法,比如: -0X1.23ABCP+20 + +字符串和字节切片: + +* `%s` 未解析的二进制字符串或切片 +* `%q` 安全转义的双引号字符串 +* `%x` 十六进制,小写,每个字节两个字符 +* `%X` 十六进制,大写,每个字节两个字符 + +切片: + +* `%p` 16进制的第0个元素的地址,以0x开头 + +### trim + +`trim`行数移除字符串两边的空格: + +```yaml +trim " hello " +``` + +上述结果为: `hello` + +### trimAll + +从字符串中移除给定的字符: + +```yaml +trimAll "$" "$5.00" +``` + +上述结果为:`5.00` (作为一个字符串)。 + +### trimPrefix + +从字符串中移除前缀: + +```yaml +trimPrefix "-" "-hello" +``` + +上述结果为:`hello` + +### trimSuffix + +从字符串中移除后缀: + +```yaml +trimSuffix "-" "hello-" +``` + +上述结果为: `hello` + +### lower + +将整个字符串转换成小写: + +```yaml +lower "HELLO" +``` + +上述结果为: `hello` + +### upper + +将整个字符串转换成大写: + +```yaml +upper "hello" +``` + +上述结果为: `HELLO` + +### title + +首字母转换成大写: + +```yaml +title "hello world" +``` + +上述结果为: `Hello World` + +### untitle + +移除首字母大写:`untitle "Hello World"` 会得到 `hello world`. + +### repeat + +重复字符串多次: + +```yaml +repeat 3 "hello" +``` + +上述结果为: `hellohellohello` + +### substr + +获取字符串的子串,有三个参数: + +* start (int) +* end (int) +* string (string) + +```yaml +substr 0 5 "hello world" +``` + +上述结果为: `hello` + +### nospace + +去掉字符串中的所有空格: + +```yaml +nospace "hello w o r l d" +``` + +上述结果为: `helloworld` + +### trunc + +截断字符串。 + +```yaml +trunc 5 "hello world" +``` + +上述结果为: `hello`. + +```yaml +trunc -5 "hello world" +``` + +上述结果为: `world`. + +### abbrev + +用省略号截断字符串 (`...`) + +参数: + +* 最大长度 +* 字符串 + +```yaml +abbrev 5 "hello world" +``` + +上述结果为: `he...`, 因为将省略号算进了长度中。 + +### abbrevboth + +两边都省略 + +```yaml +abbrevboth 5 10 "1234 5678 9123" +``` + +上述结果为: `...5678...` + +It takes: + +* 左侧偏移值 +* 最大长度 +* 字符串 + +### initials + +截取给定字符串每个单词的首字母,并组合在一起。 + +```yaml +initials "First Try" +``` + +上述结果为: `FT` + +### randAlphaNum, randAlpha, randNumeric, and randAscii + +这四个字符串生成加密安全的(使用 ```crypto/rand```)的随机字符串,但是字符集合不同: + +* `randAlphaNum` 使用 `0-9a-zA-Z` +* `randAlpha` 使用 `a-zA-Z` +* `randNumeric` 使用 `0-9` +* `randAscii` 使用所有的可打印ASCII字符 + +每个函数都需要一个参数:字符串的整型长度 + +```yaml +randNumeric 3 +``` + +上述会生成三个数字的字符串。 + +### wrap + +以给定列数给文字换行。 + +```yaml +wrap 80 $someText +``` + +上述结果会以`$someText`在80列处换行。 + +### wrapWith + +`wrapWith` 和 `wrap` 类似,但可以以指定字符串换行。(`wrap` 使用的是 `\n`) + +```yaml +wrapWith 5 "\t" "Hello World" +``` + +上述结果为: `hello world` (其中空格是ASCII tab字符) + +### contains + +测试字符串是否包含在另一个字符串中: + +```yaml +contains "cat" "catch" +``` + +上述结果为: `true` 因为 `catch` 包含了 `cat`. + +### hasPrefix and hasSuffix + +`hasPrefix` 和 `hasSuffix` 函数测试字符串是否有给定的前缀或后缀: + +```yaml +hasPrefix "cat" "catch" +``` + +上述结果为: `true` 因为 `catch` 有 `cat`. + +### quote and squote + +该函数将字符串用双引号(`quote`) 或者单引号(`squote`)括起来。 + +### cat + +`cat` 函数将多个字符串合并成一个,用空格分隔: + +```yaml +cat "hello" "beautiful" "world" +``` + +上述结果为: `hello beautiful world` + +### indent + +`indent` 以指定长度缩进给定字符串所在行,在对齐多行字符串时很有用: + +```yaml +indent 4 $lots_of_text +``` + +上述结果会将每行缩进4个空格。 + +### nindent + +`nindent` 函数和indent函数一样,但可以在字符串开头添加新行。 + +```yaml +nindent 4 $lots_of_text +``` + +上述结果会在字符串所在行缩进4个字符,并且在开头新添加一行。 + +### replace + +执行简单的字符串替换。 + +需要三个参数 + +* 待替换字符串 +* 要替换字符串 +* 源字符串 + +```yaml +"I Am Henry VIII" | replace " " "-" +``` + +上述结果为: `I-Am-Henry-VIII` + +### plural + +字符串复数化。 + +```yaml +len $fish | plural "one anchovy" "many anchovies" +``` + +如上,如果字符串长度为1,则第一个参数会被打印(`one anchovy`)。否则,会打印第二个参数(`many anchovies`)。 + +参数包括: + +* 单数字符串 +* 复数字符串 +* 整型长度 + +注意: Helm 现在不支持多语言复杂的复数规则。`0`被认为是复数的因为英文中作为(`zero anchovies`) 对待。 + +### snakecase + +将驼峰写法转换成蛇形写法。 + +```yaml +snakecase "FirstName" +``` + +上述结果为: `first_name`. + +### camelcase + +将字符串从蛇形写法转换成驼峰写法。 + +```yaml +camelcase "http_server" +``` + +上述结果为: `HttpServer`。 + +### kebabcase + +将驼峰写法转换成烤串写法。 + +```yaml +kebabcase "FirstName" +``` + +上述结果为: `first-name`. + +### swapcase + +基于单词的算法切换字符串的大小写。 + +转换算法: + +* 大写字符变成小写字母 +* 首字母变成小写字母 +* 空格后或开头的小写字母转换成大写字母 +* 其他小写字母转换成大写字母 +* 通过unicode.IsSpace(char)定义空格 + +```yaml +swapcase "This Is A.Test" +``` + +上述结果为: `tHIS iS a.tEST`. + +### shuffle + +对字符串进行洗牌。 + +```yaml +shuffle "hello" +``` + +上述`hello`的随机字符串可能会是`oelhl`。 + +## Type Conversion Functions + +Helm提供了以下类型转换函数: + +* `atoi`: 字符串转换成整型。 +* `float64`: 转换成 `float64`。 +* `int`: 按系统整型宽度转换成`int`。 +* `int64`: 转换成 `int64`。 +* `toDecimal`: 将unix八进制转换成`int64`。 +* `toString`: 转换成字符串。 +* `toStrings`: 将列表、切片或数组转换成字符串列表。 +* `toJson` (`mustToJson`): 将列表、切片、数组、字典或对象转换成JSON。 +* `toPrettyJson` (`mustToPrettyJson`): 将列表、切片、数组、字典或对象转换成格式化JSON。 +* `toRawJson` (`mustToRawJson`): 将列表、切片、数组、字典或对象转换成HTML字符未转义的JSON。 +* `fromYaml`:将YAML字符串转化成对象。 +* `fromJson`: 将JSON字符串转化成对象。 +* `toYaml`: 将列表,切片,数组,字典或对象转换成已缩进的yaml,可以从任意源拷贝yaml块。该功能和Go的yaml.Marshal函数一样,文档详见:https://pkg.go.dev/gopkg.in/yaml.v2#Marshal + +只有`atoi`需要输入一个特定的类型。其他的会尝试将任何类型转换成目标类型。比如,`int64`可以把浮点数转换成整型,也可以把字符串转换成整型。 + +### toStrings + +给定一个类列表集合,输出字符串切片。 + +```yaml +list 1 2 3 | toStrings +``` + +上述会将`1`转成`"1"`,`2`转成`"2"`,等等,然后将其作为列表返回。 + +### toDecimal + +给定一个unix八进制权限,转换成十进制。 + +```yaml +"0777" | toDecimal +``` + +上述会将 `0777` 转换成 `511` 并返回int64的值。 + +### toJson, mustToJson + +`toJson`函数将内容编码为JSON字符串。如果内容无法被转换成JSON会返回空字符串。`mustToJson`会返回错误以防无法编码成JSON。 + +```yaml +toJson .Item +``` + +上述结果为: `.Item`的JSON字符串表示。 + +### toPrettyJson, mustToPrettyJson + +`toPrettyJson`函数将内容编码为好看的(缩进的)JSON字符串。 + +```yaml +toPrettyJson .Item +``` + +上述结果为: `.Item`的已缩进的JSON字符串表示。 + +### toRawJson, mustToRawJson + +`toRawJson` 函数将内容编码成包含非转义HTML字符的JSON字符串。 + +```yaml +toRawJson .Item +``` + +上述结果为: `.Item`的非转义的JSON字符串表示。 + +### fromYaml + +`fromYaml` 函数将YAML字符串转换成模板可用的对象。 + +`文件位置: yamls/person.yaml` + +```yaml +name: Bob +age: 25 +hobbies: + - hiking + - fishing + - cooking +``` + +```yaml +{{- $person := .Files.Get "yamls/person.yaml" | fromYaml }} +greeting: | + Hi, my name is {{ $person.name }} and I am {{ $person.age }} years old. + My hobbies are {{ range $person.hobbies }}{{ . }} {{ end }}. +``` + +### fromJson + +`fromJson` 函数将JSON字符串转换成模板可用的对象。 + +`文件位置: jsons/person.json` + +```json +{ + "name": "Bob", + "age": 25, + "hobbies": [ + "hiking", + "fishing", + "cooking" + ] +} +``` + +```yaml +{{- $person := .Files.Get "jsons/person.json" | fromJson }} +greeting: | + Hi, my name is {{ $person.name }} and I am {{ $person.age }} years old. + My hobbies are {{ range $person.hobbies }}{{ . }} {{ end }}. +``` + +## Regular Expressions + +Helm 包含以下正则表达式函数 [regexFind(mustRegexFind)](#regexfindall-mustregexfindall), +[regexFindAll(mustRegexFindAll)](#regexfind-mustregexfind), [regexMatch +(mustRegexMatch)](#regexmatch-mustregexmatch), [regexReplaceAll +(mustRegexReplaceAll)](#regexreplaceall-mustregexreplaceall), +[regexReplaceAllLiteral(mustRegexReplaceAllLiteral)](#regexreplaceallliteral-mustregexreplaceallliteral), +[regexSplit (mustRegexSplit)](#regexsplit-mustregexsplit)。 + +### regexMatch, mustRegexMatch + +如果输入字符串包含可匹配正则表达式任意字符串,则返回true。 + +```yaml +regexMatch "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$" "test@acme.com" +``` + +上述结果为: `true` + +`regexMatch`有问题时会出错, `mustRegexMatch`有问题时会向模板引擎返回错误。 + +### regexFindAll, mustRegexFindAll + +返回输入字符串匹配正则表达式的所有切片。最后一个参数表示要返回的子字符串的数量,-1表示返回所有。 + +```yaml +regexFindAll "[2,4,6,8]" "123456789" -1 +``` + +上述结果为: `[2 4 6 8]` + +`regexFindAll` 有问题时会出错, `mustRegexFindAll` 有问题时会向模板引擎返回错误。 + +### regexFind, mustRegexFind + +返回输入字符串的第一个 (最左边的) 正则匹配。 + +```yaml +regexFind "[a-zA-Z][1-9]" "abcd1234" +``` + +上述结果为: `d1` + +`regexFind` 有问题时会出错, `mustRegexFind` 有问题时会向模板引擎返回错误。 + +### regexReplaceAll, mustRegexReplaceAll + +返回输入字符串的拷贝,用替换字符串替换Regexp的匹配项。在替换字符串里面, $ 标志被解释为扩展,因此对于实例来说 $1 表示第一个子匹配的文本 + +```yaml +regexReplaceAll "a(x*)b" "-ab-axxb-" "${1}W" +``` + +上述结果为: `-W-xxW-` + +`regexReplaceAll` 有问题时会出错, `mustRegexReplaceAll` 有问题时会向模板引擎返回错误。 + +### regexReplaceAllLiteral, mustRegexReplaceAllLiteral + +返回输入字符串的拷贝,用替换字符串替换Regexp的匹配项。匹配字符串直接替换而不是扩展。 + +```yaml +regexReplaceAllLiteral "a(x*)b" "-ab-axxb-" "${1}" +``` + +上述结果为: `-${1}-${1}-` + +`regexReplaceAllLiteral` 有问题时会出错,`mustRegexReplaceAllLiteral` 有问题时会向模板引擎返回错误。 + +### regexSplit, mustRegexSplit + +将输入字符串切成有表达式分隔的子字符串,并返回表达式匹配项之间的切片。最后一个参数`n`确定要返回的子字符串数量,`-1`表示返回所有匹配。 + +```yaml +regexSplit "z+" "pizza" -1 +``` + +上述结果为: `[pi a]` + +`regexSplit` 有问题时会出错,`mustRegexSplit` 有问题时会向模板引擎返回错误。 + +## Cryptographic and Security Functions + +Helm提供了一些高级的加密函数。包括了 [adler32sum](#adler32sum), [buildCustomCert](#buildcustomcert), +[decryptAES](#decryptaes), [derivePassword](#derivepassword),[encryptAES](#encryptaes), +[genCA](#genca), [genPrivateKey](#genprivatekey), [genSelfSignedCert](#genselfsignedcert), +[genSignedCert](#gensignedcert), [htpasswd](#htpasswd), [sha1sum](#sha1sum), 以及 [sha256sum](#sha256sum)。 + +### sha1sum + +`sha1sum`函数接收一个字符串,并计算它的SHA1摘要。 + +```yaml +sha1sum "Hello world!" +``` + +### sha256sum + +`sha256sum` 函数接收一个字符串,并计算它的SHA256摘要。 + +```yaml +sha256sum "Hello world!" +``` + +上述语句会以“ASCII包装”格式计算SHA 256 校验和,并安全打印出来。 + +### adler32sum + +`adler32sum`函数接收一个字符串,并计算它的Adler-32校验和。 + +```yaml +adler32sum "Hello world!" +``` + +### htpasswd + +`htpasswd` 函数使用`username` 和 `password` 生成一个密码的`bcrypt`哈希值。该结果可用于[Apache HTTP +Server](https://httpd.apache.org/docs/2.4/misc/password_encryptions.html#basic) 的基础认证。 + +```yaml +htpasswd "myUser" "myPassword" +``` + +注意,将密码直接存储在模板中并不安全。 + +### derivePassword + +`derivePassword` 函数可用于基于某些共享的“主密码”约束得到特定密码。这方面的算法有[详细说明](https://masterpassword.app/masterpassword-algorithm.pdf)。 + +```yaml +derivePassword 1 "long" "password" "user" "example.com" +``` + +注意,将这部分直接存储在模板中并不安全。 + +### genPrivateKey + +`genPrivateKey` 函数生成一个编码成PEM块的新私钥。 + +第一个参数会采用以下某个值: + +* `ecdsa`: 生成椭圆曲线 DSA key (P256) +* `dsa`: 生成 DSA key (L2048N256) +* `rsa`: 生成 RSA 4096 key + +### buildCustomCert + +`buildCustomCert` 函数允许自定义证书。 + +会采用以下字符串参数: + +* base64 编码PEM格式证书 +* base64 编码PEM格式私钥 + +返回包含以下属性的整数对象: + +* `Cert`:PEM编码证书 +* `Key`: PEM编码私钥 + +示例: + +```yaml +$ca := buildCustomCert "base64-encoded-ca-crt" "base64-encoded-ca-key" +``` + +注意返回的对象可以使用这个CA传递给`genSignedCert`函数进行签名。 + +### genCA + +`genCA` 函数生成一个新的,自签名的x509 证书机构。 + +会采用以下参数: + +* 主体通用名 (cn) +* 证书有效期(天) + +会返回一个包含以下属性的对象: + +* `Cert`: PEM编码证书 +* `Key`: PEM编码私钥 + +示例: + +```yaml +$ca := genCA "foo-ca" 365 +``` + +注意返回的对象可以使用这个CA传递给`genSignedCert`函数进行签名。 + +### genSelfSignedCert + +The `genSelfSignedCert` 函数生成一个新的,自签名的x509 证书。 + +会采用下列参数: + +* 主体通用名 (cn) +* 可选IP列表;可以为空 +* 可选备用DNS名称列表;可以为空 +* 证书有效期(天) + +会返回一个包含以下属性的对象: + +* `Cert`: PEM编码证书 +* `Key`: PEM编码私钥 + +示例: + +```yaml +$cert := genSelfSignedCert "foo.com" (list "10.0.0.1" "10.0.0.2") (list "bar.com" "bat.com") 365 +``` + +### genSignedCert + +`genSignedCert` 通过指定的CA签名生成一个新的, x509证书 + +会采用以下参数: + +* 主体通用名 (cn) +* 可选IP列表;可以为空 +* 可选备用DNS名称列表;可以为空 +* 证书有效期(天) +* CA (查看 `genCA`) + +示例: + +```yaml +$ca := genCA "foo-ca" 365 +$cert := genSignedCert "foo.com" (list "10.0.0.1" "10.0.0.2") (list "bar.com" "bat.com") 365 $ca +``` + +### encryptAES + +`encryptAES` 函数使用AES-256 CBC 加密文本并返回一个base64编码字符串。 + +```yaml +encryptAES "secretkey" "plaintext" +``` + +### decryptAES + +`decryptAES`函数接收一个AES-256 CBC编码的字符串并返回解密文本。 + +```yaml +"30tEfhuJSVRhpG97XCuWgz2okj7L8vQ1s6V9zVUPeDQ=" | decryptAES "secretkey" +``` + +## Date Functions + +Helm 包含以下可以在模板中使用的函数:[ago](#ago), [date](#date), [dateInZone](#dateinzone), +[dateModify(mustDateModify)](#datemodify-mustdatemodify), [duration](#duration), +[durationRound](#durationround), [htmlDate](#htmldate), +[htmlDateInZone](#htmldateinzone), [now](#now), +[toDate(mustToDate)](#todate-musttodate), and [unixEpoch](#unixepoch)。 + +### now + +当前日期/时间。和其他日期函数一起使用。 + +### ago + +`ago` 函数返回距time.Now的以秒为单位的间隔时间。 + +```yaml +ago .CreatedAt +``` + +返回`time.Duration`的字符串格式 + +```yaml +2h34m7s +``` + +### date + +`date`函数格式化日期 + +日期格式化为YEAR-MONTH-DAY: + +```yaml +now | date "2006-01-02" +``` + +日期格式化在Go中有[一些不同](https://pauladamsmith.com/blog/2011/05/go_time.html)。 + +简言之,以此为基准日期: + +```yaml +Mon Jan 2 15:04:05 MST 2006 +``` + +将其写成你想要的格式,上面的例子中,`2006-01-02` 是同一个日期,却是我们需要的格式。 + +### dateInZone + +和 `date` 一样,但是和时区一起。 + +```yaml +dateInZone "2006-01-02" (now) "UTC" +``` + +### duration + +将给定的秒数格式化为`time.Duration`。 + +这会返回 1m35s。 + +```yaml +duration 95 +``` + +### durationRound + +将给定时间舍入到最重要的单位。当`time.Time`计算为一个自某个时刻以来的时间,字符串和`time.Duration`被解析为一个时间段。 + +这会返回2h + +```yaml +durationRound "2h10m5s" +``` + +这会返回3mo + +```yaml +durationRound "2400h10m5s" +``` + +### unixEpoch + +返回`time.Time`的unix时间戳。 + +```yaml +now | unixEpoch +``` + +### dateModify, mustDateModify + +`dateModify` 给定一个修改日期并返回时间戳。 + +从当前时间减去一个小时三十分钟: + +```yaml +now | date_modify "-1.5h" +``` + +如果修改格式错误, `dateModify`会返回日期未定义。而`mustDateModify`会返回错误。 + +### htmlDate + +`htmlDate`函数用于格式化插入到HTML日期选择器输入字段的日期。 + +```yaml +now | htmlDate +``` + +### htmlDateInZone + +和htmlDate一样,但多了个时区。 + +```yaml +htmlDateInZone (now) "UTC" +``` + +### toDate, mustToDate + +`toDate` 将字符串转换成日期。第一个参数是日期格式,第二个参数是日期字符串。 +如果字符串无法转换就会返回0值。`mustToDate`以防无法转换会返回错误。 + +这在你将日期字符串转换成其他格式时很有用(使用pipe)。下面的例子会将"2017-12-31" 转换成 "31/12/2017"。 + +```yaml +toDate "2006-01-02" "2017-12-31" | date "02/01/2006" +``` + +## Dictionaries and Dict Functions + +Helm 提供了一个key/value存储类型称为`dict`("dictionary"的简称,Python中也有)。`dict`是无序类型。 + +字典的key **必须是字符串**。但值可以是任意类型,甚至是另一个`dict` 或 `list`。 + +不像`list`, `dict`不是不可变的。`set`和`unset`函数会修改字典的内容。 + +Helm 提供了以下函数支持使用字典:[deepCopy(mustDeepCopy)](#deepcopy-mustdeepcopy), +[dict](#dict), [get](#get),[hasKey](#haskey), [keys](#keys), [merge (mustMerge)](#merge-mustmerge), +[mergeOverwrite (mustMergeOverwrite)](#mergeoverwrite-mustmergeoverwrite), +[omit](#omit), [pick](#pick), [pluck](#pluck), [set](#set), [unset](#unset),和[values](#values)。 + +### dict + +通过调用`dict`函数并传递一个键值对列表创建字典。 + +下面是创建三个键值对的字典: + +```yaml +$myDict := dict "name1" "value1" "name2" "value2" "name3" "value 3" +``` + +### get + +给定一个映射和一个键,从映射中获取值。 + +```yaml +get $myDict "name1" +``` + +上述结果为: `"value1"` + +注意如果没有找到,会简单返回`""`。不会生成error。 + +### set + +使用`set`给字典添加一个键值对。 + +```yaml +$_ := set $myDict "name4" "value4" +``` + +注意`set` _返回字典_ (Go模板函数的一个要求),因此你可能需要像上面那样使用使用`$_`赋值来获取值。 + +### unset + +给定一个映射和key,从映射中删除这个key。 + +```yaml +$_ := unset $myDict "name4" +``` + +和`set`一样,需要返回字典。 + +注意,如果key没有找到,这个操作会简单返回,不会生成错误。 + +### hasKey + +`hasKey`函数会在给定字典中包含了给定key时返回`true`。 + +```yaml +hasKey $myDict "name1" +``` + +如果key没找到,会返回`false`。 + +### pluck + +`pluck` 函数给定一个键和多个映射,并获得所有匹配项的列表: + +```yaml +pluck "name1" $myDict $myOtherDict +``` + +上述会返回的`list`包含了每个找到的值(`[value1 otherValue1]`)。 + +如果key在映射中 _没有找到_ ,列表中的映射就不会有内容(并且返回列表的长度也会小于调用`pluck`的字典)。 + +如果key是 _存在的_, 但是值是空值,会插入一个值。 + +Helm模板中的一个常见用法是使用`pluck... | first` 从字典集合中获取第一个匹配的键。 + +### merge, mustMerge + +将两个或多个字典合并为一个, 目标字典优先: + +```yaml +$newdict := merge $dest $source1 $source2 +``` + +这是个深度合并操作,但不是深度拷贝操作。合并的嵌套对象是两个字典上的同一实例。如果想深度合并的同时进行深度拷贝, +合并的时候同时使用`deepCopy`函数,比如: + +```yaml +deepCopy $source | merge $dest +``` + +`mustMerge` 会返回错误,以防出现不成功的合并。 + +### mergeOverwrite, mustMergeOverwrite + +合并两个或多个字典,优先按照 **从右到左**,在目标字典中有效地覆盖值: + +给定的: + +```yaml +dst: + default: default + overwrite: me + key: true + +src: + overwrite: overwritten + key: false +``` + +会生成: + +```yaml +newdict: + default: default + overwrite: overwritten + key: false +``` + +```yaml +$newdict := mergeOverwrite $dest $source1 $source2 +``` + +这是一个深度合并操作但不是深度拷贝操作。两个字典上嵌入的对象被合并到了同一个实例中。如果你想在合并的同时进行深度拷贝, +使用`deepCopy`函数,比如: + +```yaml +deepCopy $source | mergeOverwrite $dest +``` + +`mustMergeOverwrite` 会返回错误,以防出现不成功的合并。 + +### keys + +`keys`函数会返回一个或多个`dict`类型中所有的key的`list`。由于字典是 _无序的_,key不会有可预料的顺序。 +可以使用`sortAlpha`存储。 + +```yaml +keys $myDict | sortAlpha +``` + +当提供了多个词典时,key会被串联起来。使用`uniq`函数和`sortAlpha`获取一个唯一有序的键列表。 + +```yaml +keys $myDict $myOtherDict | uniq | sortAlpha +``` + +### pick + +`pick`函数只从字典中选择给定的键,并创建一个新的`dict`。 + +```yaml +$new := pick $myDict "name1" "name2" +``` + +上述结果为: `{name1: value1, name2: value2}` + +### omit + +`omit`函数类似于`pick`,除它之外返回一个新的`dict`,所有的key _不_ 匹配给定的key。 + +```yaml +$new := omit $myDict "name1" "name3" +``` + +上述结果为: `{name2: value2}` + +### values + +`values`函数类似于`keys`,返回一个新的`list`包含源字典中所有的value(只支持一个字典)。 + +```yaml +$vals := values $myDict +``` + +上述结果为: `list["value1", "value2", "value 3"]`。注意 `values`不能保证结果的顺序;如果你需要顺序, +请使用`sortAlpha`。 + +### deepCopy, mustDeepCopy + +`deepCopy` 和 `mustDeepCopy` 函数给定一个值并深度拷贝这个值。包括字典和其他结构体。 `deepCopy`有问题时会出错, +而`mustDeepCopy`会返回一个错误给模板系统。 + +```yaml +dict "a" 1 "b" 2 | deepCopy +``` + +### 字典的内部说明 + +`dict` 在Go里是作为`map[string]interface{}`执行的。Go开发者可以传`map[string]interface{}`值给上下文, +将其作为 `dict` 提供给模板。 + +## Encoding functions + +Helm有以下编码和解码函数: + +* `b64enc`/`b64dec`: 编码或解码 Base64 +* `b32enc`/`b32dec`: 编码或解码 Base32 + +## Lists and List Functions + +Helm 提供了一个简单的`list`类型,包含任意顺序的列表。类似于数组或切片,但列表是被设计用于不可变数据类型。 + +创建一个整型列表: + +```yaml +$myList := list 1 2 3 4 5 +``` + +上述会生成一个列表 `[1 2 3 4 5]`。 + +Helm 提供了以下列表函数: [append(mustAppend)](#append-mustappend), [compact +(mustCompact)](#compact-mustcompact), [concat](#concat), +[first(mustFirst)](#first-mustfirst), [has (mustHas)](#has-musthas), [initial +(mustInitial)](#initial-mustinitial), [last (mustLast)](#last-mustlast), +[prepend (mustPrepend)](#prepend-mustprepend), [rest +(mustRest)](#rest-mustrest), [reverse (mustReverse)](#reverse-mustreverse), +[seq](#seq), [index](#index), [slice (mustSlice)](#slice-mustslice), [uniq +(mustUniq)](#uniq-mustuniq), [until](#until), [untilStep](#untilstep), 和 +[without (mustWithout)](#without-mustwithout)。 + +### first, mustFirst + +获取列表中的第一项,使用 `first`。 + +`first $myList` 返回 `1` + +`first` 有问题时会出错,`mustFirst` 有问题时会向模板引擎返回错误。 + +### rest, mustRest + +获取列表的尾部内容(除了第一项外的所有内容),使用`rest`。 + +`rest $myList` returns `[2 3 4 5]` + +`rest`有问题时会出错,`mustRest` 有问题时会向模板引擎返回错误。 + +### last, mustLast + +使用`last`获取列表的最后一项: + +`last $myList` 返回 `5`。这大致类似于反转列表然后调用`first`。 + +### initial, mustInitial + +通过返回所有元素 _但_ 除了最后一个元素来赞赏`last`。 `initial $myList` 返回 `[1 2 3 4]`。 + +`initial`有问题时会出错,但是 `mustInitial` 有问题时会向模板引擎返回错误。 + +### append, mustAppend + +在已有列表中追加一项,创建一个新的列表。 + +```yaml +$new = append $myList 6 +``` + +上述语句会设置 `$new` 为 `[1 2 3 4 5 6]`。 `$myList`会保持不变。 + +`append` 有问题时会出错,但 `mustAppend` 有问题时会向模板引擎返回错误。 + +### prepend, mustPrepend + +将元素添加到列表的前面,生成一个新的列表。 + +```yaml +prepend $myList 0 +``` + +上述语句会生成 `[0 1 2 3 4 5]`。 `$myList`会保持不变。 + +`prepend` 有问题时会出错,但 `mustPrepend` 有问题时会向模板引擎返回错误。 + +### concat + +将任意数量的列表串联成一个。 + +```yaml +concat $myList ( list 6 7 ) ( list 8 ) +``` + +上述语句会生成 `[1 2 3 4 5 6 7 8]`。 `$myList` 会保持不变。 + +### reverse, mustReverse + +反转给定的列表生成一个新列表。 + +```yaml +reverse $myList +``` + +上述语句会生成一个列表: `[5 4 3 2 1]`。 + +`reverse` 有问题时会出错,但 `mustReverse` 有问题时会向模板引擎返回错误。 + +### uniq, mustUniq + +生成一个移除重复项的列表。 + +```yaml +list 1 1 1 2 | uniq +``` + +上述语句会生成 `[1 2]` + +`uniq` 有问题时会出错,但 `mustUniq` 有问题时会向模板引擎返回错误。 + +### without, mustWithout + +`without` 函数从列表中过滤内容。 + +```yaml +without $myList 3 +``` + +上述语句会生成 `[1 2 4 5]` + +一个过滤器可以过滤多个元素: + +```yaml +without $myList 1 3 5 +``` + +这样会得到: `[2 4]` + +`without` 有问题时会出错,但 `mustWithout` 有问题时会向模板引擎返回错误。 + +### has, mustHas + +验证列表是否有特定元素。 + +```yaml +has 4 $myList +``` + +上述语句会返回 `true`, 但 `has "hello" $myList` 就会返回false。 + +`has` 有问题时会出错,但 `mustHas` 有问题时会向模板引擎返回错误。 + +### compact, mustCompact + +接收一个列表并删除空值项。 + +```yaml +$list := list 1 "a" "foo" "" +$copy := compact $list +``` + +`compact` 会返回一个移除了空值(比如, "")的新列表。 + +`compact` 有问题时会出错,但 `mustCompact` 有问题时会向模板引擎返回错误。 + +### index + +使用`index list [n]`获取列表的第n个元素。使用`index list [n] [m] ...`获取多位列表元素。 + +* `index $myList 0` 返回 `1`,同 `myList[0]` +* `index $myList 0 1` 同 `myList[0][1]` + +### slice, mustSlice + +从列表中获取部分元素,使用 `slice list [n] [m]`。等同于 `list[n:m]`. + +* `slice $myList` 返回 `[1 2 3 4 5]`。 等同于 `myList[:]`。 +* `slice $myList 3` 返回 `[4 5]`等同于 `myList[3:]`。 +* `slice $myList 1 3` 返回 `[2 3]`等同于 `myList[1:3]`。 +* `slice $myList 0 3` 返回 `[1 2 3]`等同于 `myList[:3]`。 + +`slice` 有问题时会出错,但 `mustSlice` 有问题时会向模板引擎返回错误。 + +### until + +`until` 函数构建一个整数范围。 + +```yaml +until 5 +``` + +上述语句会生成一个列表: `[0, 1, 2, 3, 4]`。 + +对循环语句很有用: `range $i, $e := until 5`。 + +### untilStep + +类似`until`, `untilStep` 生成一个可计数的整型列表。但允许你定义开始,结束和步长: + +```yaml +untilStep 3 6 2 +``` + +上述语句会生成 `[3 5]`,从3开始,每次加2,直到大于等于6。类似于Python的 `range` 函数。 + +### seq + +原理和bash的 `seq` 命令类似。 + +* 1 单个参数 (结束位置) - 会生成所有从1到包含 `end` 的整数。 +* 2 多个参数 (开始, 结束) - 会生成所有包含`start` 和 `end` 的整数,递增或者递减。 +* 3 多个参数 (开始, 步长, 结束) - 会生成所有包含 `start` 和 `end` 按 `step`递增或递减的整数。 + +```yaml +seq 5 => 1 2 3 4 5 +seq -3 => 1 0 -1 -2 -3 +seq 0 2 => 0 1 2 +seq 2 -2 => 2 1 0 -1 -2 +seq 0 2 10 => 0 2 4 6 8 10 +seq 0 -2 -5 => 0 -2 -4 +``` + +## Math Functions + +除非另外指定,否则所有的math函数都是操作 `int64` 的值。 + +有以下math函数可用: [add](#add), [add1](#add1), +[ceil](#ceil), [div](#div), [floor](#floor), [len](#len), [max](#max), +[min](#min), [mod](#mod), [mul](#mul), [round](#round), and [sub](#sub)。 + +### add + +使用`add`求和。接受两个或多个输入。 + +```yaml +add 1 2 3 +``` + +### add1 + +自增加1,使用 `add1`。 + +### sub + +相减使用 `sub`。 + +### div + +整除使用 `div`。 + +### mod + +取模使用`mod`。 + +### mul + +相乘使用`mul`。接受两个或多个输入。 + +```yaml +mul 1 2 3 +``` + +### max + +返回一组整数中最大的整数。 + +下列会返回`3`: + +```yaml +max 1 2 3 +``` + +### min + +返回一组数中最小的数。 + +`min 1 2 3` 会返回 `1`。 + +### floor + +返回小于等于输入值的最大浮点整数。 + +`floor 123.9999` will return `123.0`。 + +### ceil + +返回大于等于输入值的最小浮点整数。 + +`ceil 123.001` will return `124.0`。 + +### round + +返回一个四舍五入到给定小数位的数。 + +`round 123.555555 3` will return `123.556`。 + +### len + +以整数返回参数的长度。 + +```yaml +len .Arg +``` + +## Network Functions + +Helm提供了一个网络函数: `getHostByName`. + +`getHostByName`接收一个域名返回IP地址。 + +`getHostByName "www.google.com"`会返回对应的`www.google.com`的地址。 + +## File Path Functions + +Helm模板函数没有访问文件系统的权限,提供了遵循文件路径规范的函数。包括[base](#base), [clean](#clean), +[dir](#dir), [ext](#ext), 和 [isAbs](#isabs) 。 + +### base + +返回最后一个元素路径。 + +```yaml +base "foo/bar/baz" +``` + +返回 "baz"。 + +### dir + +返回目录, 去掉路径的最后一部分。因此 `dir "foo/bar/baz"` 返回 `foo/bar`。 + +### clean + +清除路径 + +```yaml +clean "foo/bar/../baz" +``` + +上述语句会清理 `..` 并返回`foo/baz`。 + +### ext + +返回文件扩展。 + +```yaml +ext "foo.bar" +``` + +上述结果为: `.bar`. + +### isAbs + +检查文件路径是否为绝对路径,使用 `isAbs`。 + +## Reflection Functions + +Helm 提供了基本的反射工具。这有助于高级模板开发者理解特定值的基本Go类型信息。Helm是由Go编写的且是强类型的。 +类型系统应用于模板中。 + +Go 有一些原始 _类型_,比如 `string`, `slice`, `int64`, 和 `bool`。 + +Go 有一个开放的 _类型_ 系统,允许开发者创建自己的类型。 + +Helm 通过[kind functions](#kind-functions) 和 [type +functions](#type-functions) 提供了一组函数。[deepEqual](#deepequal) 也可以用来比较值。 + +### Kind Functions + +有两个类型函数: `kindOf` 返回对象类型。 + +```yaml +kindOf "hello" +``` + +上述语句返回 `string`。对于简单测试(比如在`if`块中),`Kindis`函数可以验证值是否为特定类型: + +```yaml +kindIs "int" 123 +``` + +上述返回 `true`。 + +### Type Functions + +类型处理起来稍微有点复杂,所以有三个不同的函数: + +* `typeOf` 返回值的基础类型: `typeOf $foo` +* `typeIs` 类似 `kindIs`, 但针对type: `typeIs "*io.Buffer" $myVal` +* `typeIsLike` 类似 `typeIs`,除非取消指针引用 + +**注意:** 这些都不能测试是否实现了给定的接口,因为在这之前需要提前编译接口。 + +### deepEqual + + 如果两个值相比是["deeply equal"](https://golang.org/pkg/reflect/#DeepEqual),`deepEqual`返回true。 + +也适用于非基本类型 (相较于内置的 `eq`)。 + +```yaml +deepEqual (list 1 2 3) (list 1 2 3) +``` + +上述会返回 `true`。 + +## Semantic Version Functions + +有些版本结构易于分析和比较。Helm提供了适用于[SemVer 2](http://semver.org) 版本的函数。包括[semver](#semver)和 +[semverCompare](#semvercompare)。下面你也能看到使用范围和比较的细节。 + +### semver + +`semver`函数将字符串解析为语义版本: + +```yaml +$version := semver "1.2.3-alpha.1+123" +``` + +_如果解析失败,会由一个错误引起模板执行中断。_ + + `$version`是一个指向`Version`对象的指针,包含了一下属性: + +* `$version.Major`: 主版本号 (上面的`1`) +* `$version.Minor`: 次版本号 (上面的`2`) +* `$version.Patch`: 补丁版本号 (上面的`3`) +* `$version.Prerelease`: 预发布版本号 (上面的`alpha.1`) +* `$version.Metadata`: 构建元数据 (上面的`123`) +* `$version.Original`: 原始版本字符串 + +另外,你可以使用`Compare`函数比较一个`Version`和另一个`version`: + +```yaml +semver "1.4.3" | (semver "1.2.3").Compare +``` + +上面会返回 `-1`。 + +返回值可以是: + +* `-1` 如果给定的版本大于`Compare`方法调用的版本 +* `1` 如果`Compare`调用的版本更大 +* `0` 如果版本相同 + +(注意在语义版本中,`Metadata` 字段在版本比较时不比较) + +### semverCompare + +一个更健壮的比较函数是`semverCompare`。 这个版本支持版本范围: + +* `semverCompare "1.2.3" "1.2.3"` 检查精确匹配 +* `semverCompare "~1.2.0" "1.2.3"` 检查主要版本和次要版本,且补丁版本第二个版本是 _大于等于_ 第一个。 + +SemVer函数使用[semver规划库](https://github.com/Masterminds/semver),由Sprig作者创建。 + +### 基本比较 + +两个元素的比较。首先,比较字符串是以空格或逗号分隔的。然后以|| (OR)分隔。比如:`">= 1.2 < 3.0.0 || >= 4.2.3"` +是要比较大于等于1.2且小于等于3.0.0 或者大于等于4.2.3的。 + +基本比较符有: + +* `=`: 相等 +* `!=`: 不相等 +* `>`: 大于 +* `<`: 小于 +* `>=`: 大于等于 +* `<=`: 小于等于 + +### 使用预发布版本 + +预发布版本,对于那些不熟悉它们的人,是用于稳定版本或一般可用版本之前的软件版本。预发布版本的例子包括开发版、 +alpha版、beta版,和rc版本。稳定版`1.2.3`的预发布版本可能是`1.2.3-beta.1`,按照优先顺序,预发布版本在相关版本之前发布。 +比如:`1.2.3-beta.1 < 1.2.3` 。 + +根据语义版本指定的预发布版本可能不与对应的发行版本兼容。 + +> 预发布版本表示版本不稳定且可能不满足其相关正常版本所表示的预期兼容性要求。 + +使用不带预发布版本比较器约束的语义版本的比较会跳过预发布版本。比如 `>=1.2.3` 会跳过预发布而`>=1.2.3-0`会计算并查找预发布版本。 + +按照规范,上例中的`0`作为预发布的版本是因为预发布版本只能包含ASCII字母数字和连字符(以及`.`分隔符), +with `.` separators),另外排序按照ASCII排序顺序。在ASCII排序中,最小的字符是`0`(查看[ASCII表](http://www.asciitable.com/))。 + +理解ASCII排序顺序很重要因为A-Z是在a-z之前,这意味着`>=1.2.3-BETA` 会返回 `1.2.3-alpha`。这里并不适合大小写敏感, +因为是按照ASCII排序规范指定顺序。 + +### 连字符范围比较 + +有多个方法处理范围,首先是连字符范围。像这样: + +* `1.2 - 1.4.5` 等同于 `>= 1.2 <= 1.4.5` +* `2.3.4 - 4.5` 等同于 `>= 2.3.4 <= 4.5` + +### 比较中通配符 + +`x`, `X`, 和 `*` 可用于通配符。适用于所有比较运算符。当使用`=`运算符时,会返回补丁级别的比较。比如: + +* `1.2.x` 相当于 `>= 1.2.0, < 1.3.0` +* `>= 1.2.x` 相当于 `>= 1.2.0` +* `<= 2.x` 相当于 `< 3` +* `*` 相当于 `>= 0.0.0` + +### 波浪符号范围比较 (补丁版本) + +波浪 (`~`) 比较运算符是补丁级别范围的比较,在指定次要版本和主要版本变化且没有次要版本时使,比如: + +* `~1.2.3` 相当于 `>= 1.2.3, < 1.3.0` +* `~1` 相当于 `>= 1, < 2` +* `~2.3` 相当于 `>= 2.3, < 2.4` +* `~1.2.x` 相当于 `>= 1.2.0, < 1.3.0` +* `~1.x` 相当于 `>= 1, < 2` + +### 插入符号比较 (主要版本) + +插入符(`^`)比较运算是主版本级别改变时使用。在1.0.0 发布之前,次要版本充当API稳定级别版本。 +当比较主要的API版本更改时,这很有用,比如: + +* `^1.2.3` 相当于 `>= 1.2.3, < 2.0.0` +* `^1.2.x` 相当于 `>= 1.2.0, < 2.0.0` +* `^2.3` 相当于 `>= 2.3, < 3` +* `^2.x` 相当于 `>= 2.0.0, < 3` +* `^0.2.3` 相当于 `>=0.2.3 <0.3.0` +* `^0.2` 相当于 `>=0.2.0 <0.3.0` +* `^0.0.3` 相当于 `>=0.0.3 <0.0.4` +* `^0.0` 相当于 `>=0.0.0 <0.1.0` +* `^0` 相当于 `>=0.0.0 <1.0.0` + +## URL Functions + +Helm 包含 [urlParse](#urlparse), [urlJoin](#urljoin), 和[urlquery](#urlquery) 函数可以用做处理URL。 + +### urlParse + +解析URL的字符串并生成包含URL部分的字典。 + +```yaml +urlParse "http://admin:secret@server.com:8080/api?list=false#anchor" +``` + +上述结果为: 包含URL对象的字典: + +```yaml +scheme: 'http' +host: 'server.com:8080' +path: '/api' +query: 'list=false' +opaque: nil +fragment: 'anchor' +userinfo: 'admin:secret' +``` + +这是使用Go标准库中的URL包实现的。更多信息,请查看 https://golang.org/pkg/net/url/#URL。 + +### urlJoin + +将一个映射(由`urlParse`生成的)连接成URL字符串 + +```yaml +urlJoin (dict "fragment" "fragment" "host" "host:80" "path" "/path" "query" "query" "scheme" "http") +``` + +上述结果会生成以下字符串: + +```yaml +http://host:80/path?query#fragment +``` + +### urlquery + +返回作为参数传入的值的转义版本,这样就可以嵌入到URL的查询部分。 + +```yaml +$var := urlquery "string for query" +``` + +## UUID Functions + +Helm 可以生成UUID v4 通用唯一ID。 + +```yaml +uuidv4 +``` + +上述结果为: 一个新的v4类型的UUID(随机生成)。 + +## Kubernetes and Chart Functions + +Helm 包含了用于 Kubernetes的函数,包括[.Capabilities.APIVersions.Has](#capabilitiesapiversionshas), +[Files](#file-functions), 和 [lookup](#lookup)。 + +### lookup + +`lookup` 用于在正在运行的集群中查找资源。当和`helm template`命令一起使用时会返回一个空响应。 + +可以在 [lookup函数文档](https://helm.sh/zh/docs/chart_template_guide/#using-the-lookup-function)查看更多细节。 + +### .Capabilities.APIVersions.Has + +返回API版本或资源是否在集群中可用。 + +```yaml +.Capabilities.APIVersions.Has "apps/v1" +.Capabilities.APIVersions.Has "apps/v1/Deployment" +``` + +更多信息可查看 [内置对象文档](https://helm.sh/zh/docs/chart_template_guide/builtin_objects.md)。 + +### File Functions + +有几个函数能使您能够访问chart中的非特殊文件。比如访问应用配置文件。请查看[模板中访问文件](https://helm.sh/zh/docs/chart_template_guide/accessing_files.md)。 + +_注意,这里很多函数的文档是来自[Sprig](https://github.com/Masterminds/sprig)。Sprig是一个适用于Go应用的函数模板库。_ diff --git a/content/zh/docs/chart_template_guide/functions_and_pipelines.md b/content/zh/docs/chart_template_guide/functions_and_pipelines.md new file mode 100644 index 0000000000..6b52814e66 --- /dev/null +++ b/content/zh/docs/chart_template_guide/functions_and_pipelines.md @@ -0,0 +1,212 @@ +--- +title: "模板函数和流水线" +description: "使用函数和管道" +weight: 5 +--- + +到目前为止,我们已经知道了如何将信息传到模板中。 但是传入的信息并不能被修改。 +有时我们希望以一种更有用的方式来转换所提供的数据。 + +让我们从一个最佳实践开始:可以通过调用模板指令中的`quote`函数把`.Values`对象中的字符串属性用引号引起来,然后放到模板中。 + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + drink: {{ quote .Values.favorite.drink }} + food: {{ quote .Values.favorite.food }} +``` + +模板函数的语法是 `functionName arg1 arg2...`。在上面的代码片段中,`quote .Values.favorite.drink`调用了`quote`函数并传递了一个参数(`.Values.favorite.drink`)。 + +Helm 有超过60个可用函数。其中有些通过[Go模板语言](https://godoc.org/text/template)本身定义。其他大部分都是[Sprig 模板库](https://masterminds.github.io/sprig/)。我们可以在示例看到其中很多函数。 + +> 当我们讨论"Helm模板语言"时,感觉它是Helm专属的,实际上他是Go模板语言、一些额外的函数和用于 +向模板暴露某些对象的装饰器组合而成的。很多Go模板的资料也有助于你学习模板。 + +## 管道符 + +模板语言其中一个强大功能是 **管道** 概念。借鉴UNIX中的概念,管道符是将一系列的模板语言紧凑地将多个流式处理结果合并的工具。换句话说,管道符是按顺序完成一系列任务的方式。 +现在用管道符重写上述示例: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + drink: {{ .Values.favorite.drink | quote }} + food: {{ .Values.favorite.food | quote }} +``` + +在这个示例中,并不是调用`quote 参数`,而是倒置了命令。使用管道符(`|`)将参数“发送”给函数: +`.Values.favorite.drink | quote`。使用管道符可以将很多函数链接在一起: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + drink: {{ .Values.favorite.drink | quote }} + food: {{ .Values.favorite.food | upper | quote }} +``` + +> 倒置命令是模板中的常见做法。可以经常看到 `.val | quote` 而不是 `quote .val`。实际上两种操作都是可以的。 + +模板会生成以下内容: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: trendsetting-p-configmap +data: + myvalue: "Hello World" + drink: "coffee" + food: "PIZZA" +``` + +注意原有的`pizza`现在已经被转换成了`"PIZZA"`。当管道符参数类似这样的时候,第一个表达式的结果(`.Values.favorite.drink | upper` 的结果) 作为了`quote`的最后一个参数。也可以修改上述示例,用两个参数的函数来阐述: `repeat COUNT STRING`: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + drink: {{ .Values.favorite.drink | repeat 5 | quote }} + food: {{ .Values.favorite.food | upper | quote }} +``` + +`repeat`函数会返回给定参数特定的次数,则可以得到以下结果: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: melting-porcup-configmap +data: + myvalue: "Hello World" + drink: "coffeecoffeecoffeecoffeecoffee" + food: "PIZZA" +``` + +## 使用`default`函数 + +模板中频繁使用的一个函数是`default`: `default DEFAULT_VALUE GIVEN_VALUE`。 +这个函数允许你在模板中指定一个默认值,以防这个值被忽略。现在使用它修改上述示例: + +```yaml +drink: {{ .Values.favorite.drink | default "tea" | quote }} +``` + +如果运行,会得到 `coffee`: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: virtuous-mink-configmap +data: + myvalue: "Hello World" + drink: "coffee" + food: "PIZZA" +``` + +现在,从`values.yaml`中移除设置: + +```yaml +favorite: + #drink: coffee + food: pizza +``` + +现在重新运行 `helm install --dry-run --debug fair-worm ./mychart` 会生成如下内容: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: fair-worm-configmap +data: + myvalue: "Hello World" + drink: "tea" + food: "PIZZA" +``` + +在实际的chart中,所有的静态默认值应该设置在 `values.yaml` 文件中,且不应该重复使用 `default` 命令 +(否则会出现冗余)。然而这个`default` 命令很适合计算值,其不能声明在`values.yaml`文件中,比如: + +```yaml +drink: {{ .Values.favorite.drink | default (printf "%s-tea" (include "fullname" .)) }} +``` + +有些场景,`if`条件比`default`更加适合。在下一章节我们就会看到。 + +模板函数和管道符是转换信息然后将其插入到YAML中的强有力方式。但是有些时候我们需要插入一些内容之前进行一些逻辑判断,而不仅仅是插入一个字符串。 +下一章节,我们会看到模板语言提供的控制结构。 + +## 使用`lookup`函数 + +`lookup` 函数可以用于在运行的集群中 _查找_ 资源。lookup函数简述为查找 `apiVersion, kind, namespace,name -> 资源或者资源列表`。 + +| parameter | type | +|------------|--------| +| apiVersion | string | +| kind | string | +| namespace | string | +| name | string | + +`name` 和 `namespace` 都是选填的,且可以传空字符串(`""`)作为空。 + +以下是可能的参数组合: + +| 命令 | Lookup 函数 | +|----------------------------------------|--------------------------------------------| +| `kubectl get pod mypod -n mynamespace` | `lookup "v1" "Pod" "mynamespace" "mypod"` | +| `kubectl get pods -n mynamespace` | `lookup "v1" "Pod" "mynamespace" ""` | +| `kubectl get pods --all-namespaces` | `lookup "v1" "Pod" "" ""` | +| `kubectl get namespace mynamespace` | `lookup "v1" "Namespace" "" "mynamespace"` | +| `kubectl get namespaces` | `lookup "v1" "Namespace" "" ""` | + +当`lookup`返回一个对象,它会返回一个字典。这个字典可以进一步被引导以获取特定值。 + +下面的例子将返回`mynamespace`对象的annotations属性: + +```go +(lookup "v1" "Namespace" "" "mynamespace").metadata.annotations +``` + +当`lookup`返回一个对象列表时,可以通过`items`字段访问对象列表: + +```go +{{ range $index, $service := (lookup "v1" "Service" "mynamespace" "").items }} + {{/* do something with each service */}} +{{ end }} +``` + +当对象未找到时,会返回空值。可以用来检测对象是否存在。 + +`lookup`函数使用Helm已有的Kubernetes连接配置查询Kubernetes。当与调用API服务交互时返回了错误 +(比如缺少资源访问的权限),helm 的模板操作会失败。 + +请记住,Helm在`helm template`或者`helm install|upgrade|delete|rollback --dry-run`时, +不应该请求Kubernetes API服务。由此,`lookup`函数在该案例中会返回空列表(即字典)。 + +## 运算符也是函数 + +对于模板来说,运算符(`eq`, `ne`, `lt`, `gt`, `and`, `or`等等) 都是作为函数来实现的。 +在管道符中,操作可以按照圆括号分组。 + +现在我们可以从函数和管道符返回到条件控制流,循环和范围修饰符。 diff --git a/content/zh/docs/chart_template_guide/getting_started.md b/content/zh/docs/chart_template_guide/getting_started.md new file mode 100644 index 0000000000..1c1fc448e2 --- /dev/null +++ b/content/zh/docs/chart_template_guide/getting_started.md @@ -0,0 +1,226 @@ +--- +title: "从这里开始吧" +weight: 2 +description: "Chart模板的快速指南。" + + +--- + +指南的该部分,我们会创建一个chart并添加第一个模板。创建的chart会在后续指南中用到。 + +接下来,让我们简单看一下Helm chart。 + +## Charts + +如[Charts 指南](https://helm.sh/zh/docs/topics/charts)所述, Helm chart的结构如下: + +```shell +mychart/ + Chart.yaml + values.yaml + charts/ + templates/ + ... +``` + +`templates/` 目录包括了模板文件。当Helm评估chart时,会通过模板渲染引擎将所有文件发送到`templates/`目录中。 +然后收集模板的结果并发送给Kubernetes。 + +`values.yaml` 文件也导入到了模板。这个文件包含了chart的 _默认值_ 。这些值会在用户执行`helm install` 或 `helm upgrade`时被覆盖。 + +`Chart.yaml` 文件包含了该chart的描述。你可以从模板中访问它。`charts/`目录 _可以_ 包含其他的chart(称之为 _子chart_)。 +指南稍后我们会看到当涉及模板渲染时这些是如何工作的。 + +## 入门 Chart + +在本指南中我们会创建一个名为`mychart`的chart,然后会在chart中创建一些模板。 + +```console +$ helm create mychart +Creating mychart +``` + +### 快速查看 `mychart/templates/` + +如果你看看 `mychart/templates/` 目录,会注意到一些文件已经存在了: + +- `NOTES.txt`: chart的"帮助文本"。这会在你的用户执行`helm install`时展示给他们。 +- `deployment.yaml`: 创建Kubernetes + [工作负载](https://kubernetes.io/docs/user-guide/deployments/)的基本清单 +- `service.yaml`: 为你的工作负载创建一个[service终端](https://kubernetes.io/docs/user-guide/services/)基本清单。 +- `_helpers.tpl`: 放置可以通过chart复用的模板辅助对象 + +然后我们要做的是... _把它们全部删掉!_ 这样我们就可以从头开始学习我们的教程。我们在开始时会创造自己的`NOTES.txt`和`_helpers.tpl`。 + +```console +$ rm -rf mychart/templates/* +``` + +编制生产环境级别的chart时,有这些chart的基础版本会很有用。因此在日常编写中,你可能不想删除它们。 + +## 第一个模板 + +第一个创建的模板是`ConfigMap`。Kubernetes中,配置映射只是用于存储配置数据的对象。其他组件,比如pod,可以访问配置映射中的数据。 + +因为配置映射是基础资源,对我们来说是很好的起点。 + +让我们以创建一个名为 `mychart/templates/configmap.yaml`的文件开始: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: mychart-configmap +data: + myvalue: "Hello World" +``` + +**提示:** 模板名称不遵循严格的命名模式。但是建议以`.yaml`作为YAML文件的后缀,以`.tpl`作为helper文件的后缀。 + +上述YAML文件是一个简单的配置映射,构成了最小的必需字段。因为文件在 `mychart/templates/`目录中,它会通过模板引擎传递。 + +像这样将一个普通YAML文件放在`mychart/templates/`目录中是没问题的。当Helm读取这个模板时会按照原样传递给Kubernetes。 + +有了这个简单的模板,现在有一个可安装的chart了。现在安装如下: + +```console +$ helm install full-coral ./mychart +NAME: full-coral +LAST DEPLOYED: Tue Nov 1 17:36:01 2016 +NAMESPACE: default +STATUS: DEPLOYED +REVISION: 1 +TEST SUITE: None +``` + +我们可以使用Helm检索版本并查看实际加载的模板。 + +```console +$ helm get manifest full-coral + +--- +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: mychart-configmap +data: + myvalue: "Hello World" +``` + +`helm get manifest` 命令后跟一个发布名称(`full-coral`)然后打印出了所有已经上传到server的Kubernetes资源。 +每个文件以`---`开头表示YAML文件的开头,然后是自动生成的注释行,表示哪个模板文件生成了这个YAML文档。 + +从这个地方开始,我们看到的YAML数据确实是`configmap.yaml`文件中的内容。 + +现在卸载发布: `helm uninstall full-coral`。 + +### 添加一个简单的模板调用 + +将`name:`硬编码到一个资源中不是很好的方式。名称应该是唯一的。因此我们可能希望通过插入发布名称来生成名称字段。 + +**提示:** 由于DNS系统的限制,`name:`字段长度限制为63个字符。因此发布名称限制为53个字符。 +Kubernetes 1.3及更早版本限制为24个字符 (名称长度是14个字符)。 + +对应改变一下`configmap.yaml`: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" +``` + +大的变化是`name:`字段的值,现在是`{{ .Release.Name }}-configmap`。 + +> 模板命令要括在 `{{` 和 `}}` 之间。 + +模板命令 `{{ .Release.Name }}` 将发布名称注入了模板。值作为一个 _命名空间对象_ 传给了模板,用点(`.`)分隔每个命名空间的元素。 + +`Release`前面的点表示从作用域最顶层的命名空间开始(稍后会谈作用域)。这样`.Release.Name`就可解读为“通顶层命名空间开始查找 +Release对象,然后在其中找Name对象”。 + +`Release`是一个Helm的内置对象。稍后会更深入地讨论。但现在足够说明它可以显示从库中赋值的发布名称。 + +现在安装资源,可以立即看到模板命令的结果: + +```console +$ helm install clunky-serval ./mychart +NAME: clunky-serval +LAST DEPLOYED: Tue Nov 1 17:45:37 2016 +NAMESPACE: default +STATUS: DEPLOYED +REVISION: 1 +TEST SUITE: None +``` + +可以运行`helm get manifest clunky-serval`查看生成的完整的YAML。 + +注意在kubernetes内的配置映射名称是 `clunky-serval-configmap`,而不是之前的 `mychart-configmap`。 + +由此我们已经看到了最基本的模板:YAML文件有嵌入在`{{` 和 `}}`之间的模板命令。下一部分,会深入了解模板, +但在这之前,有个快捷的技巧可以加快模板的构建速度:当你想测试模板渲染的内容但又不想安装任何实际应用时,可以使用`helm +install --debug --dry-run goodly-guppy ./mychart`。这样不会安装应用(chart)到你的kubenetes集群中,只会渲染模板内容到控制台(用于测试)。渲染后的模板如下: + +```console +$ helm install --debug --dry-run goodly-guppy ./mychart +install.go:149: [debug] Original chart version: "" +install.go:166: [debug] CHART PATH: /Users/ninja/mychart + +NAME: goodly-guppy +LAST DEPLOYED: Thu Dec 26 17:24:13 2019 +NAMESPACE: default +STATUS: pending-install +REVISION: 1 +TEST SUITE: None +USER-SUPPLIED VALUES: +{} + +COMPUTED VALUES: +affinity: {} +fullnameOverride: "" +image: + pullPolicy: IfNotPresent + repository: nginx +imagePullSecrets: [] +ingress: + annotations: {} + enabled: false + hosts: + - host: chart-example.local + paths: [] + tls: [] +nameOverride: "" +nodeSelector: {} +podSecurityContext: {} +replicaCount: 1 +resources: {} +securityContext: {} +service: + port: 80 + type: ClusterIP +serviceAccount: + create: true + name: null +tolerations: [] + +HOOKS: +MANIFEST: +--- +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: goodly-guppy-configmap +data: + myvalue: "Hello World" + +``` + +使用`--dry-run`会让你变得更容易测试,但不能保证Kubernetes会接受你生成的模板。 +最好不要仅仅因为`--dry-run`可以正常运行就觉得chart可以安装。 + +在[Chart模板指南](_index.md)中,我们以这里定义的chart基本模板为例详细讨论Helm模板语言。 +然后开始讨论内置对象。 \ No newline at end of file diff --git a/content/zh/docs/chart_template_guide/helm_ignore_file.md b/content/zh/docs/chart_template_guide/helm_ignore_file.md new file mode 100644 index 0000000000..678fe529bd --- /dev/null +++ b/content/zh/docs/chart_template_guide/helm_ignore_file.md @@ -0,0 +1,56 @@ +--- +title: ".helmignore 文件" +description: "`.helmignore` 文件用来指定你不想包含在你的helm chart中的文件。" +weight: 13 +--- + +`.helmignore` 文件用来指定你不想包含在你的helm chart中的文件。 + +如果该文件存在,`helm package` 命令会在打包应用时忽略所有在`.helmignore`文件中匹配的文件。 + +这有助于避免不需要的或敏感文件及目录添加到你的helm chart中。 + +`.helmignore` 文件支持Unix shell的全局匹配,相对路径匹配,以及反向匹配(以!作为前缀)。每行只考虑一种模式。 + +这里是一个`.helmignore`文件示例: + +```shell +# comment + +# Match any file or path named .helmignore +.helmignore + +# Match any file or path named .git +.git + +# Match any text file +*.txt + +# Match only directories named mydir +mydir/ + +# Match only text files in the top-level directory +/*.txt + +# Match only the file foo.txt in the top-level directory +/foo.txt + +# Match any file named ab.txt, ac.txt, or ad.txt +a[b-d].txt + +# Match any file under subdir matching temp* +*/temp* + +*/*/temp* +temp? +``` + +一些值得注意的和.gitignore不同之处: + +- 不支持'**'语法。 +- globbing库是Go的 'filepath.Match',不是fnmatch(3) +- 末尾空格总会被忽略(不支持转义序列) +- 不支持'\!'作为特殊的引导序列 +- 默认不会排除自身,需要显式添加 `.helmignore` + +**我们需要你的帮助** 使该文档更好。添加、修正或移除信息, [提交问题](https://github.com/helm/helm-www/issues) 或者发起PR。 diff --git a/content/zh/docs/chart_template_guide/named_templates.md b/content/zh/docs/chart_template_guide/named_templates.md new file mode 100644 index 0000000000..253b2d774a --- /dev/null +++ b/content/zh/docs/chart_template_guide/named_templates.md @@ -0,0 +1,301 @@ +--- +title: "命名模板" +description: "如何定义命名模板" +weight: 9 +--- + +此时需要越过模板,开始创建其他内容了。该部分我们会看到如何在一个文件中定义 +_命名模板_,并在其他地方使用。_命名模板_ (有时称作一个 _部分_ 或一个 +_子模板_)仅仅是在文件内部定义的模板,并使用了一个名字。有两种创建方式和几种不同的使用方法。 + +在[流控制](https://helm.sh/zh/docs/chart_template_guide/control_structures)部分, +我们介绍了三种声明和管理模板的方法:`define`,`template`,和`block`。在这部分,我们将使用这三种操作并介绍一种特殊用途的 +`include`方法,类似于`template`操作。 + +命名模板时要记住一个重要细节:**模板名称是全局的**。如果您想声明两个相同名称的模板,哪个最后加载就使用哪个。 +因为在子chart中的模板和顶层模板一起编译,命名时要注意 _chart特定名称_。 + +一个常见的命名惯例是用chart名称作为模板前缀:`{{ define "mychart.labels" }}`。使用特定chart名称作为前缀可以避免可能因为 +两个不同chart使用了相同名称的模板而引起的冲突。 + +## 局部的和`_`文件 + +目前为止,我们已经使用了单个文件,且单个文件中包含了单个模板。但Helm的模板语言允许你创建命名的嵌入式模板, +这样就可以在其他位置按名称访问。 + +在编写模板细节之前,文件的命名惯例需要注意: + +* `templates/`中的大多数文件被视为包含Kubernetes清单 +* `NOTES.txt`是个例外 +* 命名以下划线(`_`)开始的文件则假定 _没有_ 包含清单内容。这些文件不会渲染为Kubernetes对象定义,但在其他chart模板中都可用。 + +这些文件用来存储局部和辅助对象,实际上当我们第一次创建`mychart`时,会看到一个名为`_helpers.tpl`的文件,这个文件是模板局部的默认位置。 + +## 用`define`和`template`声明和使用模板 + +`define`操作允许我们在模板文件中创建一个命名模板,语法如下: + +```yaml +{{- define "MY.NAME" }} + # body of template here +{{- end }} +``` + +比如我们可以定义一个模板封装Kubernetes的标签: + +```yaml +{{- define "mychart.labels" }} + labels: + generator: helm + date: {{ now | htmlDate }} +{{- end }} +``` + +现在我们将模板嵌入到了已有的配置映射中,然后使用`template`包含进来: + +```yaml +{{- define "mychart.labels" }} + labels: + generator: helm + date: {{ now | htmlDate }} +{{- end }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap + {{- template "mychart.labels" }} +data: + myvalue: "Hello World" + {{- range $key, $val := .Values.favorite }} + {{ $key }}: {{ $val | quote }} + {{- end }} +``` + +当模板引擎读取该文件时,它会存储`mychart.labels`的引用直到`template "mychart.labels"`被调用。 +然后会按行渲染模板,因此结果类似这样: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: running-panda-configmap + labels: + generator: helm + date: 2016-11-02 +data: + myvalue: "Hello World" + drink: "coffee" + food: "pizza" +``` + +注意:`define`不会有输出,除非像本示例一样用模板调用它。 + +按照惯例,Helm chart将这些模板放置在局部文件中,一般是`_helpers.tpl`。把这个方法移到那里: + +```yaml +{{/* Generate basic labels */}} +{{- define "mychart.labels" }} + labels: + generator: helm + date: {{ now | htmlDate }} +{{- end }} +``` + +按照惯例`define`方法会有个简单的文档块(`{{/* ... */}}`)来描述要做的事。 + +尽管这个定义是在`_helpers.tpl`中,但它仍能访问`configmap.yaml`: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap + {{- template "mychart.labels" }} +data: + myvalue: "Hello World" + {{- range $key, $val := .Values.favorite }} + {{ $key }}: {{ $val | quote }} + {{- end }} +``` + +如上所述,**模板名称是全局的**。因此,如果两个模板使用相同名字声明,会使用最后出现的那个。由于子chart中的模板和顶层模板一起编译, +最好用 _chart特定名称_ 命名你的模板。常用的命名规则是用chart的名字作为模板的前缀: `{{ define "mychart.labels" }}`。 + +## 设置模板范围 + +在上面定义的模板中,我们没有使用任何对象,仅仅使用了方法。修改定义好的模板让其包含chart名称和版本号: + +```yaml +{{/* Generate basic labels */}} +{{- define "mychart.labels" }} + labels: + generator: helm + date: {{ now | htmlDate }} + chart: {{ .Chart.Name }} + version: {{ .Chart.Version }} +{{- end }} +``` + +如果渲染这个,会得到以下错误: + +```console +$ helm install --dry-run moldy-jaguar ./mychart +Error: unable to build kubernetes objects from release manifest: error validating "": error validating data: [unknown object type "nil" in ConfigMap.metadata.labels.chart, unknown object type "nil" in ConfigMap.metadata.labels.version] +``` + +要查看渲染了什么,可以用`--disable-openapi-validation`参数重新执行: +`helm install --dry-run --disable-openapi-validation moldy-jaguar ./mychart`。 +结果并不是我们想要的: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: moldy-jaguar-configmap + labels: + generator: helm + date: 2021-03-06 + chart: + version: +``` + +名字和版本号怎么了?没有出现在我们定义的模板中。当一个(使用`define`创建的)命名模板被渲染时,会接收被`template`调用传入的内容。 +在我们的示例中,包含模板如下: + +```yaml +{{- template "mychart.labels" }} +``` + +没有内容传入,所以模板中无法用`.`访问任何内容。但这个很容易解决,只需要传递一个范围给模板: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap + {{- template "mychart.labels" . }} +``` + +注意这个在`template`调用末尾传入的`.`,我们可以简单传入`.Values`或`.Values.favorite`或其他需要的范围。但一定要是顶层范围。 + +现在我们可以用`helm install --dry-run --debug plinking-anaco ./mychart`执行模板,然后得到: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: plinking-anaco-configmap + labels: + generator: helm + date: 2021-03-06 + chart: mychart + version: 0.1.0 +``` + +现在`{{ .Chart.Name }}`解析为`mychart`,`{{ .Chart.Version }}`解析为`0.1.0`。 + +## `include`方法 + +假设定义了一个简单模板如下: + +```yaml +{{- define "mychart.app" -}} +app_name: {{ .Chart.Name }} +app_version: "{{ .Chart.Version }}" +{{- end -}} +``` + +现在假设我想把这个插入到模板的`labels:`部分和`data:`部分: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap + labels: + {{ template "mychart.app" . }} +data: + myvalue: "Hello World" + {{- range $key, $val := .Values.favorite }} + {{ $key }}: {{ $val | quote }} + {{- end }} +{{ template "mychart.app" . }} +``` + +如果渲染这个,会得到以下错误: + +```console +$ helm install --dry-run measly-whippet ./mychart +Error: unable to build kubernetes objects from release manifest: error validating "": error validating data: [ValidationError(ConfigMap): unknown field "app_name" in io.k8s.api.core.v1.ConfigMap, ValidationError(ConfigMap): unknown field "app_version" in io.k8s.api.core.v1.ConfigMap] +``` + +要查看渲染了什么,可以用`--disable-openapi-validation`参数重新执行: +`helm install --dry-run --disable-openapi-validation measly-whippet ./mychart`。 +输入不是我们想要的: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: measly-whippet-configmap + labels: + app_name: mychart +app_version: "0.1.0" +data: + myvalue: "Hello World" + drink: "coffee" + food: "pizza" +app_name: mychart +app_version: "0.1.0" +``` + +注意两处的`app_version`缩进都不对,为啥?因为被替换的模板中文本是左对齐的。由于`template`是一个行为,不是方法,无法将 +`template`调用的输出传给其他方法,数据只是简单地按行插入。 + +为了处理这个问题,Helm提供了一个`template`的可选项,可以将模板内容导入当前管道,然后传递给管道中的其他方法。 + +下面这个示例,使用`indent`正确地缩进了`mychart.app`模板: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap + labels: +{{ include "mychart.app" . | indent 4 }} +data: + myvalue: "Hello World" + {{- range $key, $val := .Values.favorite }} + {{ $key }}: {{ $val | quote }} + {{- end }} +{{ include "mychart.app" . | indent 2 }} +``` + +现在生成的YAML每一部分都可以正确缩进了: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: edgy-mole-configmap + labels: + app_name: mychart + app_version: "0.1.0" +data: + myvalue: "Hello World" + drink: "coffee" + food: "pizza" + app_name: mychart + app_version: "0.1.0" +``` + +> 相较于使用`template`,在helm中使用`include`被认为是更好的方式 +> 只是为了更好地处理YAML文档的输出格式 + +有时我们需要导入内容,但不是作为模板,也就是按字面意义导入文件内容,可以通过使用`.Files`对象访问文件来实现, +这将在下一部分展开描述。 diff --git a/content/zh/docs/chart_template_guide/notes_files.md b/content/zh/docs/chart_template_guide/notes_files.md new file mode 100644 index 0000000000..4a0e3f4c6c --- /dev/null +++ b/content/zh/docs/chart_template_guide/notes_files.md @@ -0,0 +1,51 @@ +--- +title: "创建一个NOTES.txt文件" +description: "如何向chart用户提供说明。" +weight: 11 +--- + +该部分会介绍为chart用户提供说明的Helm工具。在`helm install` 或 `helm upgrade`命令的最后,Helm会打印出对用户有用的信息。 +使用模板可以高度自定义这部分信息。 + +要在chart添加安装说明,只需创建`templates/NOTES.txt`文件即可。该文件是纯文本,但会像模板一样处理, +所有正常的模板函数和对象都是可用的。 + +让我们创建一个简单的`NOTES.txt`文件: + +```yaml +Thank you for installing {{ .Chart.Name }}. + +Your release is named {{ .Release.Name }}. + +To learn more about the release, try: + + $ helm status {{ .Release.Name }} + $ helm get all {{ .Release.Name }} + +``` + +现在如果我们执行`helm install rude-cardinal ./mychart` 会在底部看到: + +```yaml +RESOURCES: +==> v1/Secret +NAME TYPE DATA AGE +rude-cardinal-secret Opaque 1 0s + +==> v1/ConfigMap +NAME DATA AGE +rude-cardinal-configmap 3 0s + + +NOTES: +Thank you for installing mychart. + +Your release is named rude-cardinal. + +To learn more about the release, try: + + $ helm status rude-cardinal + $ helm get all rude-cardinal +``` + +使用`NOTES.txt`这种方式是给用户提供关于如何使用新安装的chart细节信息的好方法。尽管并不是必需的,强烈建议创建一个`NOTES.txt`文件。 diff --git a/content/zh/docs/chart_template_guide/subcharts_and_globals.md b/content/zh/docs/chart_template_guide/subcharts_and_globals.md new file mode 100644 index 0000000000..8c0aeaec0c --- /dev/null +++ b/content/zh/docs/chart_template_guide/subcharts_and_globals.md @@ -0,0 +1,214 @@ +--- +title: "子chart和全局值" +description: "与子chart和全局值进行交互" +weight: 12 +--- + +到目前为止,我们只使用了一个chart。但chart可以使用依赖,称为 _子chart_,且有自己的值和模板。 +该章节我们会创建一个子chart并能看到访问模板中的值的不同方式。 + +在深入研究代码之前,需要了解一些应用的子chart的重要细节: + +1. 子chart被认为是“独立的”,意味着子chart从来不会显示依赖它的父chart。 +2. 因此,子chart无法访问父chart的值。 +3. 父chart可以覆盖子chart的值。 +4. Helm有一个 _全局值_ 的概念,所有的chart都可以访问。 + +> 这些限制不一定都适用于提供标准化辅助功能的 [library charts](https://helm.sh/zh/docs/topics/library_charts)。 + +浏览本节的示例之后,这些概念会变得更加清晰。 + +## 创建子chart + +为了做这些练习,我们可以从本指南开始时创建的`mychart/`开始,并在其中添加一个新的chart。 + +```console +$ cd mychart/charts +$ helm create mysubchart +Creating mysubchart +$ rm -rf mysubchart/templates/* +``` + +注意,和以前一样,我们删除了所有的基本模板,然后从头开始,在这个指南中,我们聚焦于模板如何工作,而不是管理依赖。 +但[Chart指南](https://helm.sh/zh/docs/topics/charts)提供了更多子chart运行的信息。 + +## 在子chart中添加值和模板 + +下一步,为`mysubchart`创建一个简单的模板和values文件。`mychart/charts/mysubchart`应该已经有一个`values.yaml`。 +设置如下: + +```yaml +dessert: cake +``` + +下一步,在`mychart/charts/mysubchart/templates/configmap.yaml`中创建一个新的配置映射模板: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-cfgmap2 +data: + dessert: {{ .Values.dessert }} +``` + +因为每个子chart都是 _独立的chart_,可以单独测试`mysubchart`: + +```console +$ helm install --generate-name --dry-run --debug mychart/charts/mysubchart +SERVER: "localhost:44134" +CHART PATH: /Users/mattbutcher/Code/Go/src/helm.sh/helm/_scratch/mychart/charts/mysubchart +NAME: newbie-elk +TARGET NAMESPACE: default +CHART: mysubchart 0.1.0 +MANIFEST: +--- +# Source: mysubchart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: newbie-elk-cfgmap2 +data: + dessert: cake +``` + +## 用父chart的值来覆盖 + +原始chart,`mychart`现在是`mysubchart`的 _父_。这种关系是基于`mysubchart`在`mychart/charts`中这一事实。 + +因为`mychart`是父级,可以在`mychart`指定配置并将配置推送到`mysubchart`。比如可以修改`mychart/values.yaml`如下: + +```yaml +favorite: + drink: coffee + food: pizza +pizzaToppings: + - mushrooms + - cheese + - peppers + - onions + +mysubchart: + dessert: ice cream +``` + +注意最后两行,在`mysubchart`中的所有指令会被发送到`mysubchart`chart中。因此如果运行`helm install --dry-run --debug +mychart`,会看到一项`mysubchart`的配置: + +```yaml +# Source: mychart/charts/mysubchart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: unhinged-bee-cfgmap2 +data: + dessert: ice cream +``` + +现在,子chart的值已经被顶层的值覆盖了。 + +这里需要注意个重要细节。我们不会改变`mychart/charts/mysubchart/templates/configmap.yaml`模板到 +`.Values.mysubchart.dessert`的指向。从模板的角度来看,值依然是在`.Values.dessert`。当模板引擎传递值时,会设置范围。 +因此对于`mysubchart`模板,`.Values`中只提供专门用于`mysubchart`的值。 + +但是有时确实希望某些值对所有模板都可用。这是使用全局chart值完成的。 + +## 全局Chart值 + +全局值是使用完全一样的名字在所有的chart及子chart中都能访问的值。全局变量需要显式声明。不能将现有的非全局值作为全局值使用。 + +这些值数据类型有个保留部分叫`Values.global`,可以用来设置全局值。在`mychart/values.yaml`文件中设置一个值如下: + +```yaml +favorite: + drink: coffee + food: pizza +pizzaToppings: + - mushrooms + - cheese + - peppers + - onions + +mysubchart: + dessert: ice cream + +global: + salad: caesar +``` + +因为全局的工作方式,`mychart/templates/configmap.yaml`和`mysubchart/templates/configmap.yaml` +应该都能以`{{ .Values.global.salad }}`进行访问。 + +`mychart/templates/configmap.yaml`: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + salad: {{ .Values.global.salad }} +``` + +`mysubchart/templates/configmap.yaml`: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-cfgmap2 +data: + dessert: {{ .Values.dessert }} + salad: {{ .Values.global.salad }} +``` + +现在如果预安装,两个输出会看到相同的值: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: silly-snake-configmap +data: + salad: caesar + +--- +# Source: mychart/charts/mysubchart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: silly-snake-cfgmap2 +data: + dessert: ice cream + salad: caesar +``` + +全局值在类似这样传递信息时很有用,不过要确保使用全局值配置正确的模板,确实需要一些计划。 + +## 与子chart共享模板 + +父chart和子chart可以共享模板。在任意chart中定义的块在其他chart中也是可用的。 + +比如,我们可以这样定义一个简单的模板: + +```yaml +{{- define "labels" }}from: mychart{{ end }} +``` + +回想一下模板标签时如何 _全局共享的_。因此,`标签`chart可以包含在任何其他chart中。 + +当chart开发者在`include` 和 `template` 之间选择时,使用`include`的一个优势是`include`可以动态引用模板: + +```yaml +{{ include $mytemplate }} +``` + +上述会取消对`$mytemplate`的引用,相反,`template`函数只接受字符串字符。 + +## 避免使用块 + +Go 模板语言提供了一个 `block` 关键字允许开发者提供一个稍后会被重写的默认实现。在Helm chart中, +块并不是用于覆盖的最好工具,因为如果提供了同一个块的多个实现,无法预测哪个会被选定。 + +建议改为使用`include`。 diff --git a/content/zh/docs/chart_template_guide/values_files.md b/content/zh/docs/chart_template_guide/values_files.md new file mode 100644 index 0000000000..d1f3f6acd1 --- /dev/null +++ b/content/zh/docs/chart_template_guide/values_files.md @@ -0,0 +1,167 @@ +--- +title: "Values 文件" +description: "--values参数操作说明" +weight: 4 +--- + +在上一部分我们了解了Helm模板提供的内置对象。其中一个是`Values`对象。该对象提供了传递值到chart的方法, + +其内容来自于多个位置: + +- chart中的`values.yaml`文件 +- 如果是子chart,就是父chart中的`values.yaml`文件 +- 使用`-f`参数(`helm install -f myvals.yaml ./mychart`)传递到 `helm install` 或 +`helm upgrade`的values文件 +- 使用`--set` (比如`helm install --set foo=bar ./mychart`)传递的单个参数 + +以上列表有明确顺序:默认使用`values.yaml`,可以被父chart的`values.yaml`覆盖,继而被用户提供values文件覆盖, +最后会被`--set`参数覆盖,优先级为`values.yaml`最低,`--set`参数最高。 + +values文件是普通的YAML文件。现在编辑`mychart/values.yaml`然后编辑配置映射ConfigMap模板。 + +删除`values.yaml`中的默认内容,仅设置一个参数: + +```yaml +favoriteDrink: coffee +``` + +现在可以在模板中使用它: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + drink: {{ .Values.favoriteDrink }} +``` + +注意最后一行,`favoriteDrink`是`Values`的一个属性: `{{ .Values.favoriteDrink }}`。 + +看看是如何渲染的: + +```console +$ helm install geared-marsupi ./mychart --dry-run --debug +install.go:158: [debug] Original chart version: "" +install.go:175: [debug] CHART PATH: /home/bagratte/src/playground/mychart + +NAME: geared-marsupi +LAST DEPLOYED: Wed Feb 19 23:21:13 2020 +NAMESPACE: default +STATUS: pending-install +REVISION: 1 +TEST SUITE: None +USER-SUPPLIED VALUES: +{} + +COMPUTED VALUES: +favoriteDrink: coffee + +HOOKS: +MANIFEST: +--- +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: geared-marsupi-configmap +data: + myvalue: "Hello World" + drink: coffee +``` + +由于默认的`values.yaml`文件中设置了`favoriteDrink`的值为`coffee`,则这个显示在了模板中。 +可以在调用`helm install`时设置`--set`,很容易就能覆盖这个值。 + +```console +$ helm install solid-vulture ./mychart --dry-run --debug --set favoriteDrink=slurm +install.go:158: [debug] Original chart version: "" +install.go:175: [debug] CHART PATH: /home/bagratte/src/playground/mychart + +NAME: solid-vulture +LAST DEPLOYED: Wed Feb 19 23:25:54 2020 +NAMESPACE: default +STATUS: pending-install +REVISION: 1 +TEST SUITE: None +USER-SUPPLIED VALUES: +favoriteDrink: slurm + +COMPUTED VALUES: +favoriteDrink: slurm + +HOOKS: +MANIFEST: +--- +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: solid-vulture-configmap +data: + myvalue: "Hello World" + drink: slurm +``` + +由于`--set`比默认的`values.yaml`文件优先级更高,模板就生成了`drink: slurm`。 + +values文件也可以包含更多结构化的内容。比如我们可以在`values.yaml`文件中创建一个`favorite`项,然后添加一些key: + +```yaml +favorite: + drink: coffee + food: pizza +``` + +现在需要稍微修改一些模板: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + drink: {{ .Values.favorite.drink }} + food: {{ .Values.favorite.food }} +``` + +虽然可以这样构造数据,但还是建议构建更加平坦的浅层树。以后想要给子chart赋值时,会看到如何使用树结构给value命名。 + +## 删除默认的key + +如果需要从默认的value中删除key,可以将key设置为`null`,Helm将在覆盖的value合并时删除这个key。 + +比如,稳定的Drupal允许在配置自定义镜像时配置活动探针。默认值为`httpget`: + +```yaml +livenessProbe: + httpGet: + path: /user/login + port: http + initialDelaySeconds: 120 +``` + +如果你想替换掉`httpGet`用`exec`重写活动探针,使用`--set livenessProbe.exec.command=[cat,docroot/CHANGELOG.txt]`, +Helm会把默认的key和重写的key合并在一起,从而生成以下YAML: + +```yaml +livenessProbe: + httpGet: + path: /user/login + port: http + exec: + command: + - cat + - docroot/CHANGELOG.txt + initialDelaySeconds: 120 +``` + +因为Kubernetes中不能声明多个活动探针句柄,从而会应用发布会失败。为了解决这个问题,Helm可以指定通过设定null来删除`livenessProbe.httpGet`: + +```sh +helm install stable/drupal --set image=my-registry/drupal:0.1.0 --set livenessProbe.exec.command=[cat,docroot/CHANGELOG.txt] --set livenessProbe.httpGet=null +``` + +在这之前我们已经看到了几个内置对象,并用它们将信息传递到模板中。现在来模板引擎的另一部分:方法和管道。 diff --git a/content/zh/docs/chart_template_guide/variables.md b/content/zh/docs/chart_template_guide/variables.md new file mode 100644 index 0000000000..744556181b --- /dev/null +++ b/content/zh/docs/chart_template_guide/variables.md @@ -0,0 +1,140 @@ +--- +title: "变量" +description: "在模板中使用变量。" +weight: 8 +--- + +函数、管道符、对象和控制结构都可以控制,我们转向很多编程语言中更基本的思想之一:变量。 +在模板中,很少被使用。但是我们可以使用变量简化代码,并更好地使用`with`和`range`。 + +在之前的例子中,我们看到下面的代码会失败: + +```yaml + {{- with .Values.favorite }} + drink: {{ .drink | default "tea" | quote }} + food: {{ .food | upper | quote }} + release: {{ .Release.Name }} + {{- end }} +``` + +`Release.Name` 不在`with`块的限制范围内。解决作用域问题的一种方法是将对象分配给可以不考虑当前作用域而访问的变量。 + +Helm模板中,变量是对另一个对象的命名引用。遵循`$name`变量的格式且指定了一个特殊的赋值运算符:`:=`。 +我们可以使用针对`Release.Name`的变量重写上述内容。 + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + {{- $relname := .Release.Name -}} + {{- with .Values.favorite }} + drink: {{ .drink | default "tea" | quote }} + food: {{ .food | upper | quote }} + release: {{ $relname }} + {{- end }} +``` + +注意在`with`块开始之前,赋值`$relname := .Release.Name`。 +现在在`with`块中,`$relname`变量仍会执行版本名称。 + +运行之后会生成以下内容: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: viable-badger-configmap +data: + myvalue: "Hello World" + drink: "coffee" + food: "PIZZA" + release: viable-badger +``` + +变量在`range`循环中特别有用。可以用于类似列表的对象,以捕获索引和值: + +```yaml + toppings: |- + {{- range $index, $topping := .Values.pizzaToppings }} + {{ $index }}: {{ $topping }} + {{- end }} + +``` + +注意先是`range`,然后是变量,然后是赋值运算符,然后是列表。会将整型索引(从0开始)赋值给`$index`并将值赋值给`$topping`。 +执行会生成: + +```yaml + toppings: |- + 0: mushrooms + 1: cheese + 2: peppers + 3: onions +``` + +对于数据结构有key和value,可以使用`range`获取key和value。比如,可以通过`.Values.favorite`进行循环: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap +data: + myvalue: "Hello World" + {{- range $key, $val := .Values.favorite }} + {{ $key }}: {{ $val | quote }} + {{- end }} +``` + +第一次迭代,`$key`会是`drink`且`$val`会是`coffee`,第二次迭代`$key`会是`food`且`$val`会是`pizza`。 +运行之后会生成: + +```yaml +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: eager-rabbit-configmap +data: + myvalue: "Hello World" + drink: "coffee" + food: "pizza" +``` + +变量一般不是"全局的"。作用域是其声明所在的块。上面我们在模板的顶层赋值了`$relname`。变量的作用域会是整个模板。 +但在最后一个例子中`$key`和`$val`作用域会在`{{ range... }}{{ end }}`块内。 + +但有个变量一直是全局的 - `$` - 这个变量一直是指向根的上下文。当在一个范围内循环时会很有用,同时你要知道chart的版本名称。 + +举例说明如下: + +```yaml +{{- range .Values.tlsSecrets }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ .name }} + labels: + # Many helm templates would use `.` below, but that will not work, + # however `$` will work here + app.kubernetes.io/name: {{ template "fullname" $ }} + # I cannot reference .Chart.Name, but I can do $.Chart.Name + helm.sh/chart: "{{ $.Chart.Name }}-{{ $.Chart.Version }}" + app.kubernetes.io/instance: "{{ $.Release.Name }}" + # Value from appVersion in Chart.yaml + app.kubernetes.io/version: "{{ $.Chart.AppVersion }}" + app.kubernetes.io/managed-by: "{{ $.Release.Service }}" +type: kubernetes.io/tls +data: + tls.crt: {{ .certificate }} + tls.key: {{ .key }} +--- +{{- end }} +``` + +到目前为止,我们只看到在一个文件声明的一个模板。但是Helm模板语言一个很强大的特性是能够声明多个模板并将它们一起使用。 +我们将在下一节讨论这个问题。 diff --git a/content/zh/docs/chart_template_guide/wrapping_up.md b/content/zh/docs/chart_template_guide/wrapping_up.md new file mode 100644 index 0000000000..462b4af015 --- /dev/null +++ b/content/zh/docs/chart_template_guide/wrapping_up.md @@ -0,0 +1,29 @@ +--- +title: "下一步" +description: "收尾 - 一些能帮到你的指向其他的文档的链接。" +weight: 15 +--- + +本指南旨在为chart开发者提供对如何使用Helm模板语言的强大理解能力。该模板聚焦于模板开发的技术层面。 + +但涉及到chart的实际日常开发时,很多内容本指南并没有覆盖到。这里有一些有用的文档链接帮助你创建新的chart: + +- CNCF的 [Artifact Hub](https://artifacthub.io/packages/search?kind=0) 是chart不可或缺的资源。 +- Kubernetes [文档](https://kubernetes.io/docs/home/) 提供各种能用到的资源种类的详细案例,从配置映射和密钥到 + DaemonSet和工作负载。 +- Helm的[Chart指南](https://helm.sh/zh/docs/topics/charts) 阐述了使用chart的工作流。 +- Helm的[Chart钩子指南](https://helm.sh/zh/docs/topics/charts_hooks) 说明了如何创建生命周期的钩子。 +- Helm的[Chart提示和技巧](https://helm.sh/zh/docs/howto/charts_tips_and_tricks/) + 提供了编写chart时的一些有用提示。 +- [Sprig 文档](https://github.com/Masterminds/sprig) 提供了超过60个模板函数。 +- [Go 模板文档](https://godoc.org/text/template) 说明了模板语法的细节。 +- [Schelm 工具](https://github.com/databus23/schelm) 用于调试chart的辅助工具。 + +有时候从有经验的开发者那里问问题和获取答案更加容易。最佳方式是访问 [Kubernetes +Slack](https://kubernetes.slack.com)的Helm频道: + +- [#helm-users](https://kubernetes.slack.com/messages/helm-users) +- [#helm-dev](https://kubernetes.slack.com/messages/helm-dev) +- [#charts](https://kubernetes.slack.com/messages/charts) + +最后,如果你找到了文档中的错误或疏漏,想推荐一些新内容,或者想做一些贡献,请访问[Helm 项目](https://github.com/helm/helm-www)。 diff --git a/content/zh/docs/chart_template_guide/yaml_techniques.md b/content/zh/docs/chart_template_guide/yaml_techniques.md new file mode 100644 index 0000000000..6965f21887 --- /dev/null +++ b/content/zh/docs/chart_template_guide/yaml_techniques.md @@ -0,0 +1,300 @@ +--- +title: "附录: YAML技术" +description: "详细描述了YAML规范以及如何应用于Helm。" +weight: 16 +--- + +本指南大部分都聚焦于编写模板语言。这里,我们要看看YAML格式。作为模板作者,YAML有一些有用的特性 +使我们的模板不易出错,更易阅读。 + +## 标量和集合 + +根据 [YAML 规范](https://yaml.org/spec/1.2/spec.html),有两种集合类型和很多标量类型。 + +两种集合类型是map和sequence: + +```yaml +map: + one: 1 + two: 2 + three: 3 + +sequence: + - one + - two + - three +``` + +标量值是单个值,(与集合相反) + +### YAML中的标量类型 + +在Helm内部的YAML语言中,一个标量值的数据类型是由一组复杂的规则决定的,包含了资源定义的Kubernetes模式。 +但在推断类型时,以下规则往往是正确的。 + +如果整型或浮点型数字没有引号,通常被视为数字类型: + +```yaml +count: 1 +size: 2.34 +``` + +但是如果被引号引起来,会被当做字符串: + +```yaml +count: "1" # <-- string, not int +size: '2.34' # <-- string, not float +``` + +布尔函数也是如此: + +```yaml +isGood: true # bool +answer: "true" # string +``` + +空字符串是 `null` (不是 `nil`)。 + +注意 `port: "80"`是合法的YAML,可以通过模板引擎和YAML解释器传值,但是如果Kubernetes希望`port`是整型,就会失败。 + +在一些场景中,可以使用YAML节点标签强制推断特定类型: + +```yaml +coffee: "yes, please" +age: !!str 21 +port: !!int "80" +``` + +如上所示,`!!str`告诉解释器`age`是一个字符串,即使它看起来像是整型。即使`port`被引号括起来,也会被视为int。 + +## YAML中的字符串 + +YAML中的大多数数据都是字符串。YAML有多种表示字符串的方法。本节解释这些方法并演示如何使用其中一些方法。 + +有三种单行方式声明一个字符串: + +```yaml +way1: bare words +way2: "double-quoted strings" +way3: 'single-quoted strings' +``` + +单行样式必须在一行: + +- 裸字没有引号,也没有转义,因此,必须小心使用字符。 +- 双引号字符串可以使用`\`转义指定字符。比如,`"\"Hello\", she said"`。可以使用`\n`转义换行。 +- 单引号字符串是字面意义的字符串,不用`\`转义,只有单引号`''`需要转义,转成单个`'`。 + +除了单行字符串,可以声明多行字符串: + +```yaml +coffee: | + Latte + Cappuccino + Espresso +``` + +上述会被当作`coffee`的字符串值,等同于`Latte\nCappuccino\nEspresso\n`。 + +注意在第一行`|`后面必须正确缩进。可以这样破坏上述示例: + +```yaml +coffee: | + Latte + Cappuccino + Espresso + +``` + +由于`Latte`没有正确缩进,会遇到这样的错误: + +```shell +Error parsing file: error converting YAML to JSON: yaml: line 7: did not find expected key +``` + +模板中,有时候为了避免上述错误,在多行文本中添加一个假的“第一行”会更加安全: + +```yaml +coffee: | + # Commented first line + Latte + Cappuccino + Espresso + +``` + +注意无论第一行是什么,都会保存在字符串的输出中。比如你要这样把文件内容注入到配置映射中,注释应该是读取该条目需要的类型。 + +### 控制多行字符串中的空格 + +在上述示例中,使用了 `|` 来表示多行字符串。但是注意字符串后面有一个尾随的`\n`。如果需要YAML处理器去掉末尾的换行符,在`|` +后面添加`-`: + +```yaml +coffee: |- + Latte + Cappuccino + Espresso +``` + +现在 `coffee`的值变成了: `Latte\nCappuccino\nEspresso` (没有末尾的`\n`)。 + +其他时候,可能希望保留尾随空格。可以使用 `|+`符号: + +```yaml +coffee: |+ + Latte + Cappuccino + Espresso + + +another: value +``` + +现在`coffee`的值是 `Latte\nCappuccino\nEspresso\n\n\n`。 + +文本块中的缩进会被保留,也会保留换行符: + +```yaml +coffee: |- + Latte + 12 oz + 16 oz + Cappuccino + Espresso +``` + +上述示例中,`coffee`会变成 `Latte\n 12 oz\n 16 oz\nCappuccino\nEspresso`。 + +### 缩进和模板 + +编写模板时,你可能会想将文件内容插入到模板中。正如在之前的章节中看到的,有两种方法处理: + +- 使用 `{{ .Files.Get "FILENAME" }}` 获取chart中的文件内容。 +- 使用 `{{ include "TEMPLATE" . }}` 渲染模板并将其放到chart中。 + +把文件插入到YAML时,就很好理解上面的多行规则了。通常,插入一个静态文件最简单的方式是像这样: + +```yaml +myfile: | +{{ .Files.Get "myfile.txt" | indent 2 }} +``` + +注意上面是怎么做缩进的: `indent 2` 告诉模板引擎在文件"myfile.txt"中每行缩进两个空格。注意我们没有缩进模板的行。 +因为如果缩进了,文件内容的第一行会缩进两次。 + +### 折叠多行字符串 + +有时您想在 YAML 中用多行表示一个字符串,但希望在解释时将其视为一个长行。这被称为"折叠"。要声明一个折叠块,使用 `>` 代替 `|`: + +```yaml +coffee: > + Latte + Cappuccino + Espresso + + +``` + +上面`coffee`的值是: `Latte Cappuccino Espresso\n`。 注意,除了最后一个换行符之外,所有的换行符都将转换成空格。 +可以组合空格控制符和折叠字符标记 `>-` 来替换或取消所有的新行。 + +注意在折叠语法中,缩进文本将导致保留行。 + +```yaml +coffee: >- + Latte + 12 oz + 16 oz + Cappuccino + Espresso +``` + +上述结果为:`Latte\n 12 oz\n 16 oz\nCappuccino Espresso`。注意空格和换行都保存下来了。 + +## 在一个文件中嵌入多个文档 + +可以将多个YAML文档放在单个文件中。 文档前使用 `---`,文档后使用 `...` + +```yaml + +--- +document:1 +... +--- +document: 2 +... +``` + +很多情况下,可以省略`---`或者`...`。 + +Helm中的有些文件无法包含多个文档。比如,如果`values.yaml`文件提供了多个文档,只会使用第一个。 + +但是模板文件可以有多个文档。这种情况下,文件会被当做一个对象进行渲染。但是将结果YAML提供给Kubernetes时,会被分成多个文档。 + +我们建议在确实需要时才将多个文档写入单个文件。单个文件中的多个文档会变得很难调试。 + +## YAML是JSON的超集 + +由于YAML是一个JSON的超集,任何合法的JSON文档 _都应该_ 是合法的YAML。 + +```json +{ + "coffee": "yes, please", + "coffees": [ + "Latte", "Cappuccino", "Espresso" + ] +} +``` + +上述json的另一种表述方式是: + +```yaml +coffee: yes, please +coffees: +- Latte +- Cappuccino +- Espresso +``` + +而且两种可以混合(要小心): + +```yaml +coffee: "yes, please" +coffees: [ "Latte", "Cappuccino", "Espresso"] +``` + +所有这三个都应该解析为相同的内部表示形式。 + +这意味着类似 `values.yaml` 可能包含JSON数据,Helm将`.json`后缀文件视为不合法的文件。 + +## YAML 锚点 + +YAML规范存储了一种引用值的方法,然后通过引用指向该值。YAML称之为“锚定”: + +```yaml +coffee: "yes, please" +favorite: &favoriteCoffee "Cappuccino" +coffees: + - Latte + - *favoriteCoffee + - Espresso +``` + +上面示例中,`&favoriteCoffee` 设置成了`Cappuccino`的引用。之后,通过`*favoriteCoffee`使用引用。 +这样`coffees` 就变成了 `Latte, Cappuccino, Espresso`。 + +锚点在一些场景中很有用,但另一方面,锚点可能会引起细微的错误:第一次使用YAML时,将展开引用,然后将其丢弃。 + +因此,如果我们解码再重新编码上述示例,产生的YAML就会时这样: + +```yaml +coffee: yes, please +favorite: Cappuccino +coffees: +- Latte +- Cappuccino +- Espresso +``` + +因为Helm和Kubernetes经常读取,修改和重写YAML文件,锚点会丢失。 diff --git a/content/zh/docs/community/_index.md b/content/zh/docs/community/_index.md new file mode 100644 index 0000000000..c95c05cf22 --- /dev/null +++ b/content/zh/docs/community/_index.md @@ -0,0 +1,8 @@ +--- +title: "社区" +weight: 7 +--- + +# 社区指引 + +这里您可以了解到 Helm 项目的开发进程以及如何参与。 diff --git a/content/zh/docs/community/developers.md b/content/zh/docs/community/developers.md new file mode 100644 index 0000000000..26f29479e4 --- /dev/null +++ b/content/zh/docs/community/developers.md @@ -0,0 +1,124 @@ +--- +title: "开发者指南" +description: "开发Helm的环境设置说明。" +weight: 1 +--- + +该指南说明如何为开发Helm配置环境。 + +## 先决条件 + +- Go最新版本 +- Kubernetes集群及kubectl(可选) +- Git + +## 构建 Helm + +我们使用Make构建程序。最简单的开始方式是: + +```console +$ make +``` + +注意: 如果不是从`$GOPATH/src/helm.sh/helm`路径执行就会失败。目录`helm.sh`不应该是软链接,否则 +`build` 找不到相关的包。 + +有必要的话要先安装依赖,重新构建 `vendor/` 目录,并验证配置。然后会编译 `helm` 并将其放到`bin/helm`。 + +在本地执行Helm,可以执行 `bin/helm`。 + +- Helm运行在 macOS 和大多数发行版上,包括 Alpine。 + +## 执行测试 + +要运行所有测试(除了`vendor/`),执行 `make test`。作为先决条件,需要安装 +[golangci-lint](https://golangci-lint.run)。 + +## 贡献指南 + +我们欢迎你的贡献。 该项目已经设置了一些指南,为了保证 (a) 代码的高质量,(b) 保持项目一致, +(c) 贡献遵循开源法律要求。我们的目的不是为贡献者增加负担,但是要构建优雅和高质量的开源代码, +这样我们的用户才能从中受益。 + +确保你已经阅读并理解主要贡献指南: + +https://github.com/helm/helm/blob/main/CONTRIBUTING.md + +### 代码结构 + +Helm项目的代码组织如下: + +- 独立的程序位于 `cmd/`。`cmd/` 中的代码不是为库复用设计的。 +- 共享的库放在 `pkg/`。 +- `scripts/` 目录包含很多实用程序脚本。大多数用于CI/CD流水线。 + +Go依赖管理在不断变化,而且在Helm生命周期中很可能发生变化。我们建议开发者 _不要_ 手动管理依赖。 +而是建议依靠项目的 `Makefile` 来处理。使用Helm 3时,建议使用Go 1.13及更新版本。 + +### 编写文档 + +从Helm 3开始,文档已经移动到了它自己的仓库中。当编制新特性时,请编写随附文档并提交到 +[helm-www](https://github.com/helm/helm-www) 仓库。 + +有个例外:[Helm CLI 输出 (英文)](https://helm.sh/docs/helm/) 是 `helm` 程序自己生成的。 +查看 [更新Helm CLI参考文档](https://github.com/helm/helm-www#updating-the-helm-cli-reference-docs) +来了解如何生成该输出。翻译后,不会生成CLI输出,但可以在 `/content//docs/helm` 中找到。 + +### Git 约定 + +我们使用Git作为版本控制系统。 `main` 分支是当前开发候选分支。发布版本会打tag。 + +我们通过GitHub的Pull Requests(PRs)接受更改。操作工作流如下: + +1. 进入 `$GOPATH/src` 目录,然后 `mkdir helm.sh; cd helm.sh` 并`git clone`这个 + `github.com/helm/helm`仓库。 +2. Fork仓库到自己的GitHub账户 +3. 为 `$GOPATH/src/helm.sh/helm` 添加自己的远程仓库 +4. 创建一个新分支(`git checkout -b feat/my-feature`) 并在新分支上开发。 +5. 当你准备好待审查代码时,将分支推送到GitHub,并开一个新的pull request 给我们。 + +对于Git提交信息,我们遵循 +[语义化提交信息](https://karma-runner.github.io/0.13/dev/git-commit-msg.html): + +```shell +fix(helm): add --foo flag to 'helm install' + +When 'helm install --foo bar' is run, this will print "foo" in the +output regardless of the outcome of the installation. + +Closes #1234 +``` + +常见提交类型: + +- fix: 修复bug或错误 +- feat: 添加新特性 +- docs: 更新文档 +- test: 完善测试 +- ref: 重构现有代码 + +通用范围: + +- helm: Helm CLI +- pkg/lint: lint包。对任意包都遵循类似的约定 +- `*`: 两个或更多范围 + +了解更多: + +- 灵感来源于 [Deis指南](https://github.com/deis/workflow/blob/master/src/contributing/submitting-a-pull-request.md)。 +- Karma Runner + [定义](https://karma-runner.github.io/0.13/dev/git-commit-msg.html) 了语义提交信息的观点。 + +### Go 约定 + +我们非常严格地遵守Go编码风格标准。典型方式是,执行 `go fmt` 可以让代码更加整洁。 + +我们通常也通过`go lint` 和`gometalinter`遵循推荐的约定。执行 `make test-style` 来测试风格一致性。 + +了解更多: + +- 有效的Go[引入格式](https://golang.org/doc/effective_go.html#formatting)。 +- Go Wiki有关于[formatting](https://github.com/golang/go/wiki/CodeReviewComments)很棒的文章。 + +如果运行`make test`,不仅单元测试会执行,格式测试也会自执行。如果 `make test`失败,即使是因为格式方面的原因, +你的PR也不会被合并。 diff --git a/content/zh/docs/community/history.md b/content/zh/docs/community/history.md new file mode 100644 index 0000000000..707ae683f1 --- /dev/null +++ b/content/zh/docs/community/history.md @@ -0,0 +1,23 @@ +--- +title: "项目历史" +description: "提供项目历史的高级概述。" +weight: 4 +--- + +Helm 是[CNCF](https://www.cncf.io/projects/)的[毕业项目](https://helm.sh/blog/celebrating-helms-cncf-graduation/)。 + +Helm 开始时被称为[Helm Classic](https://github.com/helm/helm-classic),始于2015年的Deis项目并在KubeCon会议中被提出。 + +2016年1月,该项目与名为Kubernetes部署管理器的GCS工具合并,并移动到了[Kubernetes](https://kubernetes.io)中。 +由于代码的合并,Helm 2.0于当年晚些时候发布。在Helm 2中保留的部署管理的关键特性是服务端组件, +Helm 2.0最终的发布版本中DM重命名为了Tiller。 + +Helm于2018年6月从Kubernetes子项目晋升为CNCF的成熟项目。Helm组建了一个顶级的管理机构并在Helm项目中包含了几个子项目, +包括Monocular,Helm Chart仓库,Chart博物馆,以及后来的Helm Hub。 + +当Helm 3开发周期开始时,移除了Tiller,使其更接近于作为客户工具最初愿景。但Helm 3继续跟踪Kubernetes集群内部的版本, +使团队可以共同完成一个公共的Helm发布版本。Helm 3于2019年11月发布。 + +Helm [于2020年4月成为CNCF的毕业项目](https://www.cncf.io/announcement/2020/04/30/cloud-native-computing-foundation-announces-helm-graduation/)。 + +CNCF的[Artifact Hub](https://artifacthub.io)在2020年10月份替换了[Helm Hub](https://hub.helm.sh)。 diff --git a/content/zh/docs/community/localization.md b/content/zh/docs/community/localization.md new file mode 100644 index 0000000000..860e9c1cd0 --- /dev/null +++ b/content/zh/docs/community/localization.md @@ -0,0 +1,126 @@ +--- +title: "本地化Helm文档" +description: "本地化Helm文档的说明。" +weight: 5 +--- + +本指南介绍如何本地化Helm文档。 + +## 入门 + +翻译工作使用与文档稿件相同的过程。翻译通过[pull +requests](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests) +提供给 [helm-www](https://github.com/helm/helm-www) 仓库并由管理站点的团队审查。 + +### 双字母语言代码 + +语言代码文档由[ISO 639-1标准](https://www.loc.gov/standards/iso639-2/php/code_list.php)组织。 +比如,韩国的双字母代码是 `ko`。 + +在内容和配置中可以找到使用的语音码。三个例子如下: + +- `content` 目录中的子目录以语言码命名且本地化内容在对应的目录中。 主要在每个语言码目录的 `docs`子目录中。 +- `i18n`目录包含一个网站使用的每种语言的配置文件。文件按照 `[LANG].toml` 形式命名,`[LANG]` 是双字母语言码。 +- 顶层`config.toml`文件中,有按语言码组织的导航和其他详细信息的配置。 + +英文使用语言码 `en`,是翻译的默认语言和资源。 + +### Fork, Branch, Change, Pull Request + +贡献翻译从[helm-www仓库](https://github.com/helm/helm-www) +[创建fork](https://help.github.com/en/github/getting-started-with-github/fork-a-repo)开始。在你的fork中提交更改。 + +默认情况下,fork将在名为master的默认分支上工作。请使用分支提交更改并创建pull requests。如果你不熟悉分支,可以 +[阅读GitHub文档](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-branches)。 + +一旦有了分支,就可以添加翻译,将内容本地化为一种语言。 + +注意,Helm使用一个[Developers Certificate of Origin](https://developercertificate.org/)。 +所有的提交需要signoff。提交时可以使用 `-s` 或 `--signoff` 参数使用你Git配置的用户和邮箱签署这个提交。 +更多细节请查看 [CONTRIBUTING.md](https://github.com/helm/helm-www/blob/main/CONTRIBUTING.md#sign-your-work) +文件。 + +准备好之后,创建一个 [pull request](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests) +将翻译提交到helm-www仓库。 + +一旦创建了pull request,维护者会进行审查。过程细节查看 [CONTRIBUTING.md](https://github.com/helm/helm-www/blob/main/CONTRIBUTING.md)。 + +## 翻译内容 + +本地化所有的Helm内容是一项巨大的任务。开始很小的改动是可以的。翻译会随着时间扩展。 + +### 开始一个新语言 + +开始新语言时有些最低要求,包括: + +- 添加`content/[LANG]/docs`目录,包含`_index.md` 文件。这是顶层的文档落地页。 +- `[LANG].toml` 文件在`i18n`目录中。可以复制`en.toml`文件作为起点。 +- 在 `config.toml`文件中添加一部分用于展示新语言。可以用已有语言作为起点。 + +### 翻译 + +已翻译内容需要保留在 `content/[LANG]/docs` 目录中。应该有相同的URL作为英文源。 +比如,将intro翻译为韩文时拷贝英文是有用的: + +```sh +mkdir -p content/ko/docs/intro +cp content/en/docs/intro/install.md content/ko/docs/intro/install.md +``` + +这个新文件中的内容可以翻译成其他语言。 + +不要在`content/[LANG]/`中添加未翻译的英文文件拷贝。语言存在之后,任何未翻译的页面 +都会自动重定向到英文。翻译需要时间,应该翻译最新版本的文档,而不是过时的fork。 + +确保从头部删除`aliases`行。像 `aliases: ["/docs/using_helm/"]` 不属于翻译。 +这些是旧链接的重定向,新页面不存在这些链接。 + +注意翻译工具可以帮助完成这个过程。包括机器翻译内容。机器翻译内容在发布之前应该由说母语的人编辑或者审查语法和语义。 + +## 在语言之间切换 + +![Screen Shot 2020-05-11 at 11 24 22 +AM](https://user-images.githubusercontent.com/686194/81597103-035de600-937a-11ea-9834-cd9dcef4e914.png) + +站点全局 +[config.toml](https://github.com/helm/helm-www/blob/main/config.toml#L83L89) +文件可以配置语言导航。 + +添加新语言,可以使用上面定义的双字母语言码添加一组参数。比如: + +```toml +# Korean +[languages.ko] +title = "Helm" +description = "Helm - The Kubernetes Package Manager." +contentDir = "content/ko" +languageName = "한국어 Korean" +weight = 1 +``` + +## 解析内部链接 + +翻译的内容有时会包含跳转到其他页面的链接,但只存在于其他语言中。就会出现 +[build errors](https://app.netlify.com/sites/helm-merge/deploys)。比如: + +```shell +12:45:31 PM: htmltest started at 12:45:30 on app +12:45:31 PM: ======================================================================== +12:45:31 PM: ko/docs/chart_template_guide/accessing_files/index.html +12:45:31 PM: hash does not exist --- ko/docs/chart_template_guide/accessing_files/index.html --> #basic-example +12:45:31 PM: ✘✘✘ failed in 197.566561ms +12:45:31 PM: 1 error in 212 documents +``` + +为了解决这个问题,你需要检查翻译中的内部链接。 + +- 锚点链接需要反映翻译的 `id` 值 +- 内部页面链接需要修复 + +对于不存在的内部页, _(或者还未被翻译的)_,站点不会构建,直到修复错误。应急的话可以指向 +另一个已经存在的语言: + +`< relref path="/docs/topics/library_charts.md" lang="en" >` + +查看 [语言之间的交叉引用](https://gohugo.io/content-management/cross-references/#link-to-another-language-version) +获取更多信息。 diff --git a/content/zh/docs/community/related.md b/content/zh/docs/community/related.md new file mode 100644 index 0000000000..e77d63c460 --- /dev/null +++ b/content/zh/docs/community/related.md @@ -0,0 +1,88 @@ +--- +title: "相关项目及文档" +description: "社区提供的第三方工具,插件以及文档!" +weight: 3 +--- + +Helm社区已经创建了很多针对Helm的额外工具,插件和文档。我们乐于听到这些项目声音。 + +如果你有什么需要补充到这里的话,请创建一个 [issue](https://github.com/helm/helm-www/issues) 或者 +[pull request](https://github.com/helm/helm-www/pulls)。 + +## Helm 插件 + +- [helm-adopt](https://github.com/HamzaZo/helm-adopt) - 将现有k8s资源转换成新生成的helm +chart的helm v3插件。 +- [Helm Diff](https://github.com/databus23/helm-diff) - `helm upgrade`的彩色diff预览 +- [Helm Dashboard](https://github.com/komodorio/helm-dashboard) - Helm的GUI界面,可视化release、repository及manifest的差异 +- [helm-gcs](https://github.com/hayorov/helm-gcs) - 管理Google Cloud Storage中仓库的插件 +- [helm-git](https://github.com/aslafy-z/helm-git) - 从Git仓库中安装chart并检索values文件。 +- [helm-k8comp](https://github.com/cststack/k8comp) - 使用k8comp从hiera创建Helm Charts的插件 +- [helm-mapkubeapis](https://github.com/helm/helm-mapkubeapis) - 更新helm发布版本元数据用于替换过期或已移除的k8s API +- [helm-monitor](https://github.com/ContainerSolutions/helm-monitor) - 基于 + Prometheus/ElasticSearch的用于监控版本发布和回滚的插件 +- [helm-release-plugin](https://github.com/JovianX/helm-release-plugin) - 该插件用于管理已部署的release,更新release值,拉取(重建)helm chart,以及设置helm release TTL。 +- [helm-s3](https://github.com/hypnoglow/helm-s3) - 允许使用AWS S3作为[私有]chart仓库的插件 +- [helm-schema-gen](https://github.com/karuppiah7890/helm-schema-gen) - 为Helm + 3生成values的yaml框架的插件 +- [helm-secrets](https://github.com/jkroepke/helm-secrets) - 安全存储密钥的插件 + (基于[sops](https://github.com/mozilla/sops)) +- [helm-sigstore](https://github.com/sigstore/helm-sigstore) - Helm集成[sigstore](https://sigstore.dev/)生态的插件。 +用于搜索、上传及验证已签名的Helm chart。 +- [helm-tanka](https://github.com/Duologic/helm-tanka) - 在Helm chart中渲染Tanka/Jsonnet的插件 +- [hc-unit](https://github.com/xchapter7x/hcunit) - 使用OPA (Open Policy Agent) 和 Rego本地进行chart单元测试的插件 +- [helm-unittest](https://github.com/quintush/helm-unittest) - 使用YAML本地进行chart单元测试的插件 +- [helm-val](https://github.com/HamzaZo/helm-val) - 从之前的版本中获取值的插件 +- [helm-external-val](https://github.com/kuuji/helm-external-val) - 从外部资源(configMaps, +Secrets等)获取Helm values的插件 + +我们同样鼓励使用GitHub的各位使用[helm-plugin](https://github.com/search?q=topic%3Ahelm-plugin&type=Repositories) +给插件仓库打tag。 + +## 额外工具 + +Helm的顶层工具。 + +- [Armada](https://airshipit.readthedocs.io/projects/armada/en/latest/) - 管理各种Kubernetes命名空间中的前缀版本,并删除复杂部署的已完成作业 +- [avionix](https://github.com/zbrookle/avionix) - 生成Helm chart和Kubernetes yaml的Python接口,允许继承及更少的代码重复 +- [Botkube](https://botkube.io) - 直接从Slack,Discord, Microsoft Teams, 和Mattermost运行Helm命令。 +- [Captain](https://github.com/alauda/captain) - 使用HelmRequest和Release CRD的Helm 3控制器 +- [Chartify](https://github.com/appscode/chartify) - 从已经存在的Kubernetes资源中生成Helm chart。 +- [ChartMuseum](https://github.com/helm/chartmuseum) - 支持 Amazon S3 和Google云存储的Helm +Chart仓库 +- [chart-registry](https://github.com/hangyan/chart-registry) - 在OCI注册表上的Helm chart主机 +- [Codefresh](https://codefresh.io) - 带有UI界面的管理Helm chart和版本的Kubernetes原生CI/CD及管理平台 +- [Flux](https://fluxcd.io/docs/components/helm/) - 从Git到Kubernetes的连续和渐进交付 +- [Helmfile](https://github.com/helmfile/helmfile) - Helmfile是用于部署helm chart的声明性规范 +- [Helmsman](https://github.com/Praqma/helmsman) - Helmsman是helm-charts-as-code工具, + 可以从版本控制所需的状态文件(以简单的TOML格式描述)安装、升级、保护、移动及删除发布版本。 +- [Terraform Helm + Provider](https://github.com/hashicorp/terraform-provider-helm) - 为HashiCorp Terraform提供Helm, + 以声明性的结构作为代码的语法实现Helm Chart的生命周期管理。Helm提供者通常与其他Terraform提供者配对, + 类似于Kubernetes提供者,创建一个横跨所有基础服务的通用工作流。 +- [Konveyor Move2Kube](https://konveyor.io/move2kube/) -为现有项目生成Helm chart。 +- [Landscaper](https://github.com/Eneco/landscaper/) - "Landscaper获取一组具有值(所需状态)的Helm +hart引用,并在Kubernetes集群中实现。" +- [Monocular](https://github.com/helm/monocular) - Helm仓库的WEB UI界面。 +- [Monokle](https://monokle.io) - 桌面工具,用于创建、调试和部署Kubernetes资源和Helm Chart。 +- [Orkestra](https://azure.github.io/orkestra/) - 针对一组相关的Helm版本及子chart的云原生编排和生命周期管理平台(LCM)。 +- [Tanka](https://tanka.dev/helm) - Grafana Tanka通过具有使用Helm Chart能力的Jsonnet配置Kubernetes资源 +- [Terraform Helm Provider](https://github.com/hashicorp/terraform-provider-helm) +- HashiCorp Terraform的Helm provider,支持使用声明性代码语法对Helm Chart进行生命周期管理。 +该Helm provider通常与其他Terraform provider配对,比如Kubernetes provider,用于创建跨越所有基础服务的通用工作流。 +- [VIM-Kubernetes](https://github.com/andrewstuart/vim-kubernetes) - Kubernetes和Helm的VIM插件 + +## Helm 已含的 + +Helm支持的平台,发行版本和服务。 + +- [Kubernetic](https://kubernetic.com/) - Kubernetes桌面客户端 +- [Jenkins X](https://jenkins-x.io/) - 使用Helm的Kubernetes开源自动化CI/CD + [promoting](https://jenkins-x.io/docs/getting-started/promotion/) 通过GitOps实现的环境应用程序 + +## Misc + +为Chart作者和Helm用户准备的一些有用的东西。 + +- [Await](https://github.com/saltside/await) - Docker镜像“等待”不同的条件——对初始化容器尤其有用。 + [更多信息](https://blog.slashdeploy.com/2017/02/16/introducing-await/)。 diff --git a/content/zh/docs/community/release_checklist.md b/content/zh/docs/community/release_checklist.md new file mode 100644 index 0000000000..656806bed8 --- /dev/null +++ b/content/zh/docs/community/release_checklist.md @@ -0,0 +1,401 @@ +--- +title: "版本 Checklist" +description: "维护人员在发布下一个Helm版本时的checklist。" +weight: 2 +--- + +# 维护人员发布Helm指南 + +是时候发布新的Helm了!作为Helm维护者发布版本,如果你的经验与这里的文档不同,那你就是 +[更新版本checklist](https://github.com/helm/helm-www/blob/main/content/en/docs/community/release_checklist.md) +的最佳人选。 + +所有版本都将采用vX.Y.Z的形式,X是主版本号,Y是次版本号,Z是补丁发布号。该项目严格遵守 [语义化版本](https://semver.org/), +因此遵循这一点非常重要。 + +Helm会提前宣布下个次版本发布的日期。应尽一切努力遵守宣布的日期。此外,在开始发布过程时,应该选择下一个发布的日期在发布过程中使用。 + +这些说明将涵盖三种不同版本的遵守发布过程的初始配置: + +- 主版本 - 发布频率较低 - 有重大更新时 +- 次版本 - 每3到4个月发布 - 无重大更新 +- 补丁版本 - 每月发布 - 不需要指南中的所有步骤 + +[初始化配置](#initial-configuration) + +1. [创建发布分支](#1-create-the-release-branch) +2. [主/次版本:在Git中更改版本号](#2-majorminor-releases-change-the-version-number-in-git) +3. [主/次版本:提交并推送发布分支](#3-majorminor-releases-commit-and-push-the-release-branch) +4. [主/次版本:创建一个候选发布](#4-majorminor-releases-create-a-release-candidate) +5. [主/次版本:迭代连续的候选版本](#5-majorminor-releases-iterate-on-successive-release-candidates) +6. [完成发布](#6-finalize-the-release) +7. [编写发布日志](#7-write-the-release-notes) +8. [PGP签名下载](#8-pgp-sign-the-downloads) +9. [发布版本](#9-publish-release) +10. [更新文档](#10-update-docs) +11. [告知社区](#11-tell-the-community) + +## Initial Configuration + +### 设置远程Git + +需要注意的是该文档假设你的远程upstream仓库关联到了。 +如果不是(比如,如果你选择了“origin”或其他类似的替代),请确保根据本地环境调整列出的代码段。 +如果你不确定使用了什么远程的upstream,使用`git remote -v`命令查看。 + +如果你没有[上游远程](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/configuring-a-remote-for-a-fork), +可以类似这样添加: + +```shell +git remote add upstream git@github.com:helm/helm.git +``` + +### 设置环境变量 + +在该文档中,我们还会引用一些环境变量,更便于设置。针对主、次版本,使用以下选项: + +```shell +export RELEASE_NAME=vX.Y.0 +export RELEASE_BRANCH_NAME="release-X.Y" +export RELEASE_CANDIDATE_NAME="$RELEASE_NAME-rc.1" +``` + +如果你在创建一个补丁版本,改用以下命令: + +```shell +export PREVIOUS_PATCH_RELEASE=vX.Y.Z +export RELEASE_NAME=vX.Y.Z+1 +export RELEASE_BRANCH_NAME="release-X.Y" +``` + +### 设置签名Key + +我们还会通过对二进制文件和提供的签名文件进行哈希计算增加发布过程的安全性和认证。 +使用[GitHub 和 GPG](https://help.github.com/en/articles/about-commit-signature-verification)来执行。 +如果还没设置GPG可以按照以下步骤操作: + +1. [安装 GPG](https://gnupg.org/index.html) +2. [生成 GPG key](https://help.github.com/en/articles/generating-a-new-gpg-key) +3. [将key添加到GitHub账户中](https://help.github.com/en/articles/adding-a-new-gpg-key-to-your-github-account) +4. [在Git中设置签名密钥](https://help.github.com/en/articles/telling-git-about-your-signing-key) + +一旦你有了签名密钥,需要将其添加到仓库根目录中的KEYS文件中。文件中有添加密钥到KEY文件的说明。如果还没有,需要将公钥添加到keyserver。 +如果使用了GnuPG,可以参照[Debian提供的说明](https://debian-administration.org/article/451/Submitting_your_GPG_key_to_a_keyserver)。 + +## 1. Create the Release Branch + +### 主、次版本 + +主版本是为新特性及操作且*不具有向后兼容性*。次版本是为了不破坏向后兼容性的新特性。创建一个主版本或次版本,从主干分支创建`release-X.Y`分支。 + +```shell +git fetch upstream +git checkout upstream/main +git checkout -b $RELEASE_BRANCH_NAME +``` + +这个新分支是发布版本的基础分支,会在后面不断迭代。 + +为GitHub上已存在的版本验证[helm/helm里程碑](https://github.com/helm/helm/milestones)。 +确保针对这个版本的PR和issue都在这个里程碑中。 + +针对主版本和次版本,跳转到 2: [主/次版本:在Git中更改版本号](#2-majorminor-releases-change-the-version-number-in-git)。 + +### 补丁版本 + +补丁版本是一些已有版本中严格的cherry-picked修复。以创建`release-X.Y`分支开始: + +```shell +git fetch upstream +git checkout -b $RELEASE_BRANCH_NAME upstream/$RELEASE_BRANCH_NAME +``` + +在这里可以cherry-pick出需要带到补丁版本中的提交: + +```shell +# get the commits ids we want to cherry-pick +git log --oneline +# cherry-pick the commits starting from the oldest one, without including merge commits +git cherry-pick -x +``` + +挑出提交之后这个版本分支需要被推送。 + +```shell +git push upstream $RELEASE_BRANCH_NAME +``` + +推送分支会触发测试。创建tag之前确保测试是通过的。 +这个新tag将成为补丁版本的基础。 + +针对补丁版本,创建[helm/helm里程碑](https://github.com/helm/helm/milestones)是可选的。 + +继续之前确保[helm 在 CircleCI](https://circleci.com/gh/helm/helm)通过CI。补丁版本可以跳过2-5步, +直接执行6 [完成发布](#6-finalize-the-release)。 + +## 2. Major/Minor releases: Change the Version Number in Git + +当有主版本或次版本发布时,确保用新版本更新`internal/version/version.go`。 + +```shell +$ git diff internal/version/version.go +diff --git a/internal/version/version.go b/internal/version/version.go +index 712aae64..c1ed191e 100644 +--- a/internal/version/version.go ++++ b/internal/version/version.go +@@ -30,7 +30,7 @@ var ( + // Increment major number for new feature additions and behavioral changes. + // Increment minor number for bug fixes and performance enhancements. + // Increment patch number for critical fixes to existing releases. +- version = "v3.3" ++ version = "v3.4" + + // metadata is extra build time data + metadata = "" +``` + +除了在`version.go`文件中更行版本,还需要更新使用了新版本的相关测试。 + +- `cmd/helm/testdata/output/version.txt` +- `cmd/helm/testdata/output/version-client.txt` +- `cmd/helm/testdata/output/version-client-shorthand.txt` +- `cmd/helm/testdata/output/version-short.txt` +- `cmd/helm/testdata/output/version-template.txt` +- `pkg/chartutil/capabilities_test.go` + +```shell +git add . +git commit -m "bump version to $RELEASE_NAME" +``` + +这只会对$RELEASE_BRANCH_NAME更新。也许要在下个版本更新时推送到主干分支,就像 [3.2 更新到 +3.3](https://github.com/helm/helm/pull/8411/files),并将其添加到下一个版本的里程碑中。 + +```shell +# get the last commit id i.e. commit to bump the version +git log --format="%H" -n 1 + +# create new branch off main +git checkout main +git checkout -b bump-version- + +# cherry pick the commit using id from first command +git cherry-pick -x + +# commit the change +git push origin bump-version- +``` + +## 3. Major/Minor releases: Commit and Push the Release Branch + +为了让他人开始测试,我们可以推送发布分支到upstream并开始测试过程。 + +```shell +git push upstream $RELEASE_BRANCH_NAME +``` + +继续之前确保 [helm 在CircleCI](https://circleci.com/gh/helm/helm)版本通过CI。 + +如果有人可用,让其他人在确保所有更改都已正确处理且所有该版本的提交都已存在,并提前对分支进行同行评审。 + +## 4. Major/Minor releases: Create a Release Candidate + +现在,发布分支已经准备好了,可以开始创建和迭代候选版本了。 + +```shell +git tag --sign --annotate "${RELEASE_CANDIDATE_NAME}" --message "Helm release ${RELEASE_CANDIDATE_NAME}" +git push upstream $RELEASE_CANDIDATE_NAME +``` + +CircleCI 会自动创建一个打tag的发布镜像,同时测试客户端库。 + +对测试人员来说,在CircleCI完成测试构建过程之后开始测试,包括以下步骤来获取客户端: + +linux/amd64, 使用 /bin/bash: + +```shell +wget https://get.helm.sh/helm-$RELEASE_CANDIDATE_NAME-linux-amd64.tar.gz +``` + +darwin/amd64, 使用 Terminal.app: + +```shell +wget https://get.helm.sh/helm-$RELEASE_CANDIDATE_NAME-darwin-amd64.tar.gz +``` + +windows/amd64, 使用 PowerShell: + +```shell +PS C:\> Invoke-WebRequest -Uri "https://get.helm.sh/helm-$RELEASE_CANDIDATE_NAME-windows-amd64.tar.gz" -OutFile "helm-$ReleaseCandidateName-windows-amd64.tar.gz" +``` + +然后,将二进制包解压并移动到$PATH目录中,或者移动到某个位置并添加$PATH(比如linux/macOS的/usr/local/bin/helm,windows的 +C:\Program Files\helm\helm.exe for Windows)。 + +## 5. Major/Minor releases: Iterate on Successive Release Candidates + +花了几天时间和资源去尝试用各种方式破坏helm,将所有的相关发现都记录到发布中。这段时间应该花在测试和寻找发行版可能导致各种特性或升级环境出现问题的方法上, +不要编码。这段时间发布版本应该冻结代码,且任何要添加的代码更新都推到下个发布版本中。 + +这个阶段,$RELEASE_BRANCH_NAME 会随着你新产生的候选发布不断发展。新候选的频率取决于发布管理员:依据报告问题的严重性、 +测试人员效率和发布期限做出最佳判断。一般来说,即使跨过最后期限也不能发布坏版本。 + +在每次创建新的候选发布时,需要以添加从主干分支检出的commit开始: + +```shell +git cherry-pick -x +``` + +你也需要推送这个分支到GitHub并保证通过CI。 + +然后打tag并通知用户有新的候选版本了: + +```shell +export RELEASE_CANDIDATE_NAME="$RELEASE_NAME-rc.2" +git tag --sign --annotate "${RELEASE_CANDIDATE_NAME}" --message "Helm release ${RELEASE_CANDIDATE_NAME}" +git push upstream $RELEASE_CANDIDATE_NAME +``` + +一旦推送到了GitHub,检查分支确保tag在CI中构建。 + +从这里重复这个过程,持续测试直到你对候选发布满意为止。对于发布候选,我们不写完整的记录,但可以写一下 +[发布日志](#7-write-the-release-notes)。 + +## 6. Finalize the Release + +当你最终对自己的候选发布的质量感到满意时,可以继续并创建一个真正的发布。 最后再检查一次确保一切正常,最后推送这个发布的tag。 + +```shell +git checkout $RELEASE_BRANCH_NAME +git tag --sign --annotate "${RELEASE_NAME}" --message "Helm release ${RELEASE_NAME}" +git push upstream $RELEASE_NAME +``` + +在[CircleCI](https://circleci.com/gh/helm/helm)中验证发布是否成功。如果不行,需要修复这个版本并重新推送。 + +由于CI作业需要运行一段时间,你可以在等待其完成时去写发布日志。 + +## 7. Write the Release Notes + +我们会根据发布周期提交的记录自动生成一个更新日志,但是,如果发布说明是由人或市场团队手写的,通常对最终用户会更有利。 + +如果你在发布一个主或次版本,一般列出值得注意的面向用户的特性就足够了。对于补丁版本同样,但要标记出问题和会受影响的人。 + +发布日志应该包含版本号和下一个版本的计划发布日期。 + +针对次要版本的发布日志示例如下: + +```markdown +## vX.Y.Z + +Helm vX.Y.Z is a feature release. This release, we focused on . Users are encouraged to upgrade for the best experience. + +The community keeps growing, and we'd love to see you there! + +- Join the discussion in [Kubernetes Slack](https://kubernetes.slack.com): + - `#helm-users` for questions and just to hang out + - `#helm-dev` for discussing PRs, code, and bugs +- Hang out at the Public Developer Call: Thursday, 9:30 Pacific via [Zoom](https://zoom.us/j/696660622) +- Test, debug, and contribute charts: [Artifact Hub helm charts](https://artifacthub.io/packages/search?kind=0) + +## Notable Changes + +- Kubernetes 1.16 is now supported including new manifest apiVersions +- Sprig was upgraded to 2.22 + +## Installation and Upgrading + +Download Helm X.Y. The common platform binaries are here: + +- [MacOS amd64](https://get.helm.sh/helm-vX.Y.Z-darwin-amd64.tar.gz) ([checksum](https://get.helm.sh/helm-vX.Y.Z-darwin-amd64.tar.gz.sha256sum) / CHECKSUM_VAL) +- [Linux amd64](https://get.helm.sh/helm-vX.Y.Z-linux-amd64.tar.gz) ([checksum](https://get.helm.sh/helm-vX.Y.Z-linux-amd64.tar.gz.sha256sum) / CHECKSUM_VAL) +- [Linux arm](https://get.helm.sh/helm-vX.Y.Z-linux-arm.tar.gz) ([checksum](https://get.helm.sh/helm-vX.Y.Z-linux-arm.tar.gz.sha256) / CHECKSUM_VAL) +- [Linux arm64](https://get.helm.sh/helm-vX.Y.Z-linux-arm64.tar.gz) ([checksum](https://get.helm.sh/helm-vX.Y.Z-linux-arm64.tar.gz.sha256sum) / CHECKSUM_VAL) +- [Linux i386](https://get.helm.sh/helm-vX.Y.Z-linux-386.tar.gz) ([checksum](https://get.helm.sh/helm-vX.Y.Z-linux-386.tar.gz.sha256) / CHECKSUM_VAL) +- [Linux ppc64le](https://get.helm.sh/helm-vX.Y.Z-linux-ppc64le.tar.gz) ([checksum](https://get.helm.sh/helm-vX.Y.Z-linux-ppc64le.tar.gz.sha256sum) / CHECKSUM_VAL) +- [Linux s390x](https://get.helm.sh/helm-vX.Y.Z-linux-s390x.tar.gz) ([checksum](https://get.helm.sh/helm-vX.Y.Z-linux-s390x.tar.gz.sha256sum) / CHECKSUM_VAL) +- [Windows amd64](https://get.helm.sh/helm-vX.Y.Z-windows-amd64.zip) ([checksum](https://get.helm.sh/helm-vX.Y.Z-windows-amd64.zip.sha256sum) / CHECKSUM_VAL) + +The [Quickstart Guide](https://docs.helm.sh/using_helm/#quickstart-guide) will get you going from there. For **upgrade instructions** or detailed installation notes, check the [install guide](https://docs.helm.sh/using_helm/#installing-helm). You can also use a [script to install](https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3) on any system with `bash`. + +## What's Next + +- vX.Y.Z+1 will contain only bug fixes and is planned for . +- vX.Y+1.0 is the next feature release and is planned for . This release will focus on ... + +## Changelog + +- chore(*): bump version to v2.7.0 08c1144f5eb3e3b636d9775617287cc26e53dba4 (Adam Reese) +- fix circle not building tags f4f932fabd197f7e6d608c8672b33a483b4b76fa (Matthew Fisher) +``` + +通过运行以下命令可以创建一组包括更新日志的部分完成的发行说明: + +```shell +export VERSION="$RELEASE_NAME" +export PREVIOUS_RELEASE=vX.Y.Z +make clean +make fetch-dist +make release-notes +``` + +这回生成一个发行日志的良好基线,你仅仅需要填写 **Notable Changes** 和 **What's next** 部分。 + +可以在发布日志中随意添加你想说的,对用户来说会很好而不至于感觉我们是机器人。 + +你也需要再次检查自动生成的日志中的URL和校验和。 + +完成之后,去GitHub的 [helm/helm releases](https://github.com/helm/helm/releases) +中为已打tag的版本编辑发布说明。对于目标分支,设置$RELEASE_BRANCH_NAME。 + +现在需要让其他人在发行版本发布之前看看发行说明。发一个request到 +[#helm-dev](https://kubernetes.slack.com/messages/C51E88VDG)用于评审。发行日志很容易漏掉一些东西,因此评审总是有用的。 + +## 8. PGP Sign the downloads + +哈希生成一个表明下载内容就是其生成内容的签名,签名包提供了包来自何处的可追溯性。 + +为此,要执行以下 `make` 命令: + +```shell +export VERSION="$RELEASE_NAME" +make clean # if not already run +make fetch-dist # if not already run +make sign +``` + +这会生成通过CI推送的每个文件的ascii封装的签名文件。 + +所有的签名文件(`*.asc`)需要上传到GitHub中的发布版本(附件二级制文件)中。 + +## 9. Publish Release + +是时候正式发布了! + +发布说明保存在GitHub之后,CI构建已经完成,并且已经添加了发布版本的签名文件,你可以在发布版本上点击 "Publish" 了。 +发布的版本,标记为"latest",并在[helm/helm](https://github.com/helm/helm)仓库的首页显示这个发布版本。 + +## 10. Update Docs + +[Helm站点文档部分](https://helm.sh/docs)列出了Helm版本的文档。主、次及补丁版本需要更行到这个站点。 +下一个次要版本的发布日期也要发布出来且必须更新。这要创建一个pull request 到 +[helm-www仓库](https://github.com/helm/helm-www)。在 `config.toml` 文件中找到合适的 +`params.versions`部分并更新Helm版本,例如 [更新当前版本](https://github.com/helm/helm-www/pull/676/files)。 +在同一个`config.toml`文件中,更新`params.nextversion`部分。 + +如果需要,关闭这个版本的[helm/helm 里程碑](https://github.com/helm/helm/milestones)。 + +为主版本和次版本更新[version skew](https://github.com/helm/helm-www/blob/main/content/en/docs/topics/version_skew.md)。 + +在[这里](https://helm.sh/calendar/release)更新版本日历: + +- 为下一个次要版本创建一个条目并在GMT下午5点设置提醒 +- 在计划发布的前一周的周一为下一个次要版本的RC1创建一个条目,设置GMT下午5点的提醒 + +## 11. Tell the Community + +恭喜,你已经完成了。去喝一杯吧。这是你应得的。 + +然后继续前进并在Slack和Twitter上宣布这个新分支,并链接到[GitHub发布版本](https://github.com/helm/helm/releases)。 + +或者,写一篇新版本的blog并在上面展示一些新特性! diff --git a/content/zh/docs/faq/_index.md b/content/zh/docs/faq/_index.md new file mode 100644 index 0000000000..1a8af0e4d4 --- /dev/null +++ b/content/zh/docs/faq/_index.md @@ -0,0 +1,486 @@ +--- +title: "常见问答(FAQ)" +weight: 8 +--- + +# 常见问答 + +> Helm 2和Helm 3的主要区别是什么? +> 该页面为最常见的问题提供帮助。 + +**我们喜欢您的帮助** 使得该文档变得更好。添加、修改或移除信息, + [提问题](https://github.com/helm/helm-www/issues)或者向我们提交pull request。 + +## 从Helm 2发生的变化 + +这里会展示一个对Helm3主要引入的变化的详尽列表。 + +### 移除了Tiller + +在Helm 2的开发周期中,我们引入了Tiller。Tiller在团队协作中共享集群时扮演了重要角色。 +它使得不同的操作员与相同的版本进行交互称为了可能。 + +Kubernetes 1.6默认使用了基于角色的访问控制(RBAC),在生产环境对Tiller的锁定使用变得难于管理。 +由于大量可能的安全策略,我们的立场是提供一个自由的默认配置。这样可以允许新手用户可以乐于尝试Helm +和Kubernetes而不需要深挖安全控制。 不幸的是这种自由的配置会授予用户他们不该有的权限。DevOps和SRE +在安装多用户集群时不得不去学习额外的操作步骤。 + +在听取了社区成员在特定场景使用Helm之后,我们发现Tiller的版本管理系统不需要依赖于集群内部用户去维护 +状态或者作为一个Helm版本信息的中心hub。取而代之的是,我们可以简单地从Kubernetes API server获取信息, +在Chart客户端处理并在Kubernetes中存储安装记录。 + +Tiller的首要目标可以在没有Tiller的情况下实现,因此针对于 Helm 3 我们做的首要决定之一就是完全移除Tiller。 + +随着Tiller的消失,Helm的安全模块从根本上被简化。Helm 3 现在支持所有Kubernetes流行的安全、 +身份和授权特性。Helm的权限通过你的 +[kubeconfig文件](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/)进行评估。 +集群管理员可以限制用户权限,只要他们觉得合适, +无论什么粒度都可以做到。版本发布记录和Helm的剩余保留功能仍然会被记录在集群中。 + +### 改进升级策略: 三路策略合并补丁 + +Helm 2 使用了一种双路策略合并补丁。在升级过程中,会对比最近一次的chart manifest和提出的 +chart manifest(通过`helm upgrade`提供)。升级会对比两个chart的不同来决定哪些更改会应用到Kubernetes资源中。 +如果更改是集群外带的(比如通过`kubectl edit`),则不会被考虑。结果就是资源不会回滚到之前的状态: +因为Helm只考虑最后一次应用的chart manifest作为它的当前状态,如果chart状态没有更改,则资源的活动状态不会更改。 + +现在Helm 3中,我们使用一种三路策略来合并补丁。Helm在生成一个补丁时会考虑之前老的manifest的活动状态。 + +#### 示例 + +让我们通过一些常见的例子来看看变化带来的影响。 + +##### 回滚已经改变的活动状态 + +你的团队正好在Kubernetes上使用Helm部署了生产环境应用。chart包含了一个部署对象使用了三套副本: + +```console +$ helm install myapp ./myapp +``` + +一个开发新人加入了团队。当他们第一点观察生产环境集群时,发生了一个像是咖啡洒在了键盘上一样的严重事故, +他们使用 `kubectl scale` 对生产环境部署进行缩容,将副本数从3降到了0 。 + +```console +$ kubectl scale --replicas=0 deployment/myapp +``` + +团队里面的另一个人看到线上环境已经挂了就决定回滚这个版本到之前的状态: + +```console +$ helm rollback myapp +``` + +发生了什么? + +在Helm 2中,会生成一个补丁并对比老的manifest和新的manifest。因为这是一个回滚,manifest是一样的。 +Helm会认为新老manifest没有区别,因此没有需要更改的内容。副本统计数量继续保持为0。恐慌就接踵而至。 + +在Helm 3中,是用老的manifest生成新的补丁,活动状态和新的manifest。 +Helm 意识到老的状态是3,而现有活动状态是0,并且新的manifest希望改回3,因此会生成一个补丁将状态改回3。 + +##### 活动状态已更改的情况下升级 + +很多服务网格和其他基于controller的应用向Kubernetes对象中注入数据。比如sidecar、label和其他信息。 +之前如果你从Chart渲染给定的manifest如下: + +```yaml +containers: +- name: server + image: nginx:2.0.0 +``` + +并且另一个应用修改活动状态如下: + +```yaml +containers: +- name: server + image: nginx:2.0.0 +- name: my-injected-sidecar + image: my-cool-mesh:1.0.0 +``` + +现在你想升级`nginx`镜像到`2.1.0`。因此用指定的manifest升级chart: + +```yaml +containers: +- name: server + image: nginx:2.1.0 +``` + +发生了什么? + +在Helm 2中,Helm 在新老manifest之间生成了一个`containers`对象的补丁。 +生成补丁的过程中不考虑集群的活动状态。 + +集群的活动状态被修改成了这样: + +```yaml +containers: +- name: server + image: nginx:2.1.0 +``` + +sidecar pod从活动状态中移除了。更多的恐慌袭来。 + +在Helm 3中,Helm 在新的manifest、活动状态和老manifest之间生成了一个`containers`对象的补丁。 +会注意到新的manifest将镜像tag更新为`2.1.0`, 但是活动状态中包含了一个sidecar容器。 + +集群的活动状态被修改成了下面这样: + +```yaml +containers: +- name: server + image: nginx:2.1.0 +- name: my-injected-sidecar + image: my-cool-mesh:1.0.0 +``` + +### 发布名称现在限制在namespace范围内 + +随着Tiller的移除, 每个版本的信息需要保存在某个地方。 +在Helm 2中,是存储在Tiller相同的命名空间中。 +实际上这意味着一个发布版本使用一个名称,其他发布不能使用相同的名称, +即使在不同的命名空间中也不行。 + +在Helm 3中,特定的版本信息作为发布本身存储在相同的命名空间中。 +意味着用户现在可以在两个分开的命名空间中使用`helm install wordpress stable/wordpress`, +并且每个都能使用 `helm list` 改变当前命名空间。 (例如 `helm list --namespace foo`)。 + +与本地集群命名空间更好的一致性,使得 `helm list` 命令不再需要默认列出所有发布版本的列表。 +取而代之的是,仅仅会在命名空间中列出当前kubernetes上下文的版本。 +(也就是说运行`kubectl config view --minify`时会显示命名空间). 也就意味着您在执行`helm list`时必须提供 + `--all-namespaces` 标识才能获得和Helm 2同样的结果。 + +### 作为默认存储器的密钥 + +在 Helm 3中, 密钥被作为[默认存储驱动](https://helm.sh/zh/docs/topics/advanced#后端存储)使用。 +Helm 2默认使用ConfigMaps记录版本信息。在Helm 2.7.0中,新的存储后台使用密钥来存储版本信息, +现在是Helm 3的默认设置。 + +Helm 3默认允许更改密钥作为额外的安全措施在Kubernetes中和密钥加密一起保护chart。 + +[静态加密密钥](https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/) +在Kubernetes 1.7中作为alpha特性可以使用了,在Kubernetes 1.13中变成了稳定特性。 +这允许用户静态加密Helm的发布元数据,同时也是一个类似Vault的以后可扩展的良好起点。 + +### 更改了Go的path导入 + +在Helm 3中,Helm将Go的import路径从`k8s.io/helm`切换到了`helm.sh/helm/v3`。如果你打算 +升级到Helm 3的Go客户端库,确保你已经更改了import路径。 + +### Capabilities + +`.Capabilities`内置对象会在已经简化的渲染阶段生效。 + +[内置对象](https://helm.sh/zh/docs/chart_template_guide/builtin_objects/) + +### 使用Json格式验证Chart Values + +chart values现在可以使用JSON结构了。这保证用户提供value可以按照chart维护人员设置的结构排列, +并且当用户提供了错误的chart value时会有更好错误提示。 + +当调用以下命令时会进行JSON格式验证: + +* `helm install` +* `helm upgrade` +* `helm template` +* `helm lint` + +查看 [格式文档](https://docs.helm.sh/zh/docs/topics/charts#架构文件) 了解更多信息。 + +### 将 `requirements.yaml` 合并到了 `Chart.yaml` + +Chart依赖体系从 requirements.yaml 和 requirements.lock 移动到 Chart.yaml +和 Chart.lock。我们推荐在Helm 3的新chart中使用新格式。不过Helm 3 依然可以识别 +Chart API 版本1 (`v1`) 并且会加载已有的 `requirements.yaml` 文件。 + +Helm 2中,`requirements.yaml` 看起来是这样的: + +```yaml +dependencies: +- name: mariadb + version: 5.x.x + repository: https://charts.helm.sh/stable + condition: mariadb.enabled + tags: + - database +``` + +Helm 3中, 依赖使用了同样的表达方式,现在`Chart.yaml`是这样的: + +```yaml +dependencies: +- name: mariadb + version: 5.x.x + repository: https://charts.helm.sh/stable + condition: mariadb.enabled + tags: + - database +``` + +Chart会依然下载和放置在 `charts/` 目录, 因此 `charts/` 目录中的子chart不作修改即可继续工作。 + +### Name (或者 --generate-name) 安装时是必需的 + +Helm 2中,如果没有提供名称, 会自动生成一个名称。在生产环境,这被证明是一个麻烦事而不是一个有用的特性。 +而在Helm 3中,如果 `helm install` 没有提供name,会抛异常。 + +如果仍然需要一个自动生成的名称,您可以使用 `--generate-name` 创建。 + +### 推送Chart到OCI注册中心 + +这是一个Helm 3 中的实验性特性。使用时需要设置环境变量 `HELM_EXPERIMENTAL_OCI=1`。 + +Chart仓库在较高层次上是一个存储和分发Chart的地址。Helm客户端打包并将Chart推送到Chart仓库中。 +简单来说,Chart仓库就是一个基本的HTTP服务器用来存放index.yaml文件和打包的chart。 + +Chart 仓库API满足最基本的需求有一些好处,但是有些缺点开始显现出来: + +* Chart 仓库很难在生产环境抽象出大部分的安全性实现。在生产环境有一个认证和授权的标准API就显得格外重要。 +* Helm Chart的初始化工具用来签名和验证chart的完整性和来源,在chart的发布过程中是可选的。 +* 在多客户场景中,同一个chart可以被其他客户上传,同样的内容会被存储两次。chart仓库可以更加智能地处理 +这个问题,但并不是正式规范的一部分。 +* 在安全的多客户实现中使用单一的索引文件进行搜索、元数据信息存放和获取chart会变得困难和笨拙。 + +Docker的分发项目(也称作Docker注册中心 v2)是Docker 注册项目的继承者。 很多主要的云供应商都提供项目 +分发,很多供应商都提供相同的产品, 这个分发项目得益于多年的强化、安全性实践和对抗测试。 + +请查看 `helm help chart` 和 `helm help registry` 了解如何打包chart并推送到Docker注册中心的更多信息。 + +更多信息请查看 [注册中心](https://docs.helm.sh/zh/docs/topics/registries/)页面。 + +### 移除了`helm serve` + +`helm serve` 命令可以在你本地机器运行一个Chart仓库用于开发目的。 +然而作为一个开发工具并没有受到太多利用,并且设计上有很多问题。最终我们决定移除它, +拆分成了一个插件。 + +对于 `helm serve` 的类似经历,可以查看本地文件系统存储选项在 +[ChartMuseum](https://chartmuseum.com/docs/#using-with-local-filesystem-storage) +和 [servecm plugin](https://github.com/jdolitsky/helm-servecm). + +### Library chart支持 + +Helm 3 支持的一类chart称为 “library chart”。 这是一个被其他chart共享的chart, +但是它自己不能创建发布组件。library chart的模板只能声明 `define` 元素。 全局范围 +内的非`define`内容会被简单忽略。这允许用户复用和共享可在多个chart中重复使用的代码片段。 +避免冗余和保留chart [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself)。 + +Library chart在 Chart.yaml的依赖指令中声明,安装和管理与其他chart一致。 + +```yaml +dependencies: + - name: mylib + version: 1.x.x + repository: quay.io +``` + +我们很高兴对开发者开放了这个特性的使用案例,以及library charts使用的最佳实践。 + +### Chart.yaml api版本切换 + +随着对library chart的支持以及requirements.yaml合并到Chart.yaml,客户端可以识别Helm 2的包格式而不理解 +这些新特性。因此我们将Chart.yaml的apiVersion从 `v1` 切换到了 `v2`。 + +`helm create` 现在使用使用新格式创建chart,默认的apiVersion也切换到了这里。 + +客户端希望同时支持两个版本,进而能够检查Chart.yaml的`apiVersion`字段去理解如何解析包格式。 + +### XDG 基本目录支持 + +[XDG 基本目录规范](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html) +是一个定义了配置、数据和缓存文件应该存储在文件系统什么位置的可移植标准。 + +Helm 2中,Helm 将所有的信息存储在 `~/.helm` (被亲切地称为`helm home`),可以通过设置 `$HELM_HOME` +环境变量修改,或者使用全局参数 `--home`。 + +Helm 3中,Helm现在遵守XDG 基本目录规范使用以下环境变量: + +* `$XDG_CACHE_HOME` +* `$XDG_CONFIG_HOME` +* `$XDG_DATA_HOME` + +Helm 插件仍然使用 `$HELM_HOME` 作为 `$XDG_DATA_HOME` 的别名,以便希望将`$HELM_HOME`作为过渡环境的变量来保证向后兼容性。 + +一些新的环境变量也通过插件环境变量来兼容以下更改: + +* `$HELM_PATH_CACHE` 针对缓存路径 +* `$HELM_PATH_CONFIG` 针对配置路径 +* `$HELM_PATH_DATA` 针对data路径 + +如果Helm插件期望支持Helm 3,建议使用新的环境变量。 + +### CLI 命令重新命名 + +为了更好地从包管理器中调整不当措辞,`helm delete`被重命名为`helm uninstall`。 + `helm delete` 依然作为 `helm uninstall` 的别名保留, 因此其他格式也能使用。 + +Helm 2 中为了清除版本清单,必须提供`--purge`参数。这个功能现在是默认使用的。 +为保留之前的操作行为,要使用 `helm uninstall --keep-history`。 + +另外,其他一些重命名的命令提供了以下约定: + +* `helm inspect` -> `helm show` +* `helm fetch` -> `helm pull` + +这些命令都保留了老的动词作为别名,因此您能够使用任意一种格式。 + +### 自动创建namespace + +当用命名空间创建版本时,命名空间不存在,Helm 2会创建一个命名空间。 +Helm 3中沿用了其他Kubernetes 工具的形式,如果命名空间不存在,就返回错误。 +如果您明确指定 `--create-namespace` 参数,Helm 3 会创建一个命名空间。 + +### .Chart.ApiVersion是怎么回事? + +Helm针对缩略语遵循驼峰命名的典型惯例。我们已经在代码的其他位置做了处理,比如 +`.Capabilities.APIVersions.Has`。Helm v3中,我们将 `.Chart.ApiVersion` +更正成了`.Chart.APIVersion`。 + +## 安装 + +### 为什么没有针对Fedora和其他Linux发行版的Helm原生包? + +Helm 项目不维护针对操作系统和环境的包。Helm 社区如果觉得需要提供原生包时,可以提供原生包。 +这是Homebrew 开始列出的方案。如果您有兴趣维护一个包,我们会很高兴的。 + +### 为什么会提供 `curl ...|bash` 脚本? + +我们的仓库(`scripts/get-helm-3`)中有个脚本可以作为 `curl ..|bash` 脚本执行。 +使用HTTPS传输,The transfers are all protected by HTTPS, 并且这个脚本对它获取到包做一些审核。 +然而这个脚本有任何shell脚本的所有常见危险。 + +我们提供这个脚本因为它很好用,但是我们建议用户先仔细阅读这个脚本。不过我们真正想要的是更好的Helm打包版本。 + +### 我如何将Helm客户端文件放置在其他位置而不是默认位置? + +Helm 使用XDG结构存储文件。这些环境变量可以用来覆盖默认位置: + +* `$XDG_CACHE_HOME`: 设置另一个存储缓存文件的位置。 +* `$XDG_CONFIG_HOME`: 设置另一个存储Helm配置的位置。 +* `$XDG_DATA_HOME`: 设置另一个存储Helm数据的位置。 + +注意,如果有已经存在的仓库,您需要使用 `helm repo add...` 重新添加。 + +## 卸载 + +### 我想删除我本地Helm. 全部文件在什么位置? + +连同 `helm` 二进制文件一起,Helm将文件存储在以下位置: + +* $XDG_CACHE_HOME +* $XDG_CONFIG_HOME +* $XDG_DATA_HOME + +下面这个表格按照操作系统给出了对应的默认文件夹位置: + +| Operating System | Cache Path | Configuration Path | Data Path | +|------------------|-----------------------------|----------------------------------|---------------------------| +| Linux | `$HOME/.cache/helm` | `$HOME/.config/helm` | `$HOME/.local/share/helm` | +| macOS | `$HOME/Library/Caches/helm` | `$HOME/Library/Preferences/helm` | `$HOME/Library/helm` | +| Windows | `%TEMP%\helm` | `%APPDATA%\helm` | `%APPDATA%\helm` | + +## 故障排除 + +### 在 GKE (Google Container Engine) 我遇到了 "No SSH tunnels currently open" + +```consol +Error: Error forwarding ports: error upgrading connection: No SSH tunnels currently open. Were the targets able to accept an ssh-key for user "gke-[redacted]"? +``` + +另一个错误消息的形式: + +```consol +Unable to connect to the server: x509: certificate signed by unknown authority +``` + +这个问题是说您本地的Kubernetes 配置文件需要有正确的证书。 + +当你在GKE上创建集群时,它会为您提供一个证书,包括SSL证书和证书颁发机构。 +这些需要放在Kubernetes配置文件中(默认位置: `~/.kube/config`),保证 `kubectl` 和 `helm` 可以访问他们。 + +### 从Helm 2迁移后, `helm list` 仅显示部分(或者不显示)我的发布版本 + +您很可能忽略了一个事实:Helm 3 现在使用集群的命名空间来确定版本范围。 这意味着所有涉及版本的命令您都必须: + +* 在活动的kubernetes上下文中需要依赖当前的命名空间 (如 `kubectl config view --minify` 命令所述), +* 使用 `--namespace`/`-n` 参数指定正确命名空间,或者 +* 对于 `helm list` 命令,指定 `--all-namespaces`/`-A` 参数 + +这适用于 `helm ls`、 `helm uninstall` 以及其他所有涉及版本的 `helm` 命令。 + +### 为什么在macOS上`/etc/.mdns_debug`文件可以访问? + +我们了解到macOS上的一个案例是Helm会试图访问`/etc/.mdns_debug`文件。 +如果文件存在,Helm会在文件句柄执行的时候保持打开状态。 + +这是因为macOS的 MDNS 库。它尝试去加载这个文件读取debug设置(如果已经启用)。 +这个文件句柄可能不会保持打开,且这个问题已经报告给了苹果。 然而这种行为是macOS导致的,并不是Helm。 + +如果你不想让Helm加载这个文件,你可以将Helm编译成一个静态库而不使用主机网络堆栈。 +这样做会导致Helm的二进制文件大小膨胀,但是会阻止这个文件打开。 + +这个问题最初被标记为潜在的安全问题。但后来已经确定,这种行为不存在任何缺陷或漏洞。 + +### helm 仓库使用时添加仓库失败 + +在Helm 3.3.1及之前版本,`helm repo add `在你添加已经存在的仓库时不会输入内容。 +如果仓库已经存在,`--no-update` 参数会报错。 + +在Helm3.3.2及之后版本,试图添加一个已存在的仓库时会报以下错误: + +`Error: repository name (reponame) already exists, please specify a different name` + +现在这个默认行为是相反的。`--no-update` 现在被忽略。当您想替换(覆盖)已有仓库时,您可以使用 `--force-update`。 + +这是由于一个安全修复做出的重大更改,详情见[Helm 3.3.2 release notes](https://github.com/helm/helm/releases/tag/v3.3.2)。 + +### 开启 Kubernetes 客户端日志 + +调试Kubernetes客户端打印日志时,可以使用[klog](https://pkg.go.dev/k8s.io/klog) 参数。使用`-v`可以设置日志级别应用于大多数场景。 + +例如: + +```consol +helm list -v 6 +``` + +### Tiller停止安装且无法访问 + +Helm 发布之前可以从 获取。如["Announcing +get.helm.sh"](https://helm.sh/blog/get-helm-sh/)中所述,官方地址2019年6月已变更。 +[GitHub Container Registry](https://github.com/orgs/helm/packages/container/package/tiller) +可以获取所有旧的Tiller镜像。 + +如果你想从原来的存储位置下载Helm旧版本,你会发现找不到了: + +```console + + AccessDenied + Access denied. +
Anonymous caller does not have storage.objects.get access to the Google Cloud Storage object.
+
+``` + +[原有Tiller镜像地址](https://gcr.io/kubernetes-helm/tiller) 会在2021年8月开始删除镜像。我们已经增加了可用地址在 +[GitHub Container Registry](https://github.com/orgs/helm/packages/container/package/tiller)。 +比如下载v2.17.0,用 + +`https://get.helm.sh/helm-v2.17.0-linux-amd64.tar.gz` 替换 + +`https://storage.googleapis.com/kubernetes-helm/helm-v2.17.0-linux-amd64.tar.gz` + +使用Helm v2.17.0初始化: + +`helm init —upgrade` + +或者如果需要另一个版本,使用 --tiller-image 替换默认位置安装特定的Helm v2 版本: + +`helm init --tiller-image ghcr.io/helm/tiller:v2.16.9` + +**注意** Helm维护人员建议迁移到当前支持的Helm版本。Helm v2.17.0 是Helm 2的最终版本;Helm +v2自2020年11月起便不再支持,具体细节请查看[Helm 2 和 Charts Project 已不再支持](https://helm.sh/blog/helm-2-becomes-unsupported/)。 +自那以后,Helm已经被发现很多的CVE,这些漏洞已经在Helm v3修复,但不会再给Helm v2打补丁。现在查看 +[Helm当前已发布的建议列表](https://github.com/helm/helm/security/advisories?state=published)并计划 +[迁移到 Helm v3](https://helm.sh/docs/topics/v2_v3_migration/#helm)吧。 diff --git a/content/zh/docs/glossary/_index.md b/content/zh/docs/glossary/_index.md new file mode 100644 index 0000000000..0b817542cc --- /dev/null +++ b/content/zh/docs/glossary/_index.md @@ -0,0 +1,128 @@ +--- +title: "术语表" +description: "用于描述Helm体系结构的组件。" +weight: 9 +--- + +# 术语表 + +## Chart + +Helm包涵盖了将Kubernetes资源安装到Kubernetes集群所需要的足够多的信息。 + +Charts包含`Chart.yaml`文件和模板,默认值(`values.yaml`),以及相关依赖。 + +Charts开发设计了良好定义的目录结构,并且打包成了一种称为 _chart archive_ 文件格式。 + +## Chart包 + +Chart包(_chart archive_)是被tar和gzip压缩(并且可选签名)的chart. + +## Chart依赖 (子chart) + +Chart可以依赖于其他的chart。 依赖可能会以以下两种方式出现: + +- 软依赖: 如果另一个chart没有在集群中安装,chart可能会无法使用。Helm未对这个案例提供工具。 +这个案例中,依赖会被分别管理。 +- 硬依赖: 一个chart可以包含 (在它的`charts/`目录中) 另一个它所依赖的chart。这个案例中, +安装chart的同时会安装所有依赖。chart和它的依赖会作为一个集合进行管理。 + +当一个chart(通过`helm package`)打包时所有的依赖都会和它绑定。 + +## Chart版本 + +Chart版本根据 [语义化版本2.0 细则](https://semver.org) 发布。每个chart都需要版本号。 + +## Chart.yaml + +chart的信息说明被存储在一个特定文件`Chart.yaml`。每个chart都必须有这个文件。 + +## Helm (以及helm) + +Helm 是Kubernetes的包管理器。作为一个操作系统包管理器,使其很容易在操作系统中安装工具。 +Helm使得Kubernetes集群中安装应用和资源变得异常简单。 + +当 _Helm_ 是项目名称时, 命令行客户端也可以使用 `helm`。按照惯例,当指项目时,_Helm_ +使用大写。当指命令行时, _helm_ 使用小写。 + +## Helm配置文件 (XDG) + +Helm将配置文件存储在XDG目录中。`helm`第一次运行时这些目录会自动生成。 + +## Kube 配置 (KUBECONFIG) + +Helm客户端会通过使用 _Kube config_ 文件格式来理解Kubernetes集群。 +默认情况下,Helm会尝试在 `kubectl` 创建的 (`$HOME/.kube/config`) 目录中查找这些文件。 + +## 代码规范 (进行中) + +规范(_lint_) 一个chart是去验证其遵照Helm chart的标准规范和要求。 +Helm提供了工具来处理,尤其是`helm lint`命令。 + +## 来源 (来源文件) + +Helm chart可以由来源文件(_provenance file_)提供chart的出处及它所包含的内容。 + +来源文件是Helm安全故事的一部分。一个来源包含chart包文件的加密哈希值,Chart.yaml数据, +和一个签名块(一个OpenPGP "clearsign" 块)。当再加上一个钥匙链时,可以为chart用户提供 +以下能力: + +- 验证chart被可信第三方签名 +- 验证chart文件没有被篡改 +- 验证chart的元数据内容(`Chart.yaml`) +- 快速匹配chart的数据来源 + +来源文件有`.prov`扩展名,可以由chart仓库服务器或其他HTTP服务器提供。 + +## 发布版本 + +chart安装之后,Helm库会创建一个 _release_ 来跟踪这个安装。 + +单个chart可以在同一个集群中安装多次,并能创建多个不同的版本。例如,可以使用 `helm install` +命令以不同的版本安装三个PostgreSQL 数据库三次。 + +## 版本号 + +单个版本号可以被升级多次。通过连续技术来跟踪升级发布版本。在第一次`helm install`之后,一个版本 +会有 _release number_ 1,每一次版本升级或回滚,版本号都会升级。 + +## 回滚 + +每一次发布会更新chart或者配置。当生成发布历史后,一次发布也可以被 _rolled back_ 之前的发布版本号。 +回滚使用 `helm rollback` 命令实现。 + +重要的是, 每一次回滚版本会生成一个新的发布版本号。 + +| 操作 | 版本号 | +|------------|------------------------------------------------------| +| install | release 1 | +| upgrade | release 2 | +| upgrade | release 3 | +| rollback 1 | release 4 (但使用release 1的配置) | + +上面的列表阐明了发布版本号是怎样通过安装,升级和回滚递增的。 + +## Helm库 (或SDK) + +Helm库(或SDK)涉及到go代码,可以直接与Kubernetes API服务交互进行安装、升级、查询 +以及移除Kubernetes资源。可以被导入到项目中作为客户端库使用而不是用作CLI命令。 + +## 仓库 (Repo, Chart Repository) + +Helm图标chart可以被存储在专用的HTTP服务器上,称之为 _chart 仓库_(_repositories_,或者就叫 _repos_)。 + +chart仓库服务器就是一个简单的HTTP服务器,提供一个`index.yaml` 文件来描述一批chart, +并且提供每个chart的下载位置信息。(很多chart仓库同时提供chart和 `index.yaml`文件。) + +Helm客户端可以指向0个或多个chart仓库。默认没有配置仓库。Chart仓库可以随时使用`helm repo add`命令添加。 + +## Values (Values文件, values.yaml) + +Values 提供了一种使用您自己的信息覆盖模板默认值的方式。 + +Helm Chart是"参数化的", 这意味着chart开发者可以在安装时显式配置。比如说,chart可以暴露`username`字段, +允许为服务设置一个用户名。 + +这些可暴露的变量在Helm用语中称为 _values_。 + +Values可以在 `helm install`时和`helm upgrade`时设置,直接把它们传值进来,也可以使用`values.yaml`文件设置。 diff --git a/content/zh/docs/helm/_index.md b/content/zh/docs/helm/_index.md new file mode 100644 index 0000000000..b0fda2a1b9 --- /dev/null +++ b/content/zh/docs/helm/_index.md @@ -0,0 +1,10 @@ +--- +title: "Helm 命令行" +description: "helm CLI 命令行的全部文档内容。" +weight: 6 +slug: helm +--- + +# Helm 命令行 + +这里可以看到 Helm 命令行列表和使用帮助。 diff --git a/content/zh/docs/helm/helm.md b/content/zh/docs/helm/helm.md new file mode 100644 index 0000000000..6d23b2b473 --- /dev/null +++ b/content/zh/docs/helm/helm.md @@ -0,0 +1,108 @@ +--- +title: "Helm" +--- + +## helm + +针对Kubernetes的Helm包管理器。 + +### 简介 + +Kubernetes包管理器 + +Helm的一般操作: + +- helm search:   搜索chart +- helm pull:    下载chart到本地目录查看 +- helm install:   上传chart到Kubernetes +- helm list:     列出已发布的chart + +环境变量: +| 名称 | 描述 | +|------------------------------------|---------------------------------------------------------------------------------| +| $HELM_CACHE_HOME | 设置一个存储缓存文件的可选位置 | +| $HELM_CONFIG_HOME | 设置一个存储Helm配置的可选位置 | +| $HELM_DATA_HOME | 设置一个存储Helm数据的可选位置 | +| $HELM_DEBUG | 表示Helm是否在Debug模式系运行 | +| $HELM_DRIVER | 设置后台存储驱动,可选值包括:configmap, secret, memory, sql | +| $HELM_DRIVER_SQL_CONNECTION_STRING | 设置SQL存储驱动使用连接字符串 | +| $HELM_MAX_HISTORY | 设置发布历史记录的最大值 | +| $HELM_NAMESPACE | 设置用于helm操作的命名空间 | +| $HELM_NO_PLUGINS | 禁用插件,HELM_NO_PLUGINS=1 表示禁用插件 | +| $HELM_PLUGINS | 设置插件目录路径 | +| $HELM_REGISTRY_CONFIG | 设置注册配置文件的路径 | +| $HELM_REPOSITORY_CACHE | 设置仓库缓存目录路径 | +| $HELM_REPOSITORY_CONFIG | 设置仓库文件的路径 | +| $KUBECONFIG | 设置Kubernetes的可选配置文件(默认是"~/.kube/config") | +| $HELM_KUBEAPISERVER | 设置用于身份认证的Kubernetes API服务端 | +| $HELM_KUBECAFILE | 设置Kubernetes证书机构文件 | +| $HELM_KUBEASGROUPS | 使用逗号分隔的列表设置用于模拟的组 | +| $HELM_KUBEASUSER | 为操作设置要模拟的用户名 | +| $HELM_KUBECONTEXT | 设置kubeconfig上下文的名称 | +| $HELM_KUBETOKEN | 设置用于身份验证的不记名KubeToken | +| $HELM_KUBEINSECURE_SKIP_TLS_VERIFY | 设置 Kubernetes API 服务的证书验证是否跳过(不安全) | +| $HELM_KUBETLS_SERVER_NAME | 设置用于验证 Kubernetes API 服务器证书的服务器名称 | +| $HELM_BURST_LIMIT | 设置当 kubernetes 服务包含很大量CRD时的默认上限值(默认100, -1是不可用) | + +Helm 基于以下配置顺序存储缓存,配置和添加数据: + +- 如果设置了 HELM_*_HOME 环境变量,则使用该变量 +- 否则,在支持XDG基本目录规范的系统上,会使用XDG变量 +- 当没有设置其他位置时,将根据操作系统使用默认位置 + +默认情况下,默认目录取决于操作系统,默认值如下: + +| 操作系统 | 缓存路径 | 配置路径 | 数据路径 | +|------------------|---------------------------|--------------------------------|-------------------------| +| Linux | $HOME/.cache/helm | $HOME/.config/helm | $HOME/.local/share/helm | +| macOS | $HOME/Library/Caches/helm | $HOME/Library/Preferences/helm | $HOME/Library/helm | +| Windows | %TEMP%\helm | %APPDATA%\helm | %APPDATA%\helm | + +### 可选项 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + -h, --help help for helm + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 另请参阅 + +- [helm completion](helm_completion.md) - 为指定的shell生成自动补全脚本 +- [helm create](helm_create.md) - 使用给定的名称创建chart +- [helm dependency](helm_dependency.md) - 管理chart依赖 +- [helm env](helm_env.md) - helm客户端环境信息 +- [helm get](helm_get.md) - 下载命名版本的扩展信息 +- [helm history](helm_history.md) - 检索发布历史 +- [helm install](helm_install.md) - 安装chart +- [helm lint](helm_lint.md) - 验证chart是否存在问题 +- [helm list](helm_list.md) - 列举发布版本 +- [helm package](helm_package.md) - 将chart目录打包 +- [helm plugin](helm_plugin.md) - 安装、列举或卸载Helm插件 +- [helm pull](helm_pull.md) - 从仓库下载chart并(可选)在本地目录中打开 +- [helm push](helm_push.md) - 推送chart到远程 +- [helm registry](helm_registry.md) - 从注册表登录或登出 +- [helm repo](helm_repo.md) - 添加、列出、删除、更新和索引chart仓库 +- [helm rollback](helm_rollback.md) - 回滚发布到上一个版本 +- [helm search](helm_search.md) - helm中搜索关键字 +- [helm show](helm_show.md) - 显示chart信息 +- [helm status](helm_status.md) - 显示命名版本的状态 +- [helm template](helm_template.md) - 本地渲染模板 +- [helm test](helm_test.md) - 执行发布的测试 +- [helm uninstall](helm_uninstall.md) - 卸载版本 +- [helm upgrade](helm_upgrade.md) - 升级版本 +- [helm verify](helm_verify.md) - 验证给定路径的chart已经被签名且是合法的 +- [helm version](helm_version.md) - 打印客户端版本信息 diff --git a/content/zh/docs/helm/helm_completion.md b/content/zh/docs/helm/helm_completion.md new file mode 100644 index 0000000000..fff7e07f2f --- /dev/null +++ b/content/zh/docs/helm/helm_completion.md @@ -0,0 +1,45 @@ +--- +title: "Helm 补全" +--- + +## helm completion + +为指定的shell生成自动补全脚本 + +### 简介 + +为Helm生成针对于指定shell的自动补全脚本 + +### 可选项 + +```shell + -h, --help help for completion +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +- [helm](helm.md) - 针对Kubernetes的Helm包管理器 +- [helm completion bash](helm_completion_bash.md) - 为bash生成自动补全脚本 +- [helm completion fish](helm_completion_fish.md) - 为fish生成自动补全脚本 +- [helm completion powershell](helm_completion_powershell.md) - 为powershell生成自动补全脚本 +- [helm completion zsh](helm_completion_zsh.md) - 为zsh生成自动补全脚本 diff --git a/content/zh/docs/helm/helm_completion_bash.md b/content/zh/docs/helm/helm_completion_bash.md new file mode 100644 index 0000000000..6808da5fe3 --- /dev/null +++ b/content/zh/docs/helm/helm_completion_bash.md @@ -0,0 +1,61 @@ +--- +title: "Helm补全 - bash" +--- + +## helm completion bash + +为bash生成自动补全脚本 + +### 简介 + +为Helm生成针对于bash shell的自动补全脚本。 + +在当前shell会话中加载自动补全: + + source <(helm completion bash) + +为每个新的会话加载自动补全,执行一次: +- Linux: + + helm completion bash > /etc/bash_completion.d/helm + +- MacOS: + + helm completion bash > /usr/local/etc/bash_completion.d/helm + + +```shell +helm completion bash [flags] +``` + +### 可选项 + +```shell + -h, --help help for bash + --no-descriptions disable completion descriptions +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +- [helm completion](helm_completion.md) - 为指定的shell生成自动补全脚本 diff --git a/content/zh/docs/helm/helm_completion_fish.md b/content/zh/docs/helm/helm_completion_fish.md new file mode 100644 index 0000000000..60050c7464 --- /dev/null +++ b/content/zh/docs/helm/helm_completion_fish.md @@ -0,0 +1,56 @@ +--- +title: "Helm补全 - fish" +--- + +## helm completion fish + +为fish生成自动补全脚本 + +### 简介 + +为Helm生成针对于fish shell的自动补全脚本。 + +在当前shell会话中加载自动补全: + + helm completion fish | source + +为每个新的会话加载自动补全,执行一次: + + helm completion fish > ~/.config/fish/completions/helm.fish + +您需要启动一个新的shell使其生效 + +```shell +helm completion fish [flags] +``` + +### 可选项 + +```shell + -h, --help help for fish + --no-descriptions disable completion descriptions +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm completion](helm_completion.md) - 为指定的shell生成自动补全脚本 diff --git a/content/zh/docs/helm/helm_completion_powershell.md b/content/zh/docs/helm/helm_completion_powershell.md new file mode 100644 index 0000000000..1f59f9ffe9 --- /dev/null +++ b/content/zh/docs/helm/helm_completion_powershell.md @@ -0,0 +1,53 @@ +--- +title: "Helm补全 - Powershell" +--- + +## helm completion powershell + +为powershell生成自动补全脚本 + +### 简介 + +为powershell生成自动补全脚本。 + +在当前shell会话中加载补全项: +PS C:\> helm completion powershell | Out-String | Invoke-Expression + +在每个新会话中加载补全项,将上述命令的输出添加到你的powershell profile中。 + +```shell +helm completion powershell [flags] +``` + +### 可选项 + +```shell + -h, --help help for powershell + --no-descriptions disable completion descriptions +``` + +### 从父命令继承的选项 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参照 + +* [helm completion](helm_completion.md) - 为指定的shell生成自动补全脚本 + +###### Auto generated by spf13/cobra on 17-Sep-2021 diff --git a/content/zh/docs/helm/helm_completion_zsh.md b/content/zh/docs/helm/helm_completion_zsh.md new file mode 100644 index 0000000000..08f91f1172 --- /dev/null +++ b/content/zh/docs/helm/helm_completion_zsh.md @@ -0,0 +1,54 @@ +--- +title: "Helm补全 - zsh" +--- + +## helm completion zsh + +为zsh生成自动补全脚本 + +### 简介 + +为Helm生成针对于zsh shell的自动补全脚本。 + +在当前shell会话中加载自动补全: + + source <(helm completion zsh) + +为每个新的会话加载自动补全,执行一次: + + helm completion zsh > "${fpath[1]}/_helm" + +```shell +helm completion zsh [flags] +``` + +### 可选项 + +```shell + -h, --help help for zsh + --no-descriptions disable completion descriptions +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +- [helm completion](helm_completion.md) - 为指定的shell生成自动补全脚本 diff --git a/content/zh/docs/helm/helm_create.md b/content/zh/docs/helm/helm_create.md new file mode 100644 index 0000000000..77fbfcb743 --- /dev/null +++ b/content/zh/docs/helm/helm_create.md @@ -0,0 +1,60 @@ +--- +title: "Helm创建" +--- + +## helm create + +使用给定名称创建新的chart + +### 简介 + +该命令创建chart目录和chart用到的公共文件目录 + +比如'helm create foo'会创建一个目录结构看起来像这样: + +```shell +foo/ +├── .helmignore # Contains patterns to ignore when packaging Helm charts. +├── Chart.yaml # Information about your chart +├── values.yaml # The default values for your templates +├── charts/ # Charts that this chart depends on +└── templates/ # The template files + └── tests/ # The test files +``` + +'helm create'使用一个目录作为参数。如果给定目录路径不存在,Helm会自动创建。如果给定目录存在且非空,冲突文件会被覆盖,其他文件会被保留。 + +```shell +helm create NAME [flags] +``` + +### 可选项 + +```shell + -h, --help help for create + -p, --starter string the name or absolute path to Helm starter scaffold +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm](helm.md) - 针对Kubernetes的Helm包管理器 diff --git a/content/zh/docs/helm/helm_delete.md b/content/zh/docs/helm/helm_delete.md new file mode 100644 index 0000000000..95c8e5a363 --- /dev/null +++ b/content/zh/docs/helm/helm_delete.md @@ -0,0 +1,7 @@ +--- +section: 弃用 +--- + +## helm delete + +该命令被重命名。 请参考[helm uninstall](helm_uninstall). diff --git a/content/zh/docs/helm/helm_dependency.md b/content/zh/docs/helm/helm_dependency.md new file mode 100644 index 0000000000..8b4f610a10 --- /dev/null +++ b/content/zh/docs/helm/helm_dependency.md @@ -0,0 +1,80 @@ +--- +title: "Helm 依赖" +--- + +## helm dependency + +管理chart依赖 + +### 简介 + +管理chart依赖 + +Helm chart将依赖存储在'charts/'。对于chart开发者,管理依赖比声明了所有依赖的'Chart.yaml'文件更容易。 + +依赖命令对该文件进行操作,使得存储在'charts/'目录的需要的依赖和实际依赖之间同步变得很容易。 + +比如Chart.yaml声明了两个依赖: + +```yaml +# Chart.yaml +dependencies: +- name: nginx + version: "1.2.3" + repository: "https://example.com/charts" +- name: memcached + version: "3.2.1" + repository: "https://another.example.com/charts" +``` + +'name'是chart名称,必须匹配'Chart.yaml'文件中名称。 + +'version'字段应该包含一个语义化的版本或版本范围。 + +'repository'的URL应该指向Chart仓库。Helm希望通过附加'/index.yaml'到URL,应该能检索chart库索引。 +注意:'repository'不能是别名。别名必须以'alias:'或'@'开头。 + +从2.2.0开始,仓库可以被定义为本地存储的依赖chart的目录路径。路径应该以"file://"前缀开头,比如: + +```yaml +# Chart.yaml +dependencies: +- name: nginx + version: "1.2.3" + repository: "file://../dependency_chart/nginx" +``` + +如果在本地检索依赖chart,不需要使用"helm add repo"将仓库加入到helm。该示例中也支持版本匹配。 + +### 可选项 + +```shell + -h, --help help for dependency +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm](helm.md) - 针对Kubernetes的Helm包管理器 +* [helm dependency build](helm_dependency_build.md) - 基于Chart.lock文件重新构建charts/目录 +* [helm dependency list](helm_dependency_list.md) - 列出给定chart的依赖 +* [helm dependency update](helm_dependency_update.md) - 基于Chart.yaml内容升级charts/ diff --git a/content/zh/docs/helm/helm_dependency_build.md b/content/zh/docs/helm/helm_dependency_build.md new file mode 100644 index 0000000000..db72403b42 --- /dev/null +++ b/content/zh/docs/helm/helm_dependency_build.md @@ -0,0 +1,52 @@ +--- +title: "Helm依赖构建" +--- + +## helm dependency build + +基于Chart.lock文件重新构建charts/目录 + +### 简介 + +从Chart.lock构建输出到charts/目录 + +该构建是用来将chart的依赖项重建为锁定文件中的指定状态。就像'helm dependency update'一样并不会调整依赖状态。 + +如果没找到锁定文件,'helm dependency build'映射到'helm dependency update' + +```shell +helm dependency build CHART [flags] +``` + +### 可选项 + +```shell + -h, --help help for build + --keyring string keyring containing public keys (default "~/.gnupg/pubring.gpg") + --skip-refresh do not refresh the local repository cache + --verify verify the packages against signatures +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm dependency](helm_dependency.md) - 管理chart依赖 diff --git a/content/zh/docs/helm/helm_dependency_list.md b/content/zh/docs/helm/helm_dependency_list.md new file mode 100644 index 0000000000..aa88df3f52 --- /dev/null +++ b/content/zh/docs/helm/helm_dependency_list.md @@ -0,0 +1,50 @@ +--- +title: "Helm 依赖列表" +--- + +## helm dependency list + +列举指定chart的依赖 + +### 简介 + +列举所有的chart中声明的依赖 + +该命令可以将chart包或chart目录作为输入,不会修改chart的内容。 + +如果chart不能加载会产生错误。 + +```shell +helm dependency list CHART [flags] +``` + +### 可选项 + +```shell + -h, --help help for list + --max-col-width uint 输出结果的最大宽度(默认80) +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +- [helm dependency](helm_dependency.md) - 管理chart依赖 diff --git a/content/zh/docs/helm/helm_dependency_update.md b/content/zh/docs/helm/helm_dependency_update.md new file mode 100644 index 0000000000..abe979c843 --- /dev/null +++ b/content/zh/docs/helm/helm_dependency_update.md @@ -0,0 +1,55 @@ +--- +title: "Helm依赖升级" +--- + +## helm dependency update + +基于Chart.yaml内容升级charts/ + +### 简介 + +更新磁盘上的依赖为Chart.yaml指定内容。 + +该命令验证存储在'charts/'目录中的'Chart.yaml'文件描述的所需chart以及所需版本。 +它会拉取满足依赖的最新chart并清理旧依赖。 + +成功更新后,会生成一个锁定文件用来重新构建精确版本的依赖。 + +不需要在'Chart.yaml'中表示依赖。 因此,更新命令不会删除chart,除非是在Chart.yaml文件中的错误版本。 + +```shell +helm dependency update CHART [flags] +``` + +### 可选项 + +```shell + -h, --help help for update + --keyring string keyring containing public keys (default "~/.gnupg/pubring.gpg") + --skip-refresh do not refresh the local repository cache + --verify verify the packages against signatures +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +- [helm dependency](helm_dependency.md) - 管理chart依赖 diff --git a/content/zh/docs/helm/helm_env.md b/content/zh/docs/helm/helm_env.md new file mode 100644 index 0000000000..4ec182cd3b --- /dev/null +++ b/content/zh/docs/helm/helm_env.md @@ -0,0 +1,45 @@ +--- +title: "Helm 变量" +--- + +## helm env + +helm 客户端环境信息 + +### 简介 + +Env 打印所有Helm使用的环境信息 + +```shell +helm env [flags] +``` + +### 可选项 + +```shell + -h, --help help for env +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm](helm.md) - 针对Kubernetes的Helm包管理器 diff --git a/content/zh/docs/helm/helm_get.md b/content/zh/docs/helm/helm_get.md new file mode 100644 index 0000000000..991da77b71 --- /dev/null +++ b/content/zh/docs/helm/helm_get.md @@ -0,0 +1,51 @@ +--- +title: "Helm 获取扩展" +--- + +## helm get + +下载发布的扩展信息 + +### 简介 + +该命令有多个子命令组成,用来获取发布版本的扩展信息,包括: + +- 生成版本的值 +- 生成的清单文件 +- 发布的chart提供的注释 +- 与版本关联的钩子 + +### 可选项 + +```shell + -h, --help help for get +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +- [helm](helm.md) - 针对Kubernetes的Helm包管理器 +- [helm get all](helm_get_all.md) - 下载命名版本的所有信息 +- [helm get hooks](helm_get_hooks.md) - 下载命名版本的所有钩子 +- [helm get manifest](helm_get_manifest.md) - 下载命名版本的清单 +- [helm get notes](helm_get_notes.md) - 下载命名版本的注释 +- [helm get values](helm_get_values.md) - 下载命名版本的values文件 diff --git a/content/zh/docs/helm/helm_get_all.md b/content/zh/docs/helm/helm_get_all.md new file mode 100644 index 0000000000..bad6eb45c8 --- /dev/null +++ b/content/zh/docs/helm/helm_get_all.md @@ -0,0 +1,47 @@ +--- +title: "Helm 获取所有" +--- + +## helm get all + +下载命名版本的所有信息 + +### 简介 + +该命令打印一个具有可读性的信息集合,包括注释,钩子,提供的values,以及给定版本生成的清单文件。 + +```shell +helm get all RELEASE_NAME [flags] +``` + +### 可选项 + +```shell + -h, --help help for all + --revision int get the named release with revision + --template string go template for formatting the output, eg: {{.Release.Name}} +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm get](helm_get.md) - 下载命名版本的扩展信息 diff --git a/content/zh/docs/helm/helm_get_hooks.md b/content/zh/docs/helm/helm_get_hooks.md new file mode 100644 index 0000000000..c3f57991d1 --- /dev/null +++ b/content/zh/docs/helm/helm_get_hooks.md @@ -0,0 +1,48 @@ +--- +title: "Helm 获取钩子" +--- + +## helm get hooks + +下载命名版本的所有钩子 + +### 简介 + +该命令下载指定版本的钩子 + +钩子被格式化为YAML格式并以YAML的'---\n'分隔符分隔 + +```shell +helm get hooks RELEASE_NAME [flags] +``` + +### 可选项 + +```shell + -h, --help help for hooks + --revision int get the named release with revision +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm get](helm_get.md) - 下载命名版本的扩展信息 diff --git a/content/zh/docs/helm/helm_get_manifest.md b/content/zh/docs/helm/helm_get_manifest.md new file mode 100644 index 0000000000..1781be964c --- /dev/null +++ b/content/zh/docs/helm/helm_get_manifest.md @@ -0,0 +1,48 @@ +--- +title: "Helm 获取清单" +--- + +## helm get manifest + +下载命名版本的清单 + +### 简介 + +该命令用来获取指定版本的清单文件 + +清单是由该版本的chart生成的Kubernetes资源的YAML编码表示。 + +```shell +helm get manifest RELEASE_NAME [flags] +``` + +### 可选项 + +```shell + -h, --help help for manifest + --revision int get the named release with revision +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm get](helm_get.md) - 下载命名版本的扩展信息 diff --git a/content/zh/docs/helm/helm_get_notes.md b/content/zh/docs/helm/helm_get_notes.md new file mode 100644 index 0000000000..0877743479 --- /dev/null +++ b/content/zh/docs/helm/helm_get_notes.md @@ -0,0 +1,46 @@ +--- +title: "Helm 获取注释" +--- + +## helm get notes + +下载命名版本的注释 + +### 简介 + +该命令显示了由指定版本chart提供的注释 + +```shell +helm get notes RELEASE_NAME [flags] +``` + +### 可选项 + +```shell + -h, --help help for notes + --revision int get the named release with revision +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm get](helm_get.md) - 下载命名版本的扩展信息 diff --git a/content/zh/docs/helm/helm_get_values.md b/content/zh/docs/helm/helm_get_values.md new file mode 100644 index 0000000000..57de050ab9 --- /dev/null +++ b/content/zh/docs/helm/helm_get_values.md @@ -0,0 +1,48 @@ +--- +title: "Helm获取Values" +--- + +## helm get values + +下载命名版本的values文件 + +### 简介 + +该命令下载给定版本的values文件 + +```shell +helm get values RELEASE_NAME [flags] +``` + +### 可选项 + +```shell + -a, --all dump all (computed) values + -h, --help help for values + -o, --output format prints the output in the specified format. Allowed values: table, json, yaml (default table) + --revision int get the named release with revision +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm get](helm_get.md) - 下载命名版本的扩展信息 diff --git a/content/zh/docs/helm/helm_history.md b/content/zh/docs/helm/helm_history.md new file mode 100644 index 0000000000..c1877618d2 --- /dev/null +++ b/content/zh/docs/helm/helm_history.md @@ -0,0 +1,60 @@ +--- +title: "Helm 历史" +--- + +## helm history + +检索发布历史 + +### 简介 + +打印给定版本的历史修订。 + +默认会返回最大的256个历史版本。设置'--max'配置返回历史列表的最大长度。 + +历史发布集合会被打印成格式化的表格,例如: + +```shell +$ helm history angry-bird +REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION +1 Mon Oct 3 10:15:13 2016 superseded alpine-0.1.0 1.0 Initial install +2 Mon Oct 3 10:15:13 2016 superseded alpine-0.1.0 1.0 Upgraded successfully +3 Mon Oct 3 10:15:13 2016 superseded alpine-0.1.0 1.0 Rolled back to 2 +4 Mon Oct 3 10:15:13 2016 deployed alpine-0.1.0 1.0 Upgraded successfully +``` + +```shell +helm history RELEASE_NAME [flags] +``` + +### 可选项 + +```shell + -h, --help help for history + --max int maximum number of revision to include in history (default 256) + -o, --output format prints the output in the specified format. Allowed values: table, json, yaml (default table) +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm](helm.md) - 针对Kubernetes的Helm包管理器 diff --git a/content/zh/docs/helm/helm_init.md b/content/zh/docs/helm/helm_init.md new file mode 100644 index 0000000000..a5e59b259c --- /dev/null +++ b/content/zh/docs/helm/helm_init.md @@ -0,0 +1,10 @@ +--- +section: 弃用 +--- + +## helm init + +该命令不会出现在Helm 3中,遵循[移除的Tiller](https://helm.sh/zh/docs/faq/#移除了Tiller)。不再需要为使用helm而安装Tiller。 + +如果您在使用Helm 2, 前往[v2.helm.sh](https://v2.helm.sh/docs/helm/#helm-init) +查看[Helm初始化文档](https://v2.helm.sh/docs/helm/#helm-init)。 diff --git a/content/zh/docs/helm/helm_inspect.md b/content/zh/docs/helm/helm_inspect.md new file mode 100644 index 0000000000..c3def19081 --- /dev/null +++ b/content/zh/docs/helm/helm_inspect.md @@ -0,0 +1,7 @@ +--- +section: 弃用 +--- + +## helm inspect + +该命令已被重命名,请参考[helm show](helm_show.md)。 diff --git a/content/zh/docs/helm/helm_install.md b/content/zh/docs/helm/helm_install.md new file mode 100644 index 0000000000..209086146f --- /dev/null +++ b/content/zh/docs/helm/helm_install.md @@ -0,0 +1,161 @@ +--- +title: "Helm 安装" +--- + +## helm install + +安装chart + +### 简介 + +该命令用于安装chart包。 + +安装参数必须是chart的引用,一个打包后的chart路径,未打包的chart目录或者是一个URL。 + +要重写chart中的值,使用'--values'参数传递一个文件或者使用'--set'参数在命令行传递配置,强制使用字符串要用'--set-string'。 +当值本身对于命令行太长或者是动态生成的时候,可以使用 '--set-file' 设置独立的值。也可以在命令行使用'--set-json'参数设置json值(scalars/objects/arrays)。 + +```shell +$ helm install -f myvalues.yaml myredis ./redis +``` + +或者 + +```shell +$ helm install --set name=prod myredis ./redis +``` + +或者 + +```shell +$ helm install --set-string long_int=1234567890 myredis ./redis +``` + +或者 + +```shell +$ helm install --set-file my_script=dothings.sh myredis ./redis +``` + +或者 + +```shell +$ helm install --set-json 'master.sidecars=[{"name":"sidecar","image":"myImage","imagePullPolicy":"Always",ports":[{"name":"portname","containerPort":1234}]}]' myredis ./redis +``` + +你可以多次指定'--values'/'-f'参数。最右侧指定的文件优先级最高。比如,如果两个文件myvalues.yaml和override.yaml +都包含名为'Test'的可以,override.yaml中的值优先: + +```shell +$ helm install -f myvalues.yaml -f override.yaml myredis ./redis +``` + +可以指定'--set'参数多次,最右边的参数优先级最高,比如,'bar'和'newbar'都设置了一个名为'foo'的可以,'newbar'的值优先: + +```shell + $ helm install --set foo=bar --set foo=newbar myredis ./redis +``` + +类似地,下面的示例中'foo'被设置成了'["four"]': + +```shell + $ helm install --set-json='foo=["one", "two", "three"]' --set-json='foo=["four"]' myredis ./redis +``` + +下面的示例中,'foo'被设置成了'{"key1":"value1","key2":"bar"}': + +```shell + $ helm install --set-json='foo={"key1":"value1","key2":"value2"}' --set-json='foo.key2="bar"' myredis ./redis +``` + +为了检测生成的清单,但并不安装到chart,可以将'--debug'和'--dry-run'组合使用。 + +如果设置了--verify,chart**必须**有出处文件,且出处文件**必须**传递所有的验证步骤。 + +有六种不同的方式来标识需要安装的chart: + +1. 通过chart引用: helm install mymaria example/mariadb +2. 通过chart包: helm install mynginx ./nginx-1.2.3.tgz +3. 通过未打包chart目录的路径: helm install mynginx ./nginx +4. 通过URL绝对路径: helm install mynginx https://example.com/charts/nginx-1.2.3.tgz +5. 通过chart引用和仓库url: helm install --repo https://example.com/charts/ mynginx nginx +6. 通过OCI注册中心: helm install mynginx --version 1.2.3 oci://example.com/charts/nginx + +CHART引用 + +chart引用是在chart仓库中引用chart的一种方便方式。 + +当你用仓库前缀('example/mariadb')引用chart时,Helm会在本地配置查找名为 'example' 的chart仓库, +然后会在仓库中查找名为'mariadb'的仓库,然后会安装这个chart最新的稳定版本,除非指定了'--devel'参数且包含了开发版本(alpha, +beta,和候选版本),或者使用'--version'参数提供一个版本号。 + +要查看仓库列表,使用'helm repo list'。要在仓库中搜索chart,使用'helm search'。 + +```shell +helm install [NAME] [CHART] [flags] +``` + +### 可选项 + +```shell + --atomic if set, the installation process deletes the installation on failure. The --wait flag will be set automatically if --atomic is used + --ca-file string verify certificates of HTTPS-enabled servers using this CA bundle + --cert-file string identify HTTPS client using this SSL certificate file + --create-namespace create the release namespace if not present + --dependency-update update dependencies if they are missing before installing the chart + --description string add a custom description + --devel use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored + --disable-openapi-validation if set, the installation process will not validate rendered templates against the Kubernetes OpenAPI Schema + --dry-run simulate an install + --enable-dns enable DNS lookups when rendering templates + --force force resource updates through a replacement strategy + -g, --generate-name generate the name (and omit the NAME parameter) + -h, --help help for install + --insecure-skip-tls-verify skip tls certificate checks for the chart download + --key-file string identify HTTPS client using this SSL key file + --keyring string location of public keys used for verification (default "~/.gnupg/pubring.gpg") + --name-template string specify template used to name the release + --no-hooks prevent hooks from running during install + -o, --output format prints the output in the specified format. Allowed values: table, json, yaml (default table) + --pass-credentials pass credentials to all domains + --password string chart repository password where to locate the requested chart + --post-renderer postrenderer the path to an executable to be used for post rendering. If it exists in $PATH, the binary will be used, otherwise it will try to look for the executable at the given path (default exec) + --render-subchart-notes if set, render subchart notes along with the parent + --replace re-use the given name, only if that name is a deleted release which remains in the history. This is unsafe in production + --repo string chart repository url where to locate the requested chart + --set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) + --set-file stringArray set values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2) + --set-json stringArray set JSON values on the command line (can specify multiple or separate values with commas: key1=jsonval1,key2=jsonval2) + --set-string stringArray set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) + --skip-crds if set, no CRDs will be installed. By default, CRDs are installed if not already present + --timeout duration time to wait for any individual Kubernetes operation (like Jobs for hooks) (default 5m0s) + --username string chart repository username where to locate the requested chart + -f, --values strings specify values in a YAML file or a URL (can specify multiple) + --verify verify the package before using it + --version string specify a version constraint for the chart version to use. This constraint can be a specific tag (e.g. 1.1.1) or it may reference a valid range (e.g. ^2.0.0). If this is not specified, the latest version is used + --wait if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment, StatefulSet, or ReplicaSet are in a ready state before marking the release as successful. It will wait for as long as --timeout +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm](helm.md) - 针对Kubernetes的Helm包管理器 diff --git a/content/zh/docs/helm/helm_lint.md b/content/zh/docs/helm/helm_lint.md new file mode 100644 index 0000000000..22b8fb3798 --- /dev/null +++ b/content/zh/docs/helm/helm_lint.md @@ -0,0 +1,54 @@ +--- +title: "Helm 验证" +--- + +## helm lint + +验证chart是否存在问题 + +### 简介 + +该命令使用一个chart路径并运行一系列的测试来验证chart的格式是否正确。 + +如果遇到引起chart安装失败的情况,会触发[ERROR]信息,如果遇到违反惯例或建议的问题,会触发[WARNING]。 + +```shell +helm lint PATH [flags] +``` + +### 可选项 + +```shell + -h, --help help for lint + --set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) + --set-file stringArray set values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2) + --set-json stringArray set JSON values on the command line (can specify multiple or separate values with commas: key1=jsonval1,key2=jsonval2) + --set-string stringArray set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) + --strict fail on lint warnings + -f, --values strings specify values in a YAML file or a URL (can specify multiple) + --with-subcharts lint dependent charts +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm](helm.md) - 针对Kubernetes的Helm包管理器 diff --git a/content/zh/docs/helm/helm_list.md b/content/zh/docs/helm/helm_list.md new file mode 100644 index 0000000000..a6781ecdd5 --- /dev/null +++ b/content/zh/docs/helm/helm_list.md @@ -0,0 +1,81 @@ +--- +title: "Helm 列表" +--- + +## helm list + +列举发布版本 + +### 简介 + +该命令会列举出指定命名空间的所有发布版本,(如果没有指定命名空间,会使用当前命名空间)。 + +默认情况下,只会列举出部署的或者失败的发布,像'--uninstalled'或者'--all'会修改默认行为。这些参数可以组合使用:'--uninstalled +--failed'。 + +默认情况下,列表按字母排序。使用'-d'参数按照日期排序。 + +如果使用--filter参数,会作为一个过滤器。过滤器是应用于发布列表的正则表达式(兼容Perl)。只有过滤器匹配的才会返回。 + +```shell +$ helm list --filter 'ara[a-z]+' +NAME UPDATED CHART +maudlin-arachnid 2020-06-18 14:17:46.125134977 +0000 UTC alpine-0.1.0 +``` + +如果未找到结果,'helm list'会退出,但是没有输出(或者使用'-q',只返回头部)。 + +默认情况下,最多返回256项,使用'--max'限制数量,'--max'设置为0不会返回所有结果,而是返回服务器默认值,可能要比256更多。 +同时使用'--max'和'--offset'参数可以翻页显示。 + +```shell +helm list [flags] +``` + +### 可选项 + +```shell + -a, --all show all releases without any filter applied + -A, --all-namespaces list releases across all namespaces + -d, --date sort by release date + --deployed show deployed releases. If no other is specified, this will be automatically enabled + --failed show failed releases + -f, --filter string a regular expression (Perl compatible). Any releases that match the expression will be included in the results + -h, --help help for list + -m, --max int maximum number of releases to fetch (default 256) + --no-headers don't print headers when using the default output format + --offset int next release index in the list, used to offset from start value + -o, --output format prints the output in the specified format. Allowed values: table, json, yaml (default table) + --pending show pending releases + -r, --reverse reverse the sort order + -l, --selector string Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2). Works only for secret(default) and configmap storage backends. + -q, --short output short (quiet) listing format + --superseded show superseded releases + --time-format string format time using golang time formatter. Example: --time-format "2006-01-02 15:04:05Z0700" + --uninstalled show uninstalled releases (if 'helm uninstall --keep-history' was used) + --uninstalling show releases that are currently being uninstalled +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm](helm.md) - 针对Kubernetes的Helm包管理器 diff --git a/content/zh/docs/helm/helm_package.md b/content/zh/docs/helm/helm_package.md new file mode 100644 index 0000000000..8eb6dc15b9 --- /dev/null +++ b/content/zh/docs/helm/helm_package.md @@ -0,0 +1,61 @@ +--- +title: "Helm 包" +--- + +## helm package + +将chart目录打包到chart归档中 + +### 简介 + +该命令将chart打包成一个chart版本包文件。如果给定路径,就会在该路径中查找chart(必须包含Chart.yaml文件)然后将目录打包。 + +chart版本包会用于Helm包仓库。 + +要签名一个chart,使用'--sign'参数,在大多数场景中,也要提供'--keyring path/to/secret/keys'和'--key keyname'。 + + $ helm package --sign ./mychart --key mykey --keyring ~/.gnupg/secring.gpg + +如果'--keyring'未指定,除非配置了其他方式,不然Helm通常会指定公共秘钥环。 + +```shell +helm package [CHART_PATH] [...] [flags] +``` + +### 可选项 + +```shell + --app-version string set the appVersion on the chart to this version + -u, --dependency-update update dependencies from "Chart.yaml" to dir "charts/" before packaging + -d, --destination string location to write the chart. (default ".") + -h, --help help for package + --key string name of the key to use when signing. Used if --sign is true + --keyring string location of a public keyring (default "~/.gnupg/pubring.gpg") + --passphrase-file string location of a file which contains the passphrase for the signing key. Use "-" in order to read from stdin. + --sign use a PGP private key to sign this package + --version string set the version on the chart to this semver version +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm](helm.md) - 针对Kubernetes的Helm包管理器 diff --git a/content/zh/docs/helm/helm_plugin.md b/content/zh/docs/helm/helm_plugin.md new file mode 100644 index 0000000000..bddeb5f166 --- /dev/null +++ b/content/zh/docs/helm/helm_plugin.md @@ -0,0 +1,45 @@ +--- +title: "Helm 插件" +--- + +## helm plugin + +安装、列举或卸载Helm插件 + +### 简介 + +管理客户端插件。 + +### 可选项 + +```shell + -h, --help help for plugin +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +- [helm](helm.md) - 针对Kubernetes的Helm包管理器 +- [helm plugin install](helm_plugin_install.md) - 安装一个或多个Helm插件 +- [helm plugin list](helm_plugin_list.md) - 列举已安装的Helm插件 +- [helm plugin uninstall](helm_plugin_uninstall.md) - 卸载一个或多个Helm插件 +- [helm plugin update](helm_plugin_update.md) - 升级一个或多个Helm插件 diff --git a/content/zh/docs/helm/helm_plugin_install.md b/content/zh/docs/helm/helm_plugin_install.md new file mode 100644 index 0000000000..17d72b6e03 --- /dev/null +++ b/content/zh/docs/helm/helm_plugin_install.md @@ -0,0 +1,46 @@ +--- +title: "Helm 插件安装" +--- + +## helm plugin install + +安装一个或多个Helm插件 + +### 简介 + +该命令允许您通过VCS仓库url或者本地路径安装插件。 + +```shell +helm plugin install [options] ... [flags] +``` + +### 可选项 + +```shell + -h, --help help for install + --version string specify a version constraint. If this is not specified, the latest version is installed +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm plugin](helm_plugin.md) - 安装、列举或卸载Helm插件 diff --git a/content/zh/docs/helm/helm_plugin_list.md b/content/zh/docs/helm/helm_plugin_list.md new file mode 100644 index 0000000000..ab3c158c39 --- /dev/null +++ b/content/zh/docs/helm/helm_plugin_list.md @@ -0,0 +1,41 @@ +--- +title: "Helm 插件列表" +--- + +## helm plugin list + +列举已安装的Helm插件 + +```shell +helm plugin list [flags] +``` + +### 可选项 + +```shell + -h, --help help for list +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm plugin](helm_plugin.md) - 安装、列举或卸载Helm插件 diff --git a/content/zh/docs/helm/helm_plugin_uninstall.md b/content/zh/docs/helm/helm_plugin_uninstall.md new file mode 100644 index 0000000000..17a5562eb8 --- /dev/null +++ b/content/zh/docs/helm/helm_plugin_uninstall.md @@ -0,0 +1,41 @@ +--- +title: "Helm 插件卸载" +--- + +## helm plugin uninstall + +卸载一个或多个Helm插件 + +```shell +helm plugin uninstall ... [flags] +``` + +### 可选项 + +```shell + -h, --help help for uninstall +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm plugin](helm_plugin.md) - 安装、列举或卸载Helm插件 diff --git a/content/zh/docs/helm/helm_plugin_update.md b/content/zh/docs/helm/helm_plugin_update.md new file mode 100644 index 0000000000..5d72767a40 --- /dev/null +++ b/content/zh/docs/helm/helm_plugin_update.md @@ -0,0 +1,41 @@ +--- +title: "Helm 插件升级" +--- + +## helm plugin update + +升级一个或多个Helm插件 + +```shell +helm plugin update ... [flags] +``` + +### 可选项 + +```shell + -h, --help help for update +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm plugin](helm_plugin.md) - 安装、列举或卸载Helm插件 diff --git a/content/zh/docs/helm/helm_pull.md b/content/zh/docs/helm/helm_pull.md new file mode 100644 index 0000000000..4f18777cd9 --- /dev/null +++ b/content/zh/docs/helm/helm_pull.md @@ -0,0 +1,67 @@ +--- +title: "Helm 拉取" +--- + +## helm pull + +从仓库下载并(可选)在本地目录解压 + +### 简介 + +从包仓库中检索包并下载到本地。 + +对于要获取检查,修改或重新打包的包很有用,还可以用于在不安装chart的情况下对chart进行加密验证。 + +下载chart之后有解压的选项,会为chart创建一个目录并解压到这个目录中。 + +如果指定了--verify参数,请求的chart必须有出处文件,且必须通过验证。任意部分的失败都会导致错误,且chart不会在本地保存。 + +```shell +helm pull [chart URL | repo/chartname] [...] [flags] +``` + +### 可选项 + +```shell + --ca-file string verify certificates of HTTPS-enabled servers using this CA bundle + --cert-file string identify HTTPS client using this SSL certificate file + -d, --destination string location to write the chart. If this and untardir are specified, untardir is appended to this (default ".") + --devel use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored. + -h, --help help for pull + --insecure-skip-tls-verify skip tls certificate checks for the chart download + --key-file string identify HTTPS client using this SSL key file + --keyring string location of public keys used for verification (default "~/.gnupg/pubring.gpg") + --pass-credentials pass credentials to all domains + --password string chart repository password where to locate the requested chart + --prov fetch the provenance file, but don't perform verification + --repo string chart repository url where to locate the requested chart + --untar if set to true, will untar the chart after downloading it + --untardir string if untar is specified, this flag specifies the name of the directory into which the chart is expanded (default ".") + --username string chart repository username where to locate the requested chart + --verify verify the package before using it + --version string specify a version constraint for the chart version to use. This constraint can be a specific tag (e.g. 1.1.1) or it may reference a valid range (e.g. ^2.0.0). If this is not specified, the latest version is used +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm](helm.md) - 针对Kubernetes的Helm包管理器 diff --git a/content/zh/docs/helm/helm_push.md b/content/zh/docs/helm/helm_push.md new file mode 100644 index 0000000000..854afacbd1 --- /dev/null +++ b/content/zh/docs/helm/helm_push.md @@ -0,0 +1,47 @@ +--- +title: "Helm 推送" +--- + +## helm push + +将chart推送到远程 + +### 简介 + +上传chart到注册表。 + +如果chart有其他相关文件,也会一起上传。 + +```shell +helm push [chart] [remote] [flags] +``` + +### 可选项 + +```shell + -h, --help help for push +``` + +### 从父命令继承的可选项 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm](helm.md) - 针对Kubernetes的Helm包管理器。 diff --git a/content/zh/docs/helm/helm_registry.md b/content/zh/docs/helm/helm_registry.md new file mode 100644 index 0000000000..9be16d2290 --- /dev/null +++ b/content/zh/docs/helm/helm_registry.md @@ -0,0 +1,43 @@ +--- +title: "Helm 注册表" +--- + +## helm registry + +登录或登出注册表 + +### 简介 + +该命令由多个子命令组成,用于与注册表交互。 + +### 可选项 + +```shell + -h, --help help for registry +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm](helm.md) - 针对Kubernetes的Helm包管理器。 +* [helm registry login](helm_registry_login.md) - 登录注册表 +* [helm registry logout](helm_registry_logout.md) - 从注册表登出 diff --git a/content/zh/docs/helm/helm_registry_login.md b/content/zh/docs/helm/helm_registry_login.md new file mode 100644 index 0000000000..e033853a1b --- /dev/null +++ b/content/zh/docs/helm/helm_registry_login.md @@ -0,0 +1,49 @@ +--- +title: "Helm 注册表登录" +--- + +## helm registry login + +登录注册表 + +### 简介 + +用远程注册表进行身份验证。 + +```shell +helm registry login [host] [flags] +``` + +### 可选项 + +```shell + -h, --help help for login + --insecure allow connections to TLS registry without certs + -p, --password string registry password or identity token + --password-stdin read password or identity token from stdin + -u, --username string registry username +``` + +### 从父命令继承的可选项 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm registry](helm_registry.md) - 登录或登出注册表 diff --git a/content/zh/docs/helm/helm_registry_logout.md b/content/zh/docs/helm/helm_registry_logout.md new file mode 100644 index 0000000000..f748d37f74 --- /dev/null +++ b/content/zh/docs/helm/helm_registry_logout.md @@ -0,0 +1,45 @@ +--- +title: "Helm 注册表登出" +--- + +## helm registry logout + +从注册表登出 + +### 简介 + +从远程注册表移除认证信息。 + +```shell +helm registry logout [host] [flags] +``` + +### 可选项 + +```shell + -h, --help help for logout +``` + +### 从父命令继承的可选项 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm registry](helm_registry.md) - 登录或登出注册表 diff --git a/content/zh/docs/helm/helm_repo.md b/content/zh/docs/helm/helm_repo.md new file mode 100644 index 0000000000..172bb11249 --- /dev/null +++ b/content/zh/docs/helm/helm_repo.md @@ -0,0 +1,48 @@ +--- +title: "Helm 仓库" +--- + +## helm repo + +添加、列出、删除、更新和索引chart仓库 + +### 简介 + +该命令由于chart仓库交互的多条子命令组成 + +可以用来添加、删除、列举和索引chart仓库 + +### 可选项 + +```shell + -h, --help help for repo +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm](helm.md) - 针对Kubernetes的Helm包管理器 +* [helm repo add](helm_repo_add.md) - 添加chart仓库 +* [helm repo index](helm_repo_index.md) - 基于包含打包chart的目录,生成索引文件 +* [helm repo list](helm_repo_list.md) - 列举chart仓库 +* [helm repo remove](helm_repo_remove.md) - 删除一个或多个仓库 +* [helm repo update](helm_repo_update.md) - 从chart仓库中更新本地可用chart的信息 diff --git a/content/zh/docs/helm/helm_repo_add.md b/content/zh/docs/helm/helm_repo_add.md new file mode 100644 index 0000000000..115f24bca9 --- /dev/null +++ b/content/zh/docs/helm/helm_repo_add.md @@ -0,0 +1,52 @@ +--- +title: "Helm 添加仓库" +--- + +## helm repo add + +添加chart仓库 + +```shell +helm repo add [NAME] [URL] [flags] +``` + +### 可选项 + +```shell + --allow-deprecated-repos by default, this command will not allow adding official repos that have been permanently deleted. This disables that behavior + --ca-file string verify certificates of HTTPS-enabled servers using this CA bundle + --cert-file string identify HTTPS client using this SSL certificate file + --force-update replace (overwrite) the repo if it already exists + -h, --help help for add + --insecure-skip-tls-verify skip tls certificate checks for the repository + --key-file string identify HTTPS client using this SSL key file + --no-update Ignored. Formerly, it would disabled forced updates. It is deprecated by force-update. + --pass-credentials pass credentials to all domains + --password string chart repository password + --password-stdin read chart repository password from stdin + --username string chart repository username +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm repo](helm_repo.md) - 添加、列出、删除、更新和索引chart仓库 diff --git a/content/zh/docs/helm/helm_repo_index.md b/content/zh/docs/helm/helm_repo_index.md new file mode 100644 index 0000000000..5d6deb437f --- /dev/null +++ b/content/zh/docs/helm/helm_repo_index.md @@ -0,0 +1,52 @@ +--- +title: "Helm 仓库索引" +--- + +## helm repo index + +基于包含打包chart的目录,生成索引文件 + +### 简介 + +读取当前目录,并根据找到的 chart 生成索引文件。 + +这个工具用来为chart仓库创建一个'index.yaml'文件,使用'--url'参数创建一个chart的绝对URL。 + +要合并生成的索引和已经存在的索引文件时,使用'--merge'参数。在这个场景中,在当前目录中找到的chart会合并到已有索引中, +本地chart的优先级高于已有chart。 + +```shell +helm repo index [DIR] [flags] +``` + +### 可选项 + +```shell + -h, --help help for index + --merge string merge the generated index into the given index + --url string url of chart repository +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm repo](helm_repo.md) - 添加、列出、删除、更新和索引chart仓库 diff --git a/content/zh/docs/helm/helm_repo_list.md b/content/zh/docs/helm/helm_repo_list.md new file mode 100644 index 0000000000..82b504ca6e --- /dev/null +++ b/content/zh/docs/helm/helm_repo_list.md @@ -0,0 +1,42 @@ +--- +title: "Helm 仓库列表" +--- + +## helm repo list + +列举chart仓库 + +```shell +helm repo list [flags] +``` + +### 可选项 + +```shell + -h, --help help for list + -o, --output format prints the output in the specified format. Allowed values: table, json, yaml (default table) +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm repo](helm_repo.md) - 添加、列出、删除、更新和索引chart仓库 diff --git a/content/zh/docs/helm/helm_repo_remove.md b/content/zh/docs/helm/helm_repo_remove.md new file mode 100644 index 0000000000..4fca0be6fa --- /dev/null +++ b/content/zh/docs/helm/helm_repo_remove.md @@ -0,0 +1,41 @@ +--- +title: "Helm 删除仓库" +--- + +## helm repo remove + +删除一个或多个仓库 + +```shell +helm repo remove [REPO1 [REPO2 ...]] [flags] +``` + +### 可选项 + +```shell + -h, --help help for remove +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm repo](helm_repo.md) - 添加、列出、删除、更新和索引chart仓库 diff --git a/content/zh/docs/helm/helm_repo_update.md b/content/zh/docs/helm/helm_repo_update.md new file mode 100644 index 0000000000..0f7273701c --- /dev/null +++ b/content/zh/docs/helm/helm_repo_update.md @@ -0,0 +1,50 @@ +--- +title: "Helm 仓库更新" +--- + +## helm repo update + +从chart仓库中更新本地可用chart的信息 + +### 简介 + +更新从各自chart仓库中获取的有关chart的最新信息。信息会缓存在本地,被诸如'helm search'等命令使用。 + +你可以指定需要更新的仓库列表。 + $ helm repo update ... +使用 'helm repo update' 更新所有仓库。 + +```shell +helm repo update [REPO1 [REPO2 ...]] [flags] +``` + +### 可选项 + +```shell + --fail-on-repo-update-fail update fails if any of the repository updates fail + -h, --help help for update +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm repo](helm_repo.md) - 添加、列出、删除、更新和索引chart仓库 diff --git a/content/zh/docs/helm/helm_rollback.md b/content/zh/docs/helm/helm_rollback.md new file mode 100644 index 0000000000..029164ec49 --- /dev/null +++ b/content/zh/docs/helm/helm_rollback.md @@ -0,0 +1,58 @@ +--- +title: "Helm 回滚" +--- + +## helm rollback + +回滚发布到上一个版本 + +### 简介 + +该命令回滚发布到上一个版本 + +回滚命令的第一个参数是发布的名称,第二是修订(版本)号,如果省略此参数,会回滚到上一个版本。 + +要查看修订号,执行'helm history RELEASE'。 + +```shell +helm rollback [REVISION] [flags] +``` + +### 可选项 + +```shell + --cleanup-on-fail allow deletion of new resources created in this rollback when rollback fails + --dry-run simulate a rollback + --force force resource update through delete/recreate if needed + -h, --help help for rollback + --history-max int limit the maximum number of revisions saved per release. Use 0 for no limit (default 10) + --no-hooks prevent hooks from running during rollback + --recreate-pods performs pods restart for the resource if applicable + --timeout duration time to wait for any individual Kubernetes operation (like Jobs for hooks) (default 5m0s) + --wait if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment, StatefulSet, or ReplicaSet are in a ready state before marking the release as successful. It will wait for as long as --timeout + --wait-for-jobs if set and --wait enabled, will wait until all Jobs have been completed before marking the release as successful. It will wait for as long as --timeout +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm](helm.md) - 针对Kubernetes的Helm包管理器 diff --git a/content/zh/docs/helm/helm_search.md b/content/zh/docs/helm/helm_search.md new file mode 100644 index 0000000000..e21f394a8e --- /dev/null +++ b/content/zh/docs/helm/helm_search.md @@ -0,0 +1,43 @@ +--- +title: "Helm 搜索" +--- + +## helm search + +helm中搜索关键字 + +### 简介 + +搜索提供了可以在已经添加的Artifact Hub和仓库等多个位置搜索Helm chart 的能力。 + +### 可选项 + +```shell + -h, --help help for search +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm](helm.md) - 针对Kubernetes的Helm包管理器 +* [helm search hub](helm_search_hub.md) - 在Artifact Hub或自己的hub实例中搜索chart +* [helm search repo](helm_search_repo.md) - 用chart中关键字搜索仓库 diff --git a/content/zh/docs/helm/helm_search_hub.md b/content/zh/docs/helm/helm_search_hub.md new file mode 100644 index 0000000000..eb2ed6623f --- /dev/null +++ b/content/zh/docs/helm/helm_search_hub.md @@ -0,0 +1,57 @@ +--- +title: "Helm 搜索hub" +--- + +## helm search hub + +在Artifact Hub或自己的hub实例中搜索chart + +### 简介 + +在Artifact Hub或自己的hub实例中搜索Helm charts。 + +Artifact Hub 是基于web页面的应用,支持CNCF项目的查找、安装和发布包及配置项,包括了公开发布的Helm chart。它是CNCF的沙盒项目。可以访问https://artifacthub.io/ + +[KEYWORD] 参数接受关键字字符串或者带引号的查询字符串。查询字符串的文档,请查看 https://artifacthub.github.io/hub/api/?urls.primaryName=Monocular%20compatible%20search%20API#/Monocular/get_api_chartsvc_v1_charts_search + +之前的Helm版本使用Monocular实例作为默认的endpoint,因此为了向后兼容,Artifact +Hub兼容Monocular的搜索API。类似地,要设置endpoint参数时,指定的endpoint也必须兼容Monocular的搜索API。 +注意,指定Monocular实例作为endpoint时,不支持字符串查询。更多API细节,请参考 https://github.com/helm/monocular + +```shell +helm search hub [KEYWORD] [flags] +``` + +### 可选项 + +```shell + --endpoint string Hub instance to query for charts (default "https://hub.helm.sh") + -h, --help help for hub + --list-repo-url print charts repository URL + --max-col-width uint maximum column width for output table (default 50) + -o, --output format prints the output in the specified format. Allowed values: table, json, yaml (default table) +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm search](helm_search.md) - helm中搜索关键字 diff --git a/content/zh/docs/helm/helm_search_repo.md b/content/zh/docs/helm/helm_search_repo.md new file mode 100644 index 0000000000..0de4893b52 --- /dev/null +++ b/content/zh/docs/helm/helm_search_repo.md @@ -0,0 +1,68 @@ +--- +title: "Helm 搜索仓库" +--- + +## helm search repo + +用chart中关键字搜索仓库 + +### 简介 + +搜索会读取系统上配置的所有仓库,并查找匹配。搜索这些仓库会使用存储在系统中的元数据。 + +它会展示找到最新稳定版本的chart。如果指定了--devel参数,输出会包括预发布版本。 + +示例: + +```shell +# Search for stable release versions matching the keyword "nginx" +$ helm search repo nginx + +# Search for release versions matching the keyword "nginx", including pre-release versions +$ helm search repo nginx --devel + +# Search for the latest stable release for nginx-ingress with a major version of 1 +$ helm search repo nginx-ingress --version ^1.0.0 +``` + +仓库使用'helm repo'命令管理。 + +```shell +helm search repo [keyword] [flags] +``` + +### 可选项 + +```shell + --devel use development versions (alpha, beta, and release candidate releases), too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored + -h, --help help for repo + --max-col-width uint maximum column width for output table (default 50) + -o, --output format prints the output in the specified format. Allowed values: table, json, yaml (default table) + -r, --regexp use regular expressions for searching repositories you have added + --version string search using semantic versioning constraints on repositories you have added + -l, --versions show the long listing, with each version of each chart on its own line, for repositories you have added +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm search](helm_search.md) - helm中搜索关键字 diff --git a/content/zh/docs/helm/helm_show.md b/content/zh/docs/helm/helm_show.md new file mode 100644 index 0000000000..dac54c8a04 --- /dev/null +++ b/content/zh/docs/helm/helm_show.md @@ -0,0 +1,46 @@ +--- +title: "Helm 展示" +--- + +## helm show + +显示chart信息 + +### 简介 + +该命令由多条子命令组成来显示chart的信息 + +### 可选项 + +```shell + -h, --help help for show +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +- [helm](helm.md) - 针对Kubernetes的Helm包管理器 +- [helm show all](helm_show_all.md) - 显示chart的所有信息 +- [helm show chart](helm_show_chart.md) - 显示chart定义 +- [helm show crds](helm_show_crds.md) - 显示chart的CRD +- [helm show readme](helm_show_readme.md) - 显示chart的README +- [helm show values](helm_show_values.md) - 显示chart的values diff --git a/content/zh/docs/helm/helm_show_all.md b/content/zh/docs/helm/helm_show_all.md new file mode 100644 index 0000000000..514ebc1761 --- /dev/null +++ b/content/zh/docs/helm/helm_show_all.md @@ -0,0 +1,57 @@ +--- +title: "Helm 展示所有" +--- + +## helm show all + +显示chart的所有信息 + +### 简介 + +该命令检查chart(目录、文件或URL)并显示所有的内容(values.yaml, Chart.yaml, README) + +```shell +helm show all [CHART] [flags] +``` + +### 可选项 + +```shell + --ca-file string verify certificates of HTTPS-enabled servers using this CA bundle + --cert-file string identify HTTPS client using this SSL certificate file + --devel use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored + -h, --help help for all + --insecure-skip-tls-verify skip tls certificate checks for the chart download + --key-file string identify HTTPS client using this SSL key file + --keyring string location of public keys used for verification (default "~/.gnupg/pubring.gpg") + --pass-credentials pass credentials to all domains + --password string chart repository password where to locate the requested chart + --repo string chart repository url where to locate the requested chart + --username string chart repository username where to locate the requested chart + --verify verify the package before using it + --version string specify a version constraint for the chart version to use. This constraint can be a specific tag (e.g. 1.1.1) or it may reference a valid range (e.g. ^2.0.0). If this is not specified, the latest version is used +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm show](helm_show.md) - 显示chart信息 diff --git a/content/zh/docs/helm/helm_show_chart.md b/content/zh/docs/helm/helm_show_chart.md new file mode 100644 index 0000000000..68ad894fde --- /dev/null +++ b/content/zh/docs/helm/helm_show_chart.md @@ -0,0 +1,57 @@ +--- +title: "Helm 展示chart" +--- + +## helm show chart + +显示chart定义 + +### 简介 + +该命令检查chart(目录、文件或URL)并显示Chart.yaml文件的内容 + +```shell +helm show chart [CHART] [flags] +``` + +### 可选项 + +```shell + --ca-file string verify certificates of HTTPS-enabled servers using this CA bundle + --cert-file string identify HTTPS client using this SSL certificate file + --devel use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored + -h, --help help for chart + --insecure-skip-tls-verify skip tls certificate checks for the chart download + --key-file string identify HTTPS client using this SSL key file + --keyring string location of public keys used for verification (default "~/.gnupg/pubring.gpg") + --pass-credentials pass credentials to all domains + --password string chart repository password where to locate the requested chart + --repo string chart repository url where to locate the requested chart + --username string chart repository username where to locate the requested chart + --verify verify the package before using it + --version string specify a version constraint for the chart version to use. This constraint can be a specific tag (e.g. 1.1.1) or it may reference a valid range (e.g. ^2.0.0). If this is not specified, the latest version is used +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm show](helm_show.md) - 显示chart信息 diff --git a/content/zh/docs/helm/helm_show_crds.md b/content/zh/docs/helm/helm_show_crds.md new file mode 100644 index 0000000000..b8649107f4 --- /dev/null +++ b/content/zh/docs/helm/helm_show_crds.md @@ -0,0 +1,57 @@ +--- +title: "Helm 展示Crd" +--- + +## helm show crds + +显示chart的CRD + +### 简介 + +该命令检查chart(目录、文件或URL)并显示自定义资源(CustomResourceDefinition)文件的内容。 + +```shell +helm show crds [CHART] [flags] +``` + +### 可选项 + +```shell + --ca-file string verify certificates of HTTPS-enabled servers using this CA bundle + --cert-file string identify HTTPS client using this SSL certificate file + --devel use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored + -h, --help help for crds + --insecure-skip-tls-verify skip tls certificate checks for the chart download + --key-file string identify HTTPS client using this SSL key file + --keyring string location of public keys used for verification (default "~/.gnupg/pubring.gpg") + --pass-credentials pass credentials to all domains + --password string chart repository password where to locate the requested chart + --repo string chart repository url where to locate the requested chart + --username string chart repository username where to locate the requested chart + --verify verify the package before using it + --version string specify a version constraint for the chart version to use. This constraint can be a specific tag (e.g. 1.1.1) or it may reference a valid range (e.g. ^2.0.0). If this is not specified, the latest version is used +``` + +### 从父命令继承的可选项 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### SEE ALSO + +* [helm show](helm_show.md) - 显示chart信息 diff --git a/content/zh/docs/helm/helm_show_readme.md b/content/zh/docs/helm/helm_show_readme.md new file mode 100644 index 0000000000..cd7ecae6f3 --- /dev/null +++ b/content/zh/docs/helm/helm_show_readme.md @@ -0,0 +1,57 @@ +--- +title: "Helm 展示readme" +--- + +## helm show readme + +显示chart的README + +### 简介 + +该命令检查chart(目录、文件或URL)并显示README文件内容 + +```shell +helm show readme [CHART] [flags] +``` + +### 可选项 + +```shell + --ca-file string verify certificates of HTTPS-enabled servers using this CA bundle + --cert-file string identify HTTPS client using this SSL certificate file + --devel use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored + -h, --help help for readme + --insecure-skip-tls-verify skip tls certificate checks for the chart download + --key-file string identify HTTPS client using this SSL key file + --keyring string location of public keys used for verification (default "~/.gnupg/pubring.gpg") + --pass-credentials pass credentials to all domains + --password string chart repository password where to locate the requested chart + --repo string chart repository url where to locate the requested chart + --username string chart repository username where to locate the requested chart + --verify verify the package before using it + --version string specify a version constraint for the chart version to use. This constraint can be a specific tag (e.g. 1.1.1) or it may reference a valid range (e.g. ^2.0.0). If this is not specified, the latest version is used +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm show](helm_show.md) - 显示chart信息 diff --git a/content/zh/docs/helm/helm_show_values.md b/content/zh/docs/helm/helm_show_values.md new file mode 100644 index 0000000000..b2b192b67b --- /dev/null +++ b/content/zh/docs/helm/helm_show_values.md @@ -0,0 +1,58 @@ +--- +title: "Helm 展示value" +--- + +## helm show values + +显示chart的values + +### 简介 + +该命令检查chart(目录、文件或URL)并显示values.yaml文件的内容 + +```shell +helm show values [CHART] [flags] +``` + +### 可选项 + +```shell + --ca-file string verify certificates of HTTPS-enabled servers using this CA bundle + --cert-file string identify HTTPS client using this SSL certificate file + --devel use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored + -h, --help help for values + --insecure-skip-tls-verify skip tls certificate checks for the chart download + --jsonpath string supply a JSONPath expression to filter the output + --key-file string identify HTTPS client using this SSL key file + --keyring string location of public keys used for verification (default "~/.gnupg/pubring.gpg") + --pass-credentials pass credentials to all domains + --password string chart repository password where to locate the requested chart + --repo string chart repository url where to locate the requested chart + --username string chart repository username where to locate the requested chart + --verify verify the package before using it + --version string specify a version constraint for the chart version to use. This constraint can be a specific tag (e.g. 1.1.1) or it may reference a valid range (e.g. ^2.0.0). If this is not specified, the latest version is used +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm show](helm_show.md) - 显示chart信息 diff --git a/content/zh/docs/helm/helm_status.md b/content/zh/docs/helm/helm_status.md new file mode 100644 index 0000000000..de8c1a5261 --- /dev/null +++ b/content/zh/docs/helm/helm_status.md @@ -0,0 +1,59 @@ +--- +title: "Helm 状态" +--- + +## helm status + +显示已命名发布的状态 + +### 简介 + +该命令显示已命名发布的状态,状态包括: + +- 最后部署时间 +- 发布版本所在的k8s命名空间 +- 发布状态(可以是: unknown, deployed, uninstalled, superseded, failed, uninstalling, +pending-install, pending-upgrade 或 pending-rollback) +- 发布版本修订 +- 发布版本描述(可以是完成信息或错误信息,需要用--show-desc启用) +- 列举版本包含的资源(使用--show-resources显示) +- 最后一次测试套件运行的详细信息(如果使用) +- chart提供的额外的注释 + +```shell +helm status RELEASE_NAME [flags] +``` + +### 可选项 + +```shell + -h, --help help for status + -o, --output format prints the output in the specified format. Allowed values: table, json, yaml (default table) + --revision int if set, display the status of the named release with revision + --show-desc if set, display the description message of the named release + --show-resources if set, display the resources of the named release +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +- [helm](helm.md) - 针对Kubernetes的Helm包管理器 diff --git a/content/zh/docs/helm/helm_template.md b/content/zh/docs/helm/helm_template.md new file mode 100644 index 0000000000..cbb5e3ad9d --- /dev/null +++ b/content/zh/docs/helm/helm_template.md @@ -0,0 +1,92 @@ +--- +title: "Helm 模板" +--- + +## helm template + +本地渲染模板 + +### 简介 + +本地渲染模板并显示输出 + +通常在集群中查找或检索到的任何值都可以在本地伪造。另外,没有对chart有效性进行服务端测试。 + +```shell +helm template [NAME] [CHART] [flags] +``` + +### 可选项 + +```shell + -a, --api-versions strings Kubernetes api versions used for Capabilities.APIVersions + --atomic if set, the installation process deletes the installation on failure. The --wait flag will be set automatically if --atomic is used + --ca-file string verify certificates of HTTPS-enabled servers using this CA bundle + --cert-file string identify HTTPS client using this SSL certificate file + --create-namespace create the release namespace if not present + --dependency-update update dependencies if they are missing before installing the chart + --description string add a custom description + --devel use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored + --disable-openapi-validation if set, the installation process will not validate rendered templates against the Kubernetes OpenAPI Schema + --dry-run simulate an install + --enable-dns enable DNS lookups when rendering templates + --force force resource updates through a replacement strategy + -g, --generate-name generate the name (and omit the NAME parameter) + -h, --help help for template + --include-crds include CRDs in the templated output + --insecure-skip-tls-verify skip tls certificate checks for the chart download + --is-upgrade set .Release.IsUpgrade instead of .Release.IsInstall + --key-file string identify HTTPS client using this SSL key file + --keyring string location of public keys used for verification (default "~/.gnupg/pubring.gpg") + --kube-version string Kubernetes version used for Capabilities.KubeVersion + --name-template string specify template used to name the release + --no-hooks prevent hooks from running during install + --output-dir string writes the executed templates to files in output-dir instead of stdout + --pass-credentials pass credentials to all domains + --password string chart repository password where to locate the requested chart + --post-renderer postRendererString the path to an executable to be used for post rendering. If it exists in $PATH, the binary will be used, otherwise it will try to look for the executable at the given path + --post-renderer-args postRendererArgsSlice an argument to the post-renderer (can specify multiple) (default []) + --release-name use release name in the output-dir path. + --render-subchart-notes if set, render subchart notes along with the parent + --replace re-use the given name, only if that name is a deleted release which remains in the history. This is unsafe in production + --repo string chart repository url where to locate the requested chart + --set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) + --set-file stringArray set values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2) + --set-json stringArray set JSON values on the command line (can specify multiple or separate values with commas: key1=jsonval1,key2=jsonval2) + --set-string stringArray set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) + -s, --show-only stringArray only show manifests rendered from the given templates + --skip-crds if set, no CRDs will be installed. By default, CRDs are installed if not already present + --skip-tests skip tests from templated output + --timeout duration time to wait for any individual Kubernetes operation (like Jobs for hooks) (default 5m0s) + --username string chart repository username where to locate the requested chart + --validate validate your manifests against the Kubernetes cluster you are currently pointing at. This is the same validation performed on an install + -f, --values strings specify values in a YAML file or a URL (can specify multiple) + --verify verify the package before using it + --version string specify a version constraint for the chart version to use. This constraint can be a specific tag (e.g. 1.1.1) or it may reference a valid range (e.g. ^2.0.0). If this is not specified, the latest version is used + --wait if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment, StatefulSet, or ReplicaSet are in a ready state before marking the release as successful. It will wait for as long as --timeout + --wait-for-jobs if set and --wait enabled, will wait until all Jobs have been completed before marking the release as successful. It will wait for as long as --timeout +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm](helm.md) - 针对Kubernetes的Helm包管理器 diff --git a/content/zh/docs/helm/helm_test.md b/content/zh/docs/helm/helm_test.md new file mode 100644 index 0000000000..42bfbbd9f5 --- /dev/null +++ b/content/zh/docs/helm/helm_test.md @@ -0,0 +1,50 @@ +--- +title: "Helm 测试" +--- + +## helm test + +执行发布版本的测试 + +### 简介 + +测试命令执行发布版本的测试 + +该命令使用的参数是部署版本的名称,要运行的测试在已安装的chart中定义。 + +```shell +helm test [RELEASE] [flags] +``` + +### 可选项 + +```shell + --filter strings specify tests by attribute (currently "name") using attribute=value syntax or '!attribute=value' to exclude a test (can specify multiple or separate values with commas: name=test1,name=test2) + -h, --help help for test + --logs dump the logs from test pods (this runs after all tests are complete, but before any cleanup) + --timeout duration time to wait for any individual Kubernetes operation (like Jobs for hooks) (default 5m0s) +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm](helm.md) - 针对Kubernetes的Helm包管理器 diff --git a/content/zh/docs/helm/helm_uninstall.md b/content/zh/docs/helm/helm_uninstall.md new file mode 100644 index 0000000000..b3ddaeb31f --- /dev/null +++ b/content/zh/docs/helm/helm_uninstall.md @@ -0,0 +1,55 @@ +--- +title: "Helm 卸载" +--- + +## helm uninstall + +卸载版本 + +### 简介 + +该命令使用版本名称卸载版本 + +会删除与最新版本chart相关的所有资源以及发布历史,释放以供将来使用 + +使用'--dry-run'参数查看哪些版本将在不实际卸载的情况下能够被卸载 + +```shell +helm uninstall RELEASE_NAME [...] [flags] +``` + +### 可选项 + +```shell + --description string add a custom description + --dry-run simulate a uninstall + -h, --help help for uninstall + --keep-history remove all associated resources and mark the release as deleted, but retain the release history + --no-hooks prevent hooks from running during uninstallation + --timeout duration time to wait for any individual Kubernetes operation (like Jobs for hooks) (default 5m0s) + --wait if set, will wait until all the resources are deleted before returning. It will wait for as long as --timeout +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm](helm.md) - 针对Kubernetes的Helm包管理器 diff --git a/content/zh/docs/helm/helm_upgrade.md b/content/zh/docs/helm/helm_upgrade.md new file mode 100644 index 0000000000..e4169cb22d --- /dev/null +++ b/content/zh/docs/helm/helm_upgrade.md @@ -0,0 +1,105 @@ +--- +title: "Helm 升级" +--- + +## helm upgrade + +升级版本 + +### 简介 + +该命令将发布升级到新版的chart。 + +升级参数必须是发布和chart。chart参数可以是:chart引用('example/mariadb'),chart目录路径,打包的chart或者完整URL。 +对于chart引用,除非使用'--version'参数指定,否则会使用最新版本。 + +要在chart中重写value,需要使用'--values'参数并传一个文件或者从命令行使用'--set'参数传个配置, +要强制字符串值,使用'--set-string'。当值本身对于命令行太长或者是动态生成的时候,可以使用 '--set-file' 设置独立的值。 +也可以在命令行使用'--set-json'参数设置json值(scalars/objects/arrays)。 + +可以多次指定'--values'/'-f'参数,最后(最右边)指定的文件优先级最高。比如如果myvalues.yaml和override.yaml同时包含了名为 +'Test'的key,override.yaml中的设置会优先使用: + +```shell + $ helm upgrade -f myvalues.yaml -f override.yaml redis ./redis +``` + +可以多次指定'--set'参数,最后(最右边)指定的优先级最高。比如'bar' 和 'newbar'都设置了一个名为'foo'的可以, +'newbar'的值会优先使用: + +```shell + $ helm upgrade --set foo=bar --set foo=newbar redis ./redis +``` + +```shell +helm upgrade [RELEASE] [CHART] [flags] +``` + +### 可选项 + +```shell + --atomic if set, upgrade process rolls back changes made in case of failed upgrade. The --wait flag will be set automatically if --atomic is used + --ca-file string verify certificates of HTTPS-enabled servers using this CA bundle + --cert-file string identify HTTPS client using this SSL certificate file + --cleanup-on-fail allow deletion of new resources created in this upgrade when upgrade fails + --create-namespace if --install is set, create the release namespace if not present + --dependency-update update dependencies if they are missing before installing the chart + --description string add a custom description + --devel use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored + --disable-openapi-validation if set, the upgrade process will not validate rendered templates against the Kubernetes OpenAPI Schema + --dry-run simulate an upgrade + --enable-dns enable DNS lookups when rendering templates + --force force resource updates through a replacement strategy + -h, --help help for upgrade + --history-max int limit the maximum number of revisions saved per release. Use 0 for no limit (default 10) + --insecure-skip-tls-verify skip tls certificate checks for the chart download + -i, --install if a release by this name doesn't already exist, run an install + --key-file string identify HTTPS client using this SSL key file + --keyring string location of public keys used for verification (default "~/.gnupg/pubring.gpg") + --no-hooks disable pre/post upgrade hooks + -o, --output format prints the output in the specified format. Allowed values: table, json, yaml (default table) + --pass-credentials pass credentials to all domains + --password string chart repository password where to locate the requested chart + --post-renderer postRendererString the path to an executable to be used for post rendering. If it exists in $PATH, the binary will be used, otherwise it will try to look for the executable at the given path + --post-renderer-args postRendererArgsSlice an argument to the post-renderer (can specify multiple) (default []) + --render-subchart-notes if set, render subchart notes along with the parent + --repo string chart repository url where to locate the requested chart + --reset-values when upgrading, reset the values to the ones built into the chart + --reuse-values when upgrading, reuse the last release's values and merge in any overrides from the command line via --set and -f. If '--reset-values' is specified, this is ignored + --set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) + --set-file stringArray set values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2) + --set-json stringArray set JSON values on the command line (can specify multiple or separate values with commas: key1=jsonval1,key2=jsonval2) + --set-string stringArray set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) + --skip-crds if set, no CRDs will be installed when an upgrade is performed with install flag enabled. By default, CRDs are installed if not already present, when an upgrade is performed with install flag enabled + --timeout duration time to wait for any individual Kubernetes operation (like Jobs for hooks) (default 5m0s) + --username string chart repository username where to locate the requested chart + -f, --values strings specify values in a YAML file or a URL (can specify multiple) + --verify verify the package before using it + --version string specify a version constraint for the chart version to use. This constraint can be a specific tag (e.g. 1.1.1) or it may reference a valid range (e.g. ^2.0.0). If this is not specified, the latest version is used + --wait if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment, StatefulSet, or ReplicaSet are in a ready state before marking the release as successful. It will wait for as long as --timeout + --wait-for-jobs if set and --wait enabled, will wait until all Jobs have been completed before marking the release as successful. It will wait for as long as --timeout +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm](helm.md) - 针对Kubernetes的Helm包管理器 diff --git a/content/zh/docs/helm/helm_verify.md b/content/zh/docs/helm/helm_verify.md new file mode 100644 index 0000000000..95875d947d --- /dev/null +++ b/content/zh/docs/helm/helm_verify.md @@ -0,0 +1,50 @@ +--- +title: "Helm 验证" +--- + +## helm verify + +验证给定路径的chart已经被签名且有效 + +### 简介 + +验证指定的chart有合法的源文件。 + +源文件提供了加密验证保证chart未被篡改,且由可信提供商打包。 + +该命令用于验证本地chart,其他一些命令提供'--verify'参数执行同样的验证。要生成一个签名包,使用'helm package --sign'命令。 + +```shell +helm verify PATH [flags] +``` + +### 可选项 + +```shell + -h, --help help for verify + --keyring string keyring containing public keys (default "~/.gnupg/pubring.gpg") +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +* [helm](helm.md) - 针对Kubernetes的Helm包管理器 diff --git a/content/zh/docs/helm/helm_version.md b/content/zh/docs/helm/helm_version.md new file mode 100644 index 0000000000..cd2516f298 --- /dev/null +++ b/content/zh/docs/helm/helm_version.md @@ -0,0 +1,66 @@ +--- +title: "Helm 版本" +--- + +## helm version + +打印客户端版本信息 + +### 简介 + +显示Helm的版本。 + +该命令会打印Helm的版本描述,输出如下: + +version.BuildInfo{Version:"v3.2.1", GitCommit:"fe51cd1e31e6a202cba7dead9552a6d418ded79a", +GitTreeState:"clean", GoVersion:"go1.13.10"} + +- 版本是发布的语义化版本。 +- GitCommit是用于生成此版本提交的SHA +- 如果构建二级制包是没有本地代码修改,GitTreeState就是"干净的" +- GoVersion是用于编译Helm的Go版本 + +当使用--template参数时,下列属性在模板中是可用的: + +- .Version 包含了Helm的语义化版本 +- .GitCommit 是git的提交 +- .GitTreeState 是Helm构建时的git树结构 +- .GoVersion 包含Helm编译时使用的Go版本 + +比如, --template='Version: {{.Version}}' 输出 'Version: v3.2.1'。 + +```shell +helm version [flags] +``` + +### 可选项 + +```shell + -h, --help help for version + --short print the version number + --template string template for version string format +``` + +### 从父命令继承的命令 + +```shell + --burst-limit int client-side default throttling limit (default 100) + --debug enable verbose output + --kube-apiserver string the address and the port for the Kubernetes API server + --kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --kube-as-user string username to impersonate for the operation + --kube-ca-file string the certificate authority file for the Kubernetes API server connection + --kube-context string name of the kubeconfig context to use + --kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used + --kube-token string bearer token used for authentication + --kubeconfig string path to the kubeconfig file + -n, --namespace string namespace scope for this request + --registry-config string path to the registry config file (default "~/.config/helm/registry/config.json") + --repository-cache string path to the file containing cached repository indexes (default "~/.cache/helm/repository") + --repository-config string path to the file containing repository names and URLs (default "~/.config/helm/repositories.yaml") +``` + +### 请参阅 + +- [helm](helm.md) - 针对Kubernetes的Helm包管理器 diff --git a/content/zh/docs/howto/_index.md b/content/zh/docs/howto/_index.md new file mode 100644 index 0000000000..acfbd41299 --- /dev/null +++ b/content/zh/docs/howto/_index.md @@ -0,0 +1,8 @@ +--- +title: "如何使用" +weight: 2 +--- + +# 使用指引 + +这里您可以找到简单的“我如何做...”类型问题的简短答案。这些使用指引不能覆盖主题的深度,你可以在 [主题指引](../topics) 中获得更多内容。然而这些指引可以帮助您快速完成一般任务。 diff --git a/content/zh/docs/howto/chart_releaser_action.md b/content/zh/docs/howto/chart_releaser_action.md new file mode 100644 index 0000000000..64b6ff0642 --- /dev/null +++ b/content/zh/docs/howto/chart_releaser_action.md @@ -0,0 +1,89 @@ +--- +title: "Chart发布操作用以自动化GitHub的页面Chart" +description: "描述如何使用Chart发布操作通过GitHub页面自动发布chart。" +weight: 3 +--- + +该指南描述了如何使用[Chart发布操作](https://github.com/marketplace/actions/helm-chart-releaser) +通过GitHub页面自动发布chart。Chart发布操作是一个将GitHub项目转换成自托管Helm chart仓库的GitHub操作流。使用了 +[helm/chart-releaser](https://github.com/helm/chart-releaser) CLI 工具。 + +## 仓库变化 + +在你的GitHub组织下创建一个Git仓库。可以将其命名为`helm-charts`,当然其他名称也可以接受。所有chart的资源都可以放在主分支。 +chart应该放在根目录下的`/charts`目录中。 + +还应该有另一个分支 `gh-pages` 用于发布chart。这个分支的更改会通过Chart发布操作自动创建。同时可以创建一个 +`gh-branch`分支并添加`README.md`文件,其对访问该页面的用户是可见的。 + +你可以在`README.md`中为chart的安装添加说明,像这样: +(替换 ``, `` 和 ``): + +```text +## Usage + +[Helm](https://helm.sh) must be installed to use the charts. Please refer to +Helm's [documentation](https://helm.sh/docs) to get started. + +Once Helm has been set up correctly, add the repo as follows: + + helm repo add https://.github.io/helm-charts + +If you had already added this repo earlier, run `helm repo update` to retrieve +the latest versions of the packages. You can then run `helm search repo +` to see the charts. + +To install the chart: + + helm install my- / + +To uninstall the chart: + + helm delete my- +``` + +发布后的chart的url类似这样: + +`https://.github.io/helm-charts` + +## GitHub 操作流 + +在主分支创建一个GitHub操作流文件 `.github/workflows/release.yml` + +```text +name: Release Charts + +on: + push: + branches: + - main + +jobs: + release: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Configure Git + run: | + git config user.name "$GITHUB_ACTOR" + git config user.email "$GITHUB_ACTOR@users.noreply.github.com" + + - name: Run chart-releaser + uses: helm/chart-releaser-action@v1.5.0 + env: + CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}" +``` + +上述配置使用了[@helm/chart-releaser-action](https://github.com/helm/chart-releaser-action) +将GitHub项目转换成自托管的Helm chart仓库。在每次想主分支推送后会通过检查项目中的每个chart来执行次操作, +且每当有新的chart版本时,会创建一个与chart版本对应的GitHub版本,添加Helm chart组件到这个版本中, +并用该版本的元数据创建或更新一个`index.yaml`文件,然后托管在GitHub页面上。 + +上述Chart发布操作示例使用的版本号是`v1.5.0`。你可以将其改成[最新可用版本](https://github.com/helm/chart-releaser-action/releases)。 + +注意:Chart发布操作程序几乎总是和 [Helm测试操作Action](https://github.com/marketplace/actions/helm-chart-testing) +以及[Kind操作](https://github.com/marketplace/actions/kind-cluster)。 diff --git a/content/zh/docs/howto/chart_repository_sync_example.md b/content/zh/docs/howto/chart_repository_sync_example.md new file mode 100644 index 0000000000..ca5562e516 --- /dev/null +++ b/content/zh/docs/howto/chart_repository_sync_example.md @@ -0,0 +1,89 @@ +--- +title: "同步你的Chart仓库" +description: "描述如何同步本地和远程仓库" +weight: 2 +--- + +*注意: 该示例是专门针对Google Cloud Storage (GCS)提供的chart仓库。* + +## 先决条件 + +* 安装[gsutil](https://cloud.google.com/storage/docs/gsutil)工具。 *我们非常依赖gsutil rsync功能* +* 确保可以使用Helm程序 +* _可选:我们推荐在你的GCS中设置[对象版本](https://cloud.google.com/storage/docs/gsutil/addlhelp/ObjectVersioningandConcurrencyControl#top_of_page)以防不小心删除了什么。_ + +## 设置本地chart仓库目录 + +就像我们在[chart仓库指南](https://helm.sh/zh/docs/topics/chart_repository)做的,创建一个本地目录,并将打包好的chart放在该目录中。 + +例如: + +```console +$ mkdir fantastic-charts +$ mv alpine-0.1.0.tgz fantastic-charts/ +``` + +## 生成新的index.yaml + +使用Helm生成新的index.yaml文件,通过将目录路径和远程仓库url传递给`helm repo index`命令: + +```console +$ helm repo index fantastic-charts/ --url https://fantastic-charts.storage.googleapis.com +``` + +这会生成新的index.yaml文件并放在`fantastic-charts/`目录。 + +## 同步本地和远程仓库 + +使用`scripts/sync-repo.sh`命令上传GCS目录中的内容并传入本地目录名和GCS名。 + +例如: + +```console +$ pwd +/Users/me/code/go/src/helm.sh/helm +$ scripts/sync-repo.sh fantastic-charts/ fantastic-charts +Getting ready to sync your local directory (fantastic-charts/) to a remote repository at gs://fantastic-charts +Verifying Prerequisites.... +Thumbs up! Looks like you have gsutil. Let's continue. +Building synchronization state... +Starting synchronization +Would copy file://fantastic-charts/alpine-0.1.0.tgz to gs://fantastic-charts/alpine-0.1.0.tgz +Would copy file://fantastic-charts/index.yaml to gs://fantastic-charts/index.yaml +Are you sure you would like to continue with these changes?? [y/N]} y +Building synchronization state... +Starting synchronization +Copying file://fantastic-charts/alpine-0.1.0.tgz [Content-Type=application/x-tar]... +Uploading gs://fantastic-charts/alpine-0.1.0.tgz: 740 B/740 B +Copying file://fantastic-charts/index.yaml [Content-Type=application/octet-stream]... +Uploading gs://fantastic-charts/index.yaml: 347 B/347 B +Congratulations your remote chart repository now matches the contents of fantastic-charts/ +``` + +## 更新你的chart仓库 + +您需要保留chart仓库内容的本地副本或使用`gsutil rsync`拷贝远程chart仓库内容到本地目录。 + +例如: + +```console +$ gsutil rsync -d -n gs://bucket-name local-dir/ # the -n flag does a dry run +Building synchronization state... +Starting synchronization +Would copy gs://bucket-name/alpine-0.1.0.tgz to file://local-dir/alpine-0.1.0.tgz +Would copy gs://bucket-name/index.yaml to file://local-dir/index.yaml + +$ gsutil rsync -d gs://bucket-name local-dir/ # performs the copy actions +Building synchronization state... +Starting synchronization +Copying gs://bucket-name/alpine-0.1.0.tgz... +Downloading file://local-dir/alpine-0.1.0.tgz: 740 B/740 B +Copying gs://bucket-name/index.yaml... +Downloading file://local-dir/index.yaml: 346 B/346 B +``` + +帮助链接: + +* [gsutil rsync文档](https://cloud.google.com/storage/docs/gsutil/commands/rsync#description) +* [Chart仓库指南](https://helm.sh/zh/docs/topics/chart_repository) +* Google Cloud Storage的[对象版本控制和并发控制](https://cloud.google.com/storage/docs/gsutil/addlhelp/ObjectVersioningandConcurrencyControl#overview) diff --git a/content/zh/docs/howto/charts_tips_and_tricks.md b/content/zh/docs/howto/charts_tips_and_tricks.md new file mode 100644 index 0000000000..24ec9e652f --- /dev/null +++ b/content/zh/docs/howto/charts_tips_and_tricks.md @@ -0,0 +1,250 @@ +--- +title: "chart开发提示和技巧" +description: "涵盖了Helm chart开发人员在构建产品质量chart时学到的一些提示和技巧" +weight: 1 +--- + +本指南涵盖了Helm chart的开发人员在构建生产环境质量的chart时学到的一些提示和技巧。 + +## 了解你的模板功能 + +Helm使用了[Go模板](https://godoc.org/text/template)将你的自由文件构建成模板。 +Go塑造了一些内置方法,我们增加了一些其他的。 + +首先,我们添加了[Sprig库](https://masterminds.github.io/sprig/)中所有的方法,出于安全原因,“env”和“expandenv”除外。 + +我们也添加了两个特殊的模板方法:`include`和`required`。`include`方法允许你引入另一个模板,并将结果传递给其他模板方法。 + +比如,这个模板片段包含了一个叫`mytpl`的模板,然后将其转成小写,并使用双引号括起来。 + +```yaml +value: {{ include "mytpl" . | lower | quote }} +``` + +`required`方法可以让你声明模板渲染所需的特定值。如果这个值是空的,模板渲染会出错并打印用户提交的错误信息。 + +下面这个`required`方法的例子声明了一个`.Values.who`需要的条目,并且当这个条目不存在时会打印错误信息: + +```yaml +value: {{ required "A valid .Values.who entry required!" .Values.who }} +``` + +## 字符串引号括起来,但整型不用 + +使用字符串数据时,你总是更安全地将字符串括起来而不是露在外面: + +```yaml +name: {{ .Values.MyName | quote }} +``` + +但是使用整型时 _不要把值括起来_。在很多场景中那样会导致Kubernetes内解析失败。 + +```yaml +port: {{ .Values.Port }} +``` + +这个说明不适用于环境变量是字符串的情况,即使表现为整型: + +```yaml +env: + - name: HOST + value: "http://host" + - name: PORT + value: "1234" +``` + +## 使用'include'方法 + +Go提供了一种使用内置模板将一个模板包含在另一个模板中的方法。然而内置方法并不用用于Go模板流水线。 + +为使包含模板成为可能,然后对该模板的输出执行操作,Helm有一个特殊的`include`方法: + +```yaml +{{ include "toYaml" $value | indent 2 }} +``` + +上面这个包含的模板称为`toYaml`,传值给`$value`,然后将这个模板的输出传给`indent`方法。 + +由于YAML将重要性归因于缩进级别和空白,使其在包含代码片段时变成了一种好方法。但是在相关的上下文中要处理缩进。 + +## 使用 'required' 方法 + +Go提供了一种设置模板选项的方法去控制不在映射中的key来索引映射的行为。通常设置为`template.Options("missingkey=option")`, +`option`是`default`,`zero`,或 `error`。 将此项设置为error时会停止执行并出现错误,这会应用到map中的每一个缺失的key中。 +某些情况下chart的开发人员希望在`values.yaml`中选择值强制执行此操作。 + +`required`方法允许开发者声明一个模板渲染需要的值。如果在`values.yaml`中这个值是空的,模板就不会渲染并返回开发者提供的错误信息。 + +例如: + +```yaml +{{ required "A valid foo is required!" .Values.foo }} +``` + +上述示例表示当`.Values.foo`被定义时模板会被渲染,但是未定义时渲染会失败并退出。 + +## 使用'tpl'方法 + +`tpl`方法允许开发者在模板中使用字符串作为模板。将模板字符串作为值传给chart或渲染额外的配置文件时会很有用。 +语法: `{{ tpl TEMPLATE_STRING VALUES }}` + +示例: + +```yaml +# values +template: "{{ .Values.name }}" +name: "Tom" + +# template +{{ tpl .Values.template . }} + +# output +Tom +``` + +渲染额外的配置文件: + +```yaml +# external configuration file conf/app.conf +firstName={{ .Values.firstName }} +lastName={{ .Values.lastName }} + +# values +firstName: Peter +lastName: Parker + +# template +{{ tpl (.Files.Get "conf/app.conf") . }} + +# output +firstName=Peter +lastName=Parker +``` + +## 创建镜像拉取密钥 + +镜像拉取密钥本质上是 _注册表_, _用户名_ 和 _密码_ 的组合。在正在部署的应用程序中你可能需要它, +但创建时需要用`base64`跑一会儿。我们可以写一个辅助模板来编写Docker的配置文件,用来承载密钥。示例如下: + +首先,假定`values.yaml`文件中定义了证书如下: + +```yaml +imageCredentials: + registry: quay.io + username: someone + password: sillyness + email: someone@host.com +``` + +然后定义下面的辅助模板: + +```yaml +{{- define "imagePullSecret" }} +{{- with .Values.imageCredentials }} +{{- printf "{\"auths\":{\"%s\":{\"username\":\"%s\",\"password\":\"%s\",\"email\":\"%s\",\"auth\":\"%s\"}}}" .registry .username .password .email (printf "%s:%s" .username .password | b64enc) | b64enc }} +{{- end }} +{{- end }} +``` + +最终,我们使用辅助模板在更大的模板中创建了密钥清单: + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: myregistrykey +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} +``` + +## 自动滚动部署 + +由于配置映射或密钥作为配置文件注入容器以及其他外部依赖更新导致经常需要滚动部署pod。 +随后的`helm upgrade`更新基于这个应用可能需要重新启动,但如果负载本身没有更改并使用原有配置保持运行,会导致部署不一致。 + +`sha256sum`方法保证在另一个文件发生更改时更新负载说明: + +```yaml +kind: Deployment +spec: + template: + metadata: + annotations: + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} +[...] +``` + +注意:如果要将这些添加到库chart中,就无法使用`$.Template.BasePath`访问你的文件。相反你可以使用 +`{{ include ("mylibchart.configmap") . | sha256sum }}` 引用你的定义。 + +这个场景下你通常想滚动更新你的负载,可以使用类似的说明步骤,而不是使用随机字符串替换,因而经常更改并导致负载滚动更新: + +```yaml +kind: Deployment +spec: + template: + metadata: + annotations: + rollme: {{ randAlphaNum 5 | quote }} +[...] +``` + +每次调用模板方法会生成一个唯一的随机字符串。这意味着如果需要同步多种资源使用的随机字符串,所有的相对资源都要在同一个模板文件中。 + +这两种方法都允许你的部署利用内置的更新策略逻辑来避免停机。 + +注意:过去我们推荐使用`--recreate-pods`参数作为另一个选项。这个参数在Helm 3中不推荐使用,而支持上面更具声明性的方法。 + +## 告诉Helm不要卸载资源 + +有时在执行`helm uninstall`时有些资源不应该被卸载。Chart的开发者可以在资源中添加额外的说明避免被卸载。 + +```yaml +kind: Secret +metadata: + annotations: + "helm.sh/resource-policy": keep +[...] +``` + +(需要引号) + +这个说明`"helm.sh/resource-policy": keep`指示Helm操作(比如`helm uninstall`,`helm upgrade` +或`helm rollback`)要删除时跳过删除这个资源,_然而_,这个资源会变成孤立的。Helm不再以任何方式管理它。 +如果在已经卸载的但保留资源的版本上使用`helm install --replace`会出问题。 + +## 使用"Partials"和模板引用 + +有时你想在chart中创建可以重复利用的部分,不管是块还是局部模板。通常将这些文件保存在自己的文件中会更干净。 + +在`templates/`目录中,任何以下划线(`_`)开始的文件不希望输出到Kubernetes清单文件中。因此按照惯例,辅助模板和局部模板会被放在`_helpers.tpl`文件中。 + +## 使用很多依赖的复杂Chart + +在CNCF的[Artifact Hub](https://artifacthub.io/packages/search?kind=0)中的很多chart是创建更先进应用的“组成部分”。但是chart可能被用于创建大规模应用实例。 +在这种场景中,一个总的chart会有很多子chart,每一个是整体功能的一部分。 + +当前从离散组件组成一个复杂应用的最佳实践是创建一个顶层总体chart构建全局配置,然后使用`charts/`子目录嵌入每个组件。 + +## YAML是JSON的超集 + +根据YAML规范,YAML是JSON的超集。这意味着任意的合法JSON结构在YAML中应该是合法的。 + +这有个优势:有时候模板开发者会发现使用类JSON语法更容易表达数据结构而不是处理YAML的空白敏感度。 + +作为最佳实践,模板应遵循类YAML语法 _除非_ JSON语法大大降低了格式问题的风险。 + +## 生成随机值时留神 + +Helm中有的方法允许你生成随机数据,加密密钥等等。这些很好用,但是在升级,模板重新执行时要注意, +当模板运行与最后一次运行不一样的生成数据时,会触发资源升级。 + +## 一条命令安装或升级版本 + +Helm提供了一种简单命令执行安装或升级的方法。使用`helm upgrade`和`--install`命令,这会是Helm查看是否已经安装版本, +如果没有,会执行安装;如果版本存在,会进行升级 + +```console +$ helm upgrade --install --values +``` diff --git a/content/zh/docs/intro/_index.md b/content/zh/docs/intro/_index.md new file mode 100644 index 0000000000..89b58bbd51 --- /dev/null +++ b/content/zh/docs/intro/_index.md @@ -0,0 +1,8 @@ +--- +title: "介绍" +weight: 1 +--- + +# Helm 介绍 + +Helm 新手从这里开始。 diff --git a/content/zh/docs/intro/install.md b/content/zh/docs/intro/install.md new file mode 100644 index 0000000000..d2cc68a07d --- /dev/null +++ b/content/zh/docs/intro/install.md @@ -0,0 +1,141 @@ +--- +title: "安装Helm" +description: "了解如何安装并运行Helm" +weight: 2 +--- + +该指南展示了如何安装Helm CLI。Helm可以用源码或构建的二进制版本安装。 + +## 用Helm项目安装 + +Helm项目提供了两种获取和安装Helm的方式。这是官方提供的获取Helm发布版本的方法。另外, +Helm社区提供了通过不同包管理器安装Helm的方法。这些方法可以在下面的官方方法之后看到。 + +### 用二进制版本安装 + +每个Helm[版本](https://github.com/helm/helm/releases)都提供了各种操作系统的二进制版本,这些版本可以手动下载和安装。 + +1. 下载[需要的版本](https://github.com/helm/helm/releases) +2. 解压(`tar -zxvf helm-v3.0.0-linux-amd64.tar.gz`) +3. 在解压目录中找到`helm`程序,移动到需要的目录中(`mv linux-amd64/helm /usr/local/bin/helm`) + +然后就可以执行客户端程序并[添加稳定仓库](https://helm.sh/zh/docs/intro/quickstart/#初始化): `helm help`. + +**注意** 针对Linux AMD64,Helm的自动测试只有在CircleCi构建和发布时才会执行。测试其他操作系统是社区针对系统问题请求Helm的责任。 + +### 使用脚本安装 + +Helm现在有个安装脚本可以自动拉取最新的Helm版本并在[本地安装](https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3)。 + +您可以获取这个脚本并在本地执行。它良好的文档会让您在执行之前知道脚本都做了什么。 + +```console +$ curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 +$ chmod 700 get_helm.sh +$ ./get_helm.sh +``` + +如果想直接执行安装,运行`curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 +| bash`。 + +## 通过包管理器安装 + +Helm社区提供了通过操作系统包管理器安装Helm的方式。但Helm项目不支持且不认为是可信的第三方。 + +### 使用Homebrew (macOS) + +Helm社区成员贡献了一种在Homebrew构建Helm的方案,这个方案通常是最新的。 + +```console +brew install helm +``` + +(注意:还有一个emacs-helm的方案,当然这是另一个项目了。) + +### 使用Chocolatey (Windows) + +Helm社区成员贡献了一个[Helm包](https://chocolatey.org/packages/kubernetes-helm)在[Chocolatey](https://chocolatey.org/)中构建, +包通常是最新的。 + +```console +choco install kubernetes-helm +``` + +### 使用Scoop (Windows) + +Helm社区成员贡献了一个针对 [Scoop](https://scoop.sh) 的[Helm包](https://github.com/ScoopInstaller/Main/blob/master/bucket/helm.json),该包通常是最新的。 + +```console +scoop install helm +``` + +### 使用Apt (Debian/Ubuntu) + +Helm社区成员贡献了针对Apt的一个[Helm包](https://helm.baltorepo.com/stable/debian/),包通常是最新的。 + +```console +curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null +sudo apt-get install apt-transport-https --yes +echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list +sudo apt-get update +sudo apt-get install helm +``` + +### 使用 dnf/yum (fedora) + +从Fedora 35开始, 官方仓库可以使用helm了,可以调用以下命令安装helm: + +```console +sudo dnf install helm +``` + +### 使用Snap + +[Snapcrafters](https://github.com/snapcrafters)社区维护了[Helm 包](https://snapcraft.io/helm)的Snap版本: + +```console +sudo snap install helm --classic +``` + +### 使用 pkg (FreeBSD) + +FreeBSD社区成员贡献了一个[Helm页面](https://www.freshports.org/sysutils/helm)来构建[FreeBSD +端口集](https://man.freebsd.org/ports)。通常都是最新的包。 + +```console +pkg install helm +``` + +### 开发版本构建 + +另外您可以下载和安装Helm的开发版本。 + +### 使用Canary构建 + +"Canary"版本是从Helm最新的`main`分支构建。这些不是官方版本,可能不稳定。但是这提供测试边缘特性的条件。 + +Canary Helm二进制包存储在[get.helm.sh](https://get.helm.sh)。以下是一般构建的链接: + +- [Linux AMD64](https://get.helm.sh/helm-canary-linux-amd64.tar.gz) +- [macOS AMD64](https://get.helm.sh/helm-canary-darwin-amd64.tar.gz) +- [实验性Windows AMD64](https://get.helm.sh/helm-canary-windows-amd64.zip) + +### 使用源码Source (Linux, macOS) + +从源码构建Helm的工作要稍微多一点,但如果你想测试最新(预发布)的Helm版本,这是最好的方式。 + +您必须有可用的Go环境。 + +```console +$ git clone https://github.com/helm/helm.git +$ cd helm +$ make +``` + +如果需要,会拉取依赖并缓存,然后验证配置。然后会编译`helm`并放在`bin/helm`。 + +## 总结 + +大多数情况下,安装只需要简单地获取一个构建好的`helm`二进制包。本文档为想使用Helm做更复杂事情的人提供额外示例。 + +一旦你成功安装了Helm客户端,就可以继续使用Helm管理chart和[添加稳定的仓库](https://helm.sh/zh/docs/intro/quickstart/#初始化)。 diff --git a/content/zh/docs/intro/quickstart.md b/content/zh/docs/intro/quickstart.md new file mode 100644 index 0000000000..c142fc0a0b --- /dev/null +++ b/content/zh/docs/intro/quickstart.md @@ -0,0 +1,122 @@ +--- +title: "快速入门指南" +description: "如何安装和开始使用Helm,包括Helm的介绍、FAQs和Helm插件" +weight: 1 +--- + +本指南介绍如何快速开始使用Helm。 + +## 先决条件 + +想成功和正确地使用Helm,需要以下前置条件。 + +1. 一个 Kubernetes 集群 +2. 确定你安装版本的安全配置 +3. 安装和配置Helm。 + +### 安装或者使用现有的Kubernetes集群 + +- 使用Helm,需要一个Kubernetes集群。对于Helm的最新版本,我们建议使用Kubernetes的最新稳定版, + 在大多数情况下,它是倒数第二个次版本。 +- 您也应该有一个本地的 `kubectl`. + +查看Helm和对应支持的Kubernetes版本,您可以参考 [Helm +版本支持策略](https://helm.sh/zh/docs/topics/version_skew/)。 + +## 安装 + +您可以通过 `homebrew` 下载二进制Helm client安装包,也可以通过github下载 [github 官方发布页面](https://github.com/helm/helm/releases) + +除此之外的更多安装方式详见 [安装指南](https://helm.sh/zh/docs/intro/install)。 + +## 初始化 + +当您已经安装好了Helm之后,您可以添加一个chart 仓库。从[Artifact +Hub](https://artifacthub.io/packages/search?kind=0)中查找有效的Helm chart仓库。 + +```console +$ helm repo add bitnami https://charts.bitnami.com/bitnami +``` + +当添加完成,您将可以看到可以被您安装的charts列表: + +```console +$ helm search repo bitnami +NAME CHART VERSION APP VERSION DESCRIPTION +bitnami/bitnami-common 0.0.9 0.0.9 DEPRECATED Chart with custom templates used in ... +bitnami/airflow 8.0.2 2.0.0 Apache Airflow is a platform to programmaticall... +bitnami/apache 8.2.3 2.4.46 Chart for Apache HTTP Server +bitnami/aspnet-core 1.2.3 3.1.9 ASP.NET Core is an open-source framework create... +# ... and many more +``` + +## 安装Chart示例 + +您可以通过`helm install` 命令安装chart。 Helm可以通过多种途径查找和安装chart, +但最简单的是安装官方的`bitnami` charts。 + +```console +$ helm repo update # 确定我们可以拿到最新的charts列表 +$ helm install bitnami/mysql --generate-name +NAME: mysql-1612624192 +LAST DEPLOYED: Sat Feb 6 16:09:56 2021 +NAMESPACE: default +STATUS: deployed +REVISION: 1 +TEST SUITE: None +NOTES: ... +``` + +在上面的例子中,`bitnami/mysql`这个chart被发布,名字是 `mysql-1612624192` + +您可以通过执行 `helm show chart bitnami/mysql` 命令简单的了解到这个chart的基本信息。 +或者您可以执行 `helm show all bitnami/mysql` 获取关于该chart的所有信息。 + +每当您执行 `helm install` 的时候,都会创建一个新的发布版本。 +所以一个chart在同一个集群里面可以被安装多次,每一个都可以被独立的管理和升级。 + +`helm install` 是一个拥有很多能力的强大的命令,更多信息详见 [使用 Helm](https://helm.sh/zh/docs/intro/using_helm) + +## 关于版本发布 + +通过Helm您可以很容易看到哪些chart被发布了: + +```console +$ helm list +NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION +mysql-1612624192 default 1 2021-02-06 16:09:56.283059 +0100 CET deployed mysql-8.3.0 8.0.23 +``` + +`helm list` (或 `helm ls`) 命令会列出所有可被部署的版本。 + +## 卸载一个版本 + +您可以使用`helm uninstall` 命令卸载你的版本 + +```console +$ helm uninstall mysql-1612624192 +release "mysql-1612624192" uninstalled +``` + +该命令会从Kubernetes卸载 `mysql-1612624192`, 它将删除和该版本相关的所有相关资源(service、deployment、 +pod等等)甚至版本历史。 + +如果您在执行 `helm uninstall` 的时候提供 `--keep-history` 选项, Helm将会保存版本历史。 +您可以通过命令查看该版本的信息 + +```console +$ helm status mysql-1612624192 +Status: UNINSTALLED +... +``` + +因为 `--keep-history` 选项会让helm跟踪你的版本(即使你卸载了他们), 所以你可以审计集群历史甚至使用 +`helm rollback` 回滚版本。 + +## 查看帮助信息 + +如果您想通过Helm命令查看更多的有用的信息,请使用 `helm help` 命令,或者在任意命令后添加 `-h` 选项: + +```console +$ helm get -h +``` diff --git a/content/zh/docs/intro/using_helm.md b/content/zh/docs/intro/using_helm.md new file mode 100644 index 0000000000..848bc5c85d --- /dev/null +++ b/content/zh/docs/intro/using_helm.md @@ -0,0 +1,479 @@ +--- +title: "使用Helm" +description: "解释 Helm 的基础知识。" +weight: 3 +--- + +本指南介绍了使用 Helm 来管理 Kubernetes 集群上的软件包的基础知识。在这之前,假定您已经 +[安装](https://helm.sh/zh/docs/intro/install)了 Helm 客户端。 + +如果您仅对运行一些快速命令感兴趣,则不妨从[快速入门指南](https://helm.sh/zh/docs/intro/quickstart)开始。本章包含了 +Helm 命令的详细说明,并解释如何使用 Helm。 + +## 三大概念 + +*Chart* 代表着 Helm 包。它包含在 Kubernetes 集群内部运行应用程序,工具或服务所需的所有资源定义。你可以把它看作是 +Homebrew formula,Apt dpkg,或 Yum RPM 在Kubernetes 中的等价物。 + +*Repository(仓库)* 是用来存放和共享 charts 的地方。它就像 Perl 的 [CPAN 档案库网络](https://www.cpan.org) +或是 Fedora 的[软件包仓库](https://src.fedoraproject.org/),只不过它是供 Kubernetes 包所使用的。 + +*Release* 是运行在 Kubernetes 集群中的 chart 的实例。一个 chart 通常可以在同一个集群中安装多次。每一次安装都会创建一个新的 +_release_。以 MySQL chart为例,如果你想在你的集群中运行两个数据库,你可以安装该chart两次。每一个数据库都会拥有它自己的 +_release_ 和 _release name_。 + +在了解了上述这些概念以后,我们就可以这样来解释 Helm: + +Helm 安装 _charts_ 到 Kubernetes 集群中,每次安装都会创建一个新的 _release_。你可以在 Helm 的 +chart _repositories_ 中寻找新的 chart。 + +## 'helm search':查找 Charts + +Helm 自带一个强大的搜索命令,可以用来从两种来源中进行搜索: + +- `helm search hub` 从 [Artifact Hub](https://artifacthub.io) 中查找并列出 helm charts。 + Artifact Hub中存放了大量不同的仓库。 +- `helm search repo` 从你添加(使用 `helm repo add`)到本地 helm 客户端中的仓库中进行查找。该命令基于本地数据进行搜索,无需连接互联网。 + +你可以通过运行 `helm search hub` 命令找到公开可用的charts: + +```console +$ helm search hub wordpress +URL CHART VERSION APP VERSION DESCRIPTION +https://hub.helm.sh/charts/bitnami/wordpress 7.6.7 5.2.4 Web publishing platform for building blogs and ... +https://hub.helm.sh/charts/presslabs/wordpress-... v0.6.3 v0.6.3 Presslabs WordPress Operator Helm Chart +https://hub.helm.sh/charts/presslabs/wordpress-... v0.7.1 v0.7.1 A Helm chart for deploying a WordPress site on ... +``` + +上述命令从 Artifact Hub 中搜索所有的 `wordpress` charts。 + +如果不进行过滤,`helm search hub` 命令会展示所有可用的 charts。 + +使用 `helm search repo` 命令,你可以从你所添加的仓库中查找chart的名字。 + +```console +$ helm repo add brigade https://brigadecore.github.io/charts +"brigade" has been added to your repositories +$ helm search repo brigade +NAME CHART VERSION APP VERSION DESCRIPTION +brigade/brigade 1.3.2 v1.2.1 Brigade provides event-driven scripting of Kube... +brigade/brigade-github-app 0.4.1 v0.2.1 The Brigade GitHub App, an advanced gateway for... +brigade/brigade-github-oauth 0.2.0 v0.20.0 The legacy OAuth GitHub Gateway for Brigade +brigade/brigade-k8s-gateway 0.1.0 A Helm chart for Kubernetes +brigade/brigade-project 1.0.0 v1.0.0 Create a Brigade project +brigade/kashti 0.4.0 v0.4.0 A Helm chart for Kubernetes +``` + +Helm 搜索使用模糊字符串匹配算法,所以你可以只输入名字的一部分: + +```console +$ helm search repo kash +NAME CHART VERSION APP VERSION DESCRIPTION +brigade/kashti 0.4.0 v0.4.0 A Helm chart for Kubernetes +``` + +搜索是用来发现可用包的一个好办法。一旦你找到你想安装的 helm 包,你便可以通过使用 `helm install` 命令来安装它。 + +## 'helm install':安装一个 helm 包 + +使用 `helm install` 命令来安装一个新的 helm 包。最简单的使用方法只需要传入两个参数:你命名的release名字和你想安装的chart的名称。 + +```console +$ helm install happy-panda bitnami/wordpress +NAME: happy-panda +LAST DEPLOYED: Tue Jan 26 10:27:17 2021 +NAMESPACE: default +STATUS: deployed +REVISION: 1 +NOTES: +** Please be patient while the chart is being deployed ** + +Your WordPress site can be accessed through the following DNS name from within your cluster: + + happy-panda-wordpress.default.svc.cluster.local (port 80) + +To access your WordPress site from outside the cluster follow the steps below: + +1. Get the WordPress URL by running these commands: + + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + Watch the status with: 'kubectl get svc --namespace default -w happy-panda-wordpress' + + export SERVICE_IP=$(kubectl get svc --namespace default happy-panda-wordpress --template "{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}") + echo "WordPress URL: http://$SERVICE_IP/" + echo "WordPress Admin URL: http://$SERVICE_IP/admin" + +2. Open a browser and access WordPress using the obtained URL. + +3. Login with the following credentials below to see your blog: + + echo Username: user + echo Password: $(kubectl get secret --namespace default happy-panda-wordpress -o jsonpath="{.data.wordpress-password}" | base64 --decode) + +``` + +现在`wordpress` chart 已经安装。注意安装chart时创建了一个新的 _release_ 对象。上述发布被命名为 `happy-panda`。 +(如果想让Helm生成一个名称,删除发布名称并使用`--generate-name`。) + +在安装过程中,`helm` 客户端会打印一些有用的信息,其中包括:哪些资源已经被创建,release当前的状态,以及你是否还需要执行额外的配置步骤。 + +Helm按照以下顺序安装资源: + +- Namespace +- NetworkPolicy +- ResourceQuota +- LimitRange +- PodSecurityPolicy +- PodDisruptionBudget +- ServiceAccount +- Secret +- SecretList +- ConfigMap +- StorageClass +- PersistentVolume +- PersistentVolumeClaim +- CustomResourceDefinition +- ClusterRole +- ClusterRoleList +- ClusterRoleBinding +- ClusterRoleBindingList +- Role +- RoleList +- RoleBinding +- RoleBindingList +- Service +- DaemonSet +- Pod +- ReplicationController +- ReplicaSet +- Deployment +- HorizontalPodAutoscaler +- StatefulSet +- Job +- CronJob +- Ingress +- APIService + +Helm 客户端不会等到所有资源都运行才退出。许多 charts 需要大小超过 600M 的 Docker 镜像,可能需要很长时间才能安装到集群中。 + +你可以使用 `helm status` 来追踪 release 的状态,或是重新读取配置信息: + +```console +$ helm status happy-panda +NAME: happy-panda +LAST DEPLOYED: Tue Jan 26 10:27:17 2021 +NAMESPACE: default +STATUS: deployed +REVISION: 1 +NOTES: +** Please be patient while the chart is being deployed ** + +Your WordPress site can be accessed through the following DNS name from within your cluster: + + happy-panda-wordpress.default.svc.cluster.local (port 80) + +To access your WordPress site from outside the cluster follow the steps below: + +1. Get the WordPress URL by running these commands: + + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + Watch the status with: 'kubectl get svc --namespace default -w happy-panda-wordpress' + + export SERVICE_IP=$(kubectl get svc --namespace default happy-panda-wordpress --template "{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}") + echo "WordPress URL: http://$SERVICE_IP/" + echo "WordPress Admin URL: http://$SERVICE_IP/admin" + +2. Open a browser and access WordPress using the obtained URL. + +3. Login with the following credentials below to see your blog: + + echo Username: user + echo Password: $(kubectl get secret --namespace default happy-panda-wordpress -o jsonpath="{.data.wordpress-password}" | base64 --decode) +``` + +上述信息展示了 release 的当前状态。 + +### 安装前自定义 chart + +上述安装方式只会使用 chart 的默认配置选项。很多时候,我们需要自定义 chart 来指定我们想要的配置。 + +使用 `helm show values` 可以查看 chart 中的可配置选项: + +```console +$ helm show values bitnami/wordpress +## Global Docker image parameters +## Please, note that this will override the image parameters, including dependencies, configured to use the global value +## Current available global Docker image parameters: imageRegistry and imagePullSecrets +## +# global: +# imageRegistry: myRegistryName +# imagePullSecrets: +# - myRegistryKeySecretName +# storageClass: myStorageClass + +## Bitnami WordPress image version +## ref: https://hub.docker.com/r/bitnami/wordpress/tags/ +## +image: + registry: docker.io + repository: bitnami/wordpress + tag: 5.6.0-debian-10-r35 + [..] +``` + +然后,你可以使用 YAML 格式的文件覆盖上述任意配置项,并在安装过程中使用该文件。 + +```console +$ echo '{mariadb.auth.database: user0db, mariadb.auth.username: user0}' > values.yaml +$ helm install -f values.yaml bitnami/wordpress --generate-name +``` + +上述命令将为 MariaDB 创建一个名称为 `user0` 的默认用户,并且授予该用户访问新建的 `user0db` 数据库的权限。chart 中的其他默认配置保持不变。 + +安装过程中有两种方式传递配置数据: + +- `--values` (或 `-f`):使用 YAML 文件覆盖配置。可以指定多次,优先使用最右边的文件。 +- `--set`:通过命令行的方式对指定项进行覆盖。 + +如果同时使用两种方式,则 `--set` 中的值会被合并到 `--values` 中,但是 `--set` 中的值优先级更高。在`--set` +中覆盖的内容会被被保存在 ConfigMap 中。可以通过 `helm get values ` 来查看指定 release 中 +`--set` 设置的值。也可以通过运行 `helm upgrade` 并指定 `--reset-values` 字段来清除 `--set` 中设置的值。 + +#### `--set` 的格式和限制 + +`--set` 选项使用0或多个 name/value 对。最简单的用法类似于:`--set name=value`,等价于如下 YAML 格式: + +```yaml +name: value +``` + +多个值使用逗号分割,因此 `--set a=b,c=d` 的 YAML 表示是: + +```yaml +a: b +c: d +``` + +支持更复杂的表达式。例如,`--set outer.inner=value` 被转换成了: + +```yaml +outer: + inner: value +``` + +列表使用花括号(`{}`)来表示。例如,`--set name={a, b, c}` 被转换成了: + +```yaml +name: + - a + - b + - c +``` + +某些name/key可以设置为`null`或者空数组,例如 `--set name=[],a=null` 由 + +```yaml +name: + - a + - b + - c +a: b +``` + +变成了 + +```yaml +name: [] +a: null +``` + +从 2.5.0 版本开始,可以使用数组下标的语法来访问列表中的元素。例如 `--set servers[0].port=80` 就变成了: + +```yaml +servers: + - port: 80 +``` + +多个值也可以通过这种方式来设置。`--set servers[0].port=80,servers[0].host=example` 变成了: + +```yaml +servers: + - port: 80 + host: example +``` + +如果需要在 `--set` 中使用特殊字符,你可以使用反斜线来进行转义;`--set name=value1\,value2` 就变成了: + +```yaml +name: "value1,value2" +``` + +类似的,你也可以转义点序列(英文句号)。这可能会在 chart 使用 `toYaml` 函数来解析 annotations,labels,和 +node selectors 时派上用场。`--set nodeSelector."kubernetes\.io/role"=master` 语法就变成了: + +```yaml +nodeSelector: + kubernetes.io/role: master +``` + +深层嵌套的数据结构可能会很难用 `--set` 表达。我们希望 Chart 的设计者们在设计 `values.yaml` 文件的格式时,考虑到 `--set` +的使用。(更多内容请查看 [Values 文件](https://helm.sh/docs/chart_template_guide/values_files/)) + +### 更多安装方法 + +`helm install` 命令可以从多个来源进行安装: + +- chart 的仓库(如上所述) +- 本地 chart 压缩包(`helm install foo foo-0.1.1.tgz`) +- 解压后的 chart 目录(`helm install foo path/to/foo`) +- 完整的 URL(`helm install foo https://example.com/charts/foo-1.2.3.tgz`) + +## 'helm upgrade' 和 'helm rollback':升级 release 和失败时恢复 + +当你想升级到 chart 的新版本,或是修改 release 的配置,你可以使用 `helm upgrade` 命令。 + +一次升级操作会使用已有的 release 并根据你提供的信息对其进行升级。由于 Kubernetes 的 chart +可能会很大而且很复杂,Helm 会尝试执行最小侵入式升级。即它只会更新自上次发布以来发生了更改的内容。 + +```console +$ helm upgrade -f panda.yaml happy-panda bitnami/wordpress +``` + +在上面的例子中,`happy-panda` 这个 release 使用相同的 chart 进行升级,但是使用了一个新的 YAML 文件: + +```yaml +mariadb.auth.username: user1 +``` + +我们可以使用 `helm get values` 命令来看看配置值是否真的生效了: + +```console +$ helm get values happy-panda +mariadb: + auth: + username: user1 +``` + +`helm get` 是一个查看集群中 release 的有用工具。正如我们上面所看到的,`panda.yaml` 中的新值已经被部署到集群中了。 + +现在,假如在一次发布过程中,发生了不符合预期的事情,也很容易通过 `helm rollback [RELEASE] [REVISION]` 命令回滚到之前的发布版本。 + +```console +$ helm rollback happy-panda 1 +``` + +上面这条命令将我们的 `happy-panda` 回滚到了它最初的版本。release 版本其实是一个增量修订(revision)。 +每当发生了一次安装、升级或回滚操作,revision 的值就会加1。第一次 revision 的值永远是1。我们可以使用 +`helm history [RELEASE]` 命令来查看一个特定 release 的修订版本号。 + +## 安装、升级、回滚时的有用选项 + +你还可以指定一些其他有用的选项来自定义 Helm 在安装、升级、回滚期间的行为。请注意这并不是 cli 参数的完整列表。 +要查看所有参数的说明,请执行 `helm --help` 命令。 + +- `--timeout`:一个 [Go duration](https://golang.org/pkg/time/#ParseDuration) 类型的值, + 用来表示等待 Kubernetes 命令完成的超时时间,默认值为 `5m0s`。 +- `--wait`:表示必须要等到所有的 Pods 都处于 ready 状态,PVC 都被绑定,Deployments 都至少拥有最小 ready 状态 + Pods 个数(`Desired`减去 `maxUnavailable`),并且 Services 都具有 IP 地址(如果是`LoadBalancer`, + 则为 Ingress),才会标记该 release 为成功。最长等待时间由 `--timeout` 值指定。如果达到超时时间,release 将被标记为 + `FAILED`。注意:当 Deployment 的 `replicas` 被设置为1,但其滚动升级策略中的 `maxUnavailable` + 没有被设置为0时,`--wait` 将返回就绪,因为已经满足了最小 ready Pod 数。 +- `--no-hooks`:不运行当前命令的钩子。 +- `--recreate-pods`(仅适用于 `upgrade` 和 `rollback`):这个参数会导致重建所有的 + Pod(deployment中的Pod 除外)。(在 Helm 3 中已被废弃) + +## 'helm uninstall':卸载 release + +使用 `helm uninstall` 命令从集群中卸载一个 release: + +```console +$ helm uninstall happy-panda +``` + +该命令将从集群中移除指定 release。你可以通过 `helm list` 命令看到当前部署的所有 release: + +```console +$ helm list +NAME VERSION UPDATED STATUS CHART +inky-cat 1 Wed Sep 28 12:59:46 2016 DEPLOYED alpine-0.1.0 +``` + +从上面的输出中,我们可以看到,`happy-panda` 这个 release 已经被卸载。 + +在上一个 Helm 版本中,当一个 release 被删除,会保留一条删除记录。而在 Helm 3 中,删除也会移除 release 的记录。 +如果你想保留删除记录,使用 `helm uninstall --keep-history`。使用 `helm list --uninstalled` +只会展示使用了 `--keep-history` 删除的 release。 + +`helm list --all` 会展示 Helm 保留的所有 release 记录,包括失败或删除的条目(指定了 `--keep-history`): + +```console +$ helm list --all +NAME VERSION UPDATED STATUS CHART +happy-panda 2 Wed Sep 28 12:47:54 2016 UNINSTALLED wordpress-10.4.5.6.0 +inky-cat 1 Wed Sep 28 12:59:46 2016 DEPLOYED alpine-0.1.0 +kindred-angelf 2 Tue Sep 27 16:16:10 2016 UNINSTALLED alpine-0.1.0 +``` + +注意,因为现在默认会删除 release,所以你不再能够回滚一个已经被卸载的资源了。 + +## 'helm repo':使用仓库 + +Helm 3 不再附带一个默认的 chart 仓库。`helm repo` 提供了一组命令用于添加、列出和移除仓库。 + +使用 `helm repo list` 来查看配置的仓库: + +```console +$ helm repo list +NAME URL +stable https://charts.helm.sh/stable +mumoshu https://mumoshu.github.io/charts +``` + +使用 `helm repo add` 来添加新的仓库: + +```console +$ helm repo add dev https://example.com/dev-charts +``` + +因为 chart 仓库经常在变化,在任何时候你都可以通过执行 `helm repo update` 命令来确保你的 Helm 客户端是最新的。 + +使用 `helm repo remove` 命令来移除仓库。 + +## 创建你自己的 charts + +[chart 开发指南](https://helm.sh/zh/docs/topics/charts) 介绍了如何开发你自己的chart。 但是你也可以通过使用 +`helm create` 命令来快速开始: + +```console +$ helm create deis-workflow +Creating deis-workflow +``` + +现在,`./deis-workflow` 目录下已经有一个 chart 了。你可以编辑它并创建你自己的模版。 + +在编辑 chart 时,可以通过 `helm lint` 验证格式是否正确。 + +当准备将 chart 打包分发时,你可以运行 `helm package` 命令: + +```console +$ helm package deis-workflow +deis-workflow-0.1.0.tgz +``` + +然后这个 chart 就可以很轻松的通过 `helm install` 命令安装: + +```console +$ helm install deis-workflow ./deis-workflow-0.1.0.tgz +... +``` + +打包好的 chart 可以上传到 chart 仓库中。查看[Helm chart 仓库](https://helm.sh/zh/docs/topics/chart_repository)获取更多信息。 + +## 总结 + +这一章介绍了 `helm` 客户端的基本使用方式,包括搜索,安装,升级,和卸载。也涵盖了一些有用的工具类命令,如`helm status`, +`helm get`,和 `helm repo`。 + +有关这些命令的更多信息,请查看 Helm 的内置帮助命令:`helm help`。 + +在下一章中,我们来看一下如何开发 charts。 diff --git a/content/zh/docs/topics/_index.md b/content/zh/docs/topics/_index.md new file mode 100644 index 0000000000..abc829a145 --- /dev/null +++ b/content/zh/docs/topics/_index.md @@ -0,0 +1,8 @@ +--- +title: "主题" +weight: 3 +--- + +# 主题指引 + +这里可以找到所有您想知道的Helm的关键部分说明。 diff --git a/content/zh/docs/topics/advanced.md b/content/zh/docs/topics/advanced.md new file mode 100644 index 0000000000..a6f8931bdd --- /dev/null +++ b/content/zh/docs/topics/advanced.md @@ -0,0 +1,167 @@ +--- +title: "Helm高级技术" +description: "为Helm的高级用户说明各种高级特性" +weight: 9 +--- + +这部分解释说明了使用Helm的各种高级特性和技术。 +这部分旨在为Helm的高级用户提供高度自定义和操作chart及发布的信息。每个高级特性都会有它自己的权衡利弊, +因此每个使用它们的都要有Helm的深度知识并小心使用。或者换言之, +谨记 [Peter Parker 原则](https://en.wikipedia.org/wiki/With_great_power_comes_great_responsibility) + +## 后置渲染 +后置渲染允许在通过Helm安装chart之前手动使用、配置或者验证渲染的manifest。 +这允许有高级配置需求的用户可以使用诸如[`kustomize`](https://kustomize.io) 来配置更改而不需要fork一个公共 +chart或要求chart维护人员为每个软件指定每个最新的配置项。 +这里同样有一些示例用来在企业环境中注入常用工具和sidecar或者在部署前对manifest进行分析。 + +### 前提条件 +- Helm 3.1+ + +### 使用 +后置渲染器是在STDIN能够接受渲染后的Kubernetes manifest并能在STDOUT返回有效的Kubernetes manifest, +可以是任意可执行文件。它应该在出现失败事件时返回非0退出码。这是两个组件之间的唯一API。允许在你的后置渲染过程中有很好的灵活性。 + +后置渲染器可以和`install`、`upgrade`以及`template`一起使用。使用后置渲染器时,使用`--post-renderer` +参数并指定要使用的渲染器可执行文件的路径: + +```shell +$ helm install mychart stable/wordpress --post-renderer ./path/to/executable +``` + +如果路径中不包含任何分隔符,就会在$PATH中搜索,否则就会把相对路径转换成全路径。 + +如果需要使用多个后置渲染器,在一个脚本中调用它们,或者在构建任何二进制工具时调用它们。 +在bash中,就像 `renderer1 | renderer2 | renderer3` 一样简单。 + +你可以在 [这里](https://github.com/thomastaylor312/advanced-helm-demos/tree/master/post-render) +查看作为一个后置渲染器使用 `kustomize` 的示例。 + +### 警告 +在使用后置渲染器时,以下这些事需要注意:使用后置渲染器时最重要的是, +所有人在修改版本时**必须** 使用同样的渲染器来保证可重复的构建。 +这个功能是专门为允许任何用户切换他们正在使用或停止使用的渲染器而构建的, 但是这个应该谨慎操作,以避免意外修改或数据丢失。 + +另一个重要的注意事项就是安全,如果您正在使用一个后置渲染器,要保证它来自一个可信源(对于其他任意可执行文件也是如此)。 +不推荐使用不可靠的或者未核实的可访问所有渲染器模板的渲染器,渲染器模板经常会包含隐私数据。 + +### 自定义后置渲染 +使用Go SDK时后置渲染器甚至可以提供更多的灵活性。任意后置渲染器只需要执行下面的Go接口: + +```go +type PostRenderer interface { + // Run expects a single buffer filled with Helm rendered manifests. It + // expects the modified results to be returned on a separate buffer or an + // error if there was an issue or failure while running the post render step + Run(renderedManifests *bytes.Buffer) (modifiedManifests *bytes.Buffer, err error) +} +``` + +有关Go SDK的更多信息,请查看 [Go SDK 部分](#go-sdk) + +## Go SDK +Helm 3 首次发布了完全重组的Go SDK,以便在构建利用Helm的软件和工具时有更好的体验。完整的文档可以在 [https://pkg.go.dev/helm.sh/helm/v3](https://pkg.go.dev/helm.sh/helm/v3) 查看,下面将要简要介绍一些常用的软件包和一个简单的示例。 + +### 包概览 +对每个最常用的包的简要说明列表: + +- `pkg/action`: 包含执行Helm操作的主要客户端。和CLI处理过程中使用的是同一个包。如果你仅仅需要执行来自另一个Go程序的最基本的Helm命令,这个包会很适合你 +- `pkg/{chart,chartutil}`: 加载和控制chart时使用的方法和帮助内容 +- `pkg/cli` 和它的子包: 包含标准Helm环境变量所有的处理程序以及子包涵盖了输出和正在处理的value文件 +- `pkg/release`: 定义了 `Release` 对象和状态值 + +显然除了这些还有更多的包,查看SDK文档获取更多内容! + +### 简要示例 +这是一个使用Go SDK的 `helm list` 的简单示例: + +```go +package main + +import ( + "log" + "os" + + "helm.sh/helm/v3/pkg/action" + "helm.sh/helm/v3/pkg/cli" +) + +func main() { + settings := cli.New() + + actionConfig := new(action.Configuration) + // You can pass an empty string instead of settings.Namespace() to list + // all namespaces + if err := actionConfig.Init(settings.RESTClientGetter(), settings.Namespace(), os.Getenv("HELM_DRIVER"), log.Printf); err != nil { + log.Printf("%+v", err) + os.Exit(1) + } + + client := action.NewList(actionConfig) + // Only list deployed + client.Deployed = true + results, err := client.Run() + if err != nil { + log.Printf("%+v", err) + os.Exit(1) + } + + for _, rel := range results { + log.Printf("%+v", rel) + } +} + +``` + +## 后端存储 + +Helm 3 改变了存储命名空间版本秘钥的默认版本信息。Helm 2 默认将版本信息作为ConfigMap存储在命名空间的Tiller实例中。 +下面小节部分会演示如果配置不同的后端。配置是基于 `HELM_DRIVER` 环境变量。它会被设置成这几个值其中之一:`[configmap, secret, sql]`。 + +### ConfigMap 后端存储 + +要使ConfigMap 后端生效, 你需要在 `configmap` 设置环境变量 `HELM_DRIVER`。 + +你可以在shell中类似下面这样设置: + +```shell +export HELM_DRIVER=configmap +``` + +如果你想从默认后端切到ConfigMap后端,你必须自己进行迁移。你可以使用以下命令找回版本信息: + +```shell +kubectl get secret --all-namespaces -l "owner=helm" +``` + +**产品说明**: 发布信息包含chart和values文件的内容,因此可能包含敏感数据(比如密码,私钥,和其他认证)需要防止未经授权访问。 管理Kubernetes授权时使用 [RBAC](https://kubernetes.io/docs/reference/access-authn-authz/rbac/), 当限制访问私密资源是,它可能会授予ConfigMap 资源广泛的访问权限。对于实例,默认的 [面向用户角色](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#user-facing-roles) “视图” 授予大多数资源的访问权限,但是不允许访问私密数据。此外,私密数据会针对于 [加密存储](https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/) 进行配置。切换到ConfigMap后端时要记得这一点,因为它可能会暴露你应用程序的敏感数据。 + +### SQL 后台存储 + +这是个 ***beta*** 版SQL存储后端,在SQL数据库中存储了版本信息。 + +如果你的版本信息内容超过1MB这种存储后端会特别有用(在这种场景中,它无法存储在ConfigMaps/Secrets中,因为Kubernetes内部的etcd key-value存储有限制。 + +要启用SQL后端,你需要部署SQL数据库并设置环境变量`HELM_DRIVER`到`sql`。DB的细节用环境变量`HELM_DRIVER_SQL_CONNECTION_STRING`设置。 + +你可以在shell中设置如下: + +```shell +export HELM_DRIVER=sql +export HELM_DRIVER_SQL_CONNECTION_STRING=postgresql://helm-postgres:5432/helm?user=helm&password=changeme +``` + +> 注意:目前只支持PostgreSQL。 + +**产品说明**: 建议如下: + +- 确保你的数据库产品可以使用。对于PostgreSQL,请参考 +[Server Administration](https://www.postgresql.org/docs/12/admin.html) 文档了解更多细节内容 +- 为版本信息启用 [权限管理](https://helm.sh/zh/docs/topics/permissions_sql_storage_backend/)镜像到 +Kubernetes RBAC + +如果你想从默认后端切到SQL后端,你必须自己完成迁移,你可以使用以下命令找回版本信息: + +```shell +kubectl get secret --all-namespaces -l "owner=helm" +``` diff --git a/content/zh/docs/topics/architecture.md b/content/zh/docs/topics/architecture.md new file mode 100644 index 0000000000..9f69b8c554 --- /dev/null +++ b/content/zh/docs/topics/architecture.md @@ -0,0 +1,55 @@ +--- +title: "Helm 架构" +description: "Describes the Helm architecture at a high level." +weight: 8 +--- + +# Helm 架构 + +本文从较高的层次描述Helm的体系结构。 + +## Helm的目标 + +Helm管理名为chart的Kubernetes包的工具。Helm可以做以下的事情: + +- 从头开始创建新的chart +- 将chart打包成归档(tgz)文件 +- 与存储chart的仓库进行交互 +- 在现有的Kubernetes集群中安装和卸载chart +- 管理与Helm一起安装的chart的发布周期 + +对于Helm,有三个重要的概念: + +1. _chart_ 创建Kubernetes应用程序所必需的一组信息。 +2. _config_ 包含了可以合并到打包的chart中的配置信息,用于创建一个可发布的对象。 +3. _release_ 是一个与特定配置相结合的chart的运行实例。 + +## 组件 + +Helm是一个可执行文件,执行时分成两个不同的部分: + +**Helm客户端** 是终端用户的命令行客户端。负责以下内容: + +- 本地chart开发 +- 管理仓库 +- 管理发布 +- 与Helm库建立接口 + - 发送安装的chart + - 发送升级或卸载现有发布的请求 + +**Helm库** 提供执行所有Helm操作的逻辑。与Kubernetes API服务交互并提供以下功能: + +- 结合chart和配置来构建版本 +- 将chart安装到Kubernetes中,并提供后续发布对象 +- 与Kubernetes交互升级和卸载chart + +独立的Helm库封装了Helm逻辑以便不同的客户端可以使用它。 + +## 执行 + +Helm客户端和库是使用Go编程语言编写的 + +这个库使用Kubernetes客户端库与Kubernetes通信。现在,这个库使用REST+JSON。它将信息存储在Kubernetes的密钥中。 +不需要自己的数据库。 + +如果可能,配置文件是用YAML编写的。 diff --git a/content/zh/docs/topics/chart_repository.md b/content/zh/docs/topics/chart_repository.md new file mode 100644 index 0000000000..701a7adf1b --- /dev/null +++ b/content/zh/docs/topics/chart_repository.md @@ -0,0 +1,255 @@ +--- +title: "Chart仓库指南" +description: "如何创建和使用Helm chart 仓库" +weight: 6 +--- + +本节介绍如何创建和使用chart仓库。在高层级中,chart仓库是打包的chart存储和分享的位置。 + +社区的Helm chart仓库位于[Artifact Hub](https://artifacthub.io/packages/search?kind=0),欢迎加入。 +不过Helm也可以创建并运行你自己的chart仓库。该指南将介绍如何操作。 + +## 先决条件 + +* 先阅读[快速开始](https://helm.sh/zh/docs/intro/quickstart/) +* 阅读[Charts](https://helm.sh/zh/docs/topics/charts/)文档 + +## 创建一个chart仓库 + +_chart仓库_ 是一个配置了`index.yaml`文件和一些已经打包chart的HTTP服务器。当你准备好分享chart时,最好的方法是将chart上传到chart仓库。 + +**注意:** 从Helm 2.2.0开始,客户端支持对仓库进行SSL身份认证。其他身份验证协议可以通过插件提供。 + +由于chart仓库可以是任何服务于YAML和tar文件并响应GET请求的HTTP服务器,托管你自己的chart仓库时就有很多选择。比如可以使用Google +Cloud Storage(GCS), Amazon S3,GitHub页面,甚至创建自己的web服务器。 + +### chart仓库结构 + +chart仓库由chart包和包含了仓库中所有chart索引的特殊文件`index.yaml`。 +通常描述chart的`index.yaml`也托管在同一个服务器上作为[来源文件](https://helm.sh/zh/docs/topics/provenance/)。 + +比如,`https://example.com/charts`仓库布局可能看起来像这样: + +```console +charts/ + | + |- index.yaml + | + |- alpine-0.1.2.tgz + | + |- alpine-0.1.2.tgz.prov +``` + +在这个案例中,index文件包含了Alpine这一个chart的信息,并提供了下载地址:`https://example.com/charts/alpine-0.1.2.tgz`。 + +`index.yaml`文件不是必须和chart包放在同一个服务器上,但是这样是最方便的。 + +### index文件 + +`index.yaml`文件是一个yaml格式的文件。包含了一些包的元信息,包括chart中`Chart.yaml`文件的内容。 +一个合法的chart仓库必须有一个index文件,包含了chart仓库中每一个chart的信息。 +`helm repo index`命令会基于给定的包含chart包的本地目录生成一个index文件。 + +index文件类似于这样: + +```yaml +apiVersion: v1 +entries: + alpine: + - created: 2016-10-06T16:23:20.499814565-06:00 + description: Deploy a basic Alpine Linux pod + digest: 99c76e403d752c84ead610644d4b1c2f2b453a74b921f422b9dcb8a7c8b559cd + home: https://helm.sh/helm + name: alpine + sources: + - https://github.com/helm/helm + urls: + - https://technosophos.github.io/tscharts/alpine-0.2.0.tgz + version: 0.2.0 + - created: 2016-10-06T16:23:20.499543808-06:00 + description: Deploy a basic Alpine Linux pod + digest: 515c58e5f79d8b2913a10cb400ebb6fa9c77fe813287afbacf1a0b897cd78727 + home: https://helm.sh/helm + name: alpine + sources: + - https://github.com/helm/helm + urls: + - https://technosophos.github.io/tscharts/alpine-0.1.0.tgz + version: 0.1.0 + nginx: + - created: 2016-10-06T16:23:20.499543808-06:00 + description: Create a basic nginx HTTP server + digest: aaff4545f79d8b2913a10cb400ebb6fa9c77fe813287afbacf1a0b897cdffffff + home: https://helm.sh/helm + name: nginx + sources: + - https://github.com/helm/charts + urls: + - https://technosophos.github.io/tscharts/nginx-1.1.0.tgz + version: 1.1.0 +generated: 2016-10-06T16:23:20.499029981-06:00 +``` + +## 托管chart仓库 + +这部分展示了几种提供chart仓库的方法 + +### Google Cloud存储 + +第一步是**create your GCS bucket**。我们会调用`fantastic-charts`。 + +![Create a GCS Bucket](https://helm.sh/img/create-a-bucket.png) + +然后使用**editing the bucket permissions**保证你的bucket是公开的。 + +![Edit Permissions](https://helm.sh/img/edit-permissions.png) + +插入这一行 **保证你的bucket是公开的**: + +![Make Bucket Public](https://helm.sh/img/make-bucket-public.png) + +恭喜,您现在准备好了一个提供chart的空GCS bucket! + +你可以使用Google Cloud Storage命令行工具上传你的chart仓库,或者使用GCS的web页面。 +一个公共的GCS bucket可以通过简单的HTTPS地址访问:`https://bucket-name.storage.googleapis.com/`。 + +### Cloudsmith + +也可以使用Cloudsmith设置chart仓库。在 [这里](https://help.cloudsmith.io/docs/helm-chart-repository) +阅读更多关于Cloudsmith配置chart仓库的内容。 + +### JFrog Artifactory + +同样,也可以使用JFrog Artifactory配置chart仓库。 在 [这里](https://www.jfrog.com/confluence/display/RTF/Helm+Chart+Repositories) +阅读更多关于JFrog Artifactory配置chart仓库的内容。 + +### GitHub页面示例 + +你可以用GitHub页面以类似的方式创建chart仓库。 + +GitHub允许你使用两种方式提供静态web页面: + +* 通过`docs/`目录配置项目 +* 通过特定的分支配置项目 + +我们将使用第二种方式,不过第一种方式也很简单。 + +第一步是**创建你的gh-pages分支**。可以在本地创建: + +```console +$ git checkout -b gh-pages +``` + +或者在你的GitHub仓库通过web页面使用 **Branch** 按钮: + +![Create GitHub Pages branch](https://helm.sh/img/create-a-gh-page-button.png) + +然后,你要保证你的**gh-pages branch**设置为GitHub页面,点击你仓库的**Settings**并相信找到**GitHub pages**部分并设置如下: + +![Create GitHub Pages branch](https://helm.sh/img/set-a-gh-page.png) + +默认**Source**一般设置为**gh-pages branch**。如果不是默认,把它选上。 + +如果想使用自定义域名使用**custom domain**。 + +然后确保勾选了**Enforce HTTPS**, 这样提供chart时会使用**HTTPS**。 + +在这个配置中,你可以使用你的默认分支存储你的chart代码,并使用**gh-pages branch**作为chart仓库,比如: +`https://USERNAME.github.io/REPONAME`。[TS Charts](https://github.com/technosophos/tscharts)示范仓库可以访问 +`https://technosophos.github.io/tscharts/`。 + +如果你想使用GitHub页面托管chart仓库,请查看[Chart发布操作](https://helm.sh/zh/docs/howto/chart_releaser_action)。 +Chart 发布操作是GitHub的操作流,可以将GitHub项目转换成自托管的Helm chart仓库,可以使用使用 +[helm/chart-releaser](https://github.com/helm/chart-releaser) CLI工具。 + +### 普通web服务器 + +配置一个一般的服务器来提供Helm chart,您只需执行以下操作: + +* 将index和chart放置在可提供服务的服务器目录中 +* 确保`index.yaml`文件无需验证即可访问 +* 确保`yaml`文件是正确的内容类型(`text/yaml`或`text/x-yaml`) + +比如,如果你想在`$WEBROOT/charts`提供你的chart,要保证在web的root目录有一个`charts/`目录,并将index文件和chart放在这个目录中。 + +### ChartMuseum 仓库服务器 + +ChartMuseum 是一个用Go写的开源的Helm Chart仓库服务器,支持云存储后端,包括[Google Cloud Storage](https://cloud.google.com/storage/), +[Amazon S3](https://aws.amazon.com/s3/),[Microsoft Azure Blob Storage](https://azure.microsoft.com/en-us/services/storage/blobs/), +[Alibaba Cloud OSS Storage](https://www.alibabacloud.com/product/oss), +[Openstack Object Storage](https://developer.openstack.org/api-ref/object-store/), +[Oracle Cloud Infrastructure Object Storage](https://cloud.oracle.com/storage), +[Baidu Cloud BOS Storage](https://cloud.baidu.com/product/bos.html), +[Tencent Cloud Object Storage](https://intl.cloud.tencent.com/product/cos), +[DigitalOcean Spaces](https://www.digitalocean.com/products/spaces/), +[Minio](https://min.io/),以及[etcd](https://etcd.io/)。 + +你也可以使用[ChartMuseum](https://chartmuseum.com/docs/#using-with-local-filesystem-storage)服务从本地文件系统托管一个chart仓库。 + +### GitLab 包注册表 + +使用GitLab你可以在你的项目包注册表中发布Helm chart。在[这里](https://docs.gitlab.com/ee/user/packages/helm_repository/)查看更多使用GitLab设置helm包仓库的信息。 + +## 管理chart仓库 + +现在你拥有了一个chart仓库,最后一部分知道介绍如何下仓库中维护chart。 + +### 在chart仓库中存储chart + +现在你拥有了一个chart仓库,上传一个chart和index文件到仓库中。仓库中的chart必须打包(`helm package chart-name/`) +且使用正确的版本号(参照[SemVer 2](https://semver.org/)指导)。 + +下一步构建一个简单的示例工作流,不过欢迎你使用自己喜欢的工作流来存储和更新你的chart仓库。 + +一旦你准备好了打包的chart,创建一个新目录,然后将包移动到这个目录中。 + +```console +$ helm package docs/examples/alpine/ +$ mkdir fantastic-charts +$ mv alpine-0.1.0.tgz fantastic-charts/ +$ helm repo index fantastic-charts --url https://fantastic-charts.storage.googleapis.com +``` + +最后一条命令会用刚才创建的本地路径和远程仓库url构建一个`index.yaml`文件放在给定的目录路径中。 + +现在你可以使用同步工具或手动上传chart和index文件到chart仓库中。如果使用的是Google Cloud Storage,使用gsutil客户端检查 +[示范工作流](https://helm.sh/zh/docs/howto/chart_repository_sync_example/)。针对于GitHub,你可以简单地将chart放在合适的目标分支中。 + +### 添加一个新的chart到已有仓库中 + +每次你想在仓库中添加一个新的chart时,你必须重新生成index。`helm repo index`命令会完全无痕重建`index.yaml`文件。只包括在本地找到的chart。 + +不过你可以使用`--merge`参数增量添加新的chart到现有`index.yaml`文件中(使用类似GCS的远程仓库时很有用)。执行 +`helm repo index --help`了解更多。 + +确保修订过的`index.yaml`文件和chart都上传了,如果生成了源文件,也要上传。 + +### 与别人分享你的chart + +准备好分享你的chart时,只需要告诉别人你的仓库地址就可以了。 + +他们会通过`helm repo add [NAME] [URL]`命令将仓库添加到他们的客户端,并使用想引用仓库的任何名称。 + +```console +$ helm repo add fantastic-charts https://fantastic-charts.storage.googleapis.com +$ helm repo list +fantastic-charts https://fantastic-charts.storage.googleapis.com +``` + +如果chart支持HTTP的基础验证,你也需要提供用户名和密码: + +```console +$ helm repo add fantastic-charts https://fantastic-charts.storage.googleapis.com --username my-username --password my-password +$ helm repo list +fantastic-charts https://fantastic-charts.storage.googleapis.com +``` + +**注意:** 如果不存在有效的`index.yaml`就无法添加仓库。 + +**注意:** 如果你的helm仓库使用了类似于自签名的证书,为了跳过CA认证,可以使用 +`helm repo add --insecure-skip-tls-verify ...`。 + +然后,你的用户就可以通过你的chart进行搜索。更新了仓库之后,他们可以使用`helm repo update`命令获取最新的chart信息。 + +*在内部 `helm repo add` 和 `helm repo update` 命令会检索index.yaml文件并将其存储在 +`$XDG_CACHE_HOME/helm/repository/cache/`目录中。这里是`helm search`方法查找chart信息的位置。* diff --git a/content/zh/docs/topics/chart_tests.md b/content/zh/docs/topics/chart_tests.md new file mode 100644 index 0000000000..ca31d912dd --- /dev/null +++ b/content/zh/docs/topics/chart_tests.md @@ -0,0 +1,92 @@ +--- +title: "Chart Test" +description: "描述如何执行和测试你的chart" +weight: 3 +--- + +  chart包含了很多一起工作的Kubernetes资源和组件。作为一个chart作者,你可能想写一些测试验证chart安装时是否按照预期工作。 +这些测试同时可以帮助chart用户理解你的chart在做什么。 + +**test** 在helm chart中放在 `templates/`目录,并且是一个指定了容器和给定命令的任务。如果测试通过,容器应该成功退出 (exit 0) +任务的定义必须包含helm测试钩子的注释:`helm.sh/hook: test`。 + +注意Helm v3中,任务定义需要包含helm的测试钩子注释之一:`helm.sh/hook: test-success` 或者 `helm.sh/hook: test-failure`。 +`helm.sh/hook: test-success` 仍然向后兼容,也可以是 `helm.sh/hook: test`。 + +示例测试以下内容: + +- 验证你values.yaml文件中的配置可以正确注入。 + - 确保你的用户名和密码是对的 + - 确保不正确的用户名和密码不会工作 +- 判断你的服务只启动的并且正确地负载均衡 +- 等等。 + +你可以在Helm的一个版本中运行预定义的测试,执行 `helm test `。对于chart用户来说, +这是验证chart发布(或应用)可以正常运行的很好的方式。 + +## Example Test + +[helm create](https://helm.sh/zh/docs/helm/helm_create)命令会自动创建一些目录和文件。 +要尝试helm的测试功能,需要先创建一个helm chart示例。 + +```console +$ helm create demo +``` + +然后就可以看到示例demo的目录结构如下: + +```console +demo/ + Chart.yaml + values.yaml + charts/ + templates/ + templates/tests/test-connection.yaml +``` + +在`demo/templates/tests/test-connection.yaml`中,可以试试看到的测试功能,测试pod定义如下: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "demo.fullname" . }}-test-connection" + labels: + {{- include "demo.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['{{ include "demo.fullname" . }}:{{ .Values.service.port }}'] + restartPolicy: Never +``` + +## 运行一个发布版本测试套件的步骤 + +首先,安装chart到你的集群中创建一个版本。需要等待所有的pod变成active的状态;如果安装之后立即执行test, +可能会出现相应的失败,你不得不再执行一次test。 + +```console +$ helm install demo demo --namespace default +$ helm test demo +NAME: demo +LAST DEPLOYED: Mon Feb 14 20:03:16 2022 +NAMESPACE: default +STATUS: deployed +REVISION: 1 +TEST SUITE: demo-test-connection +Last Started: Mon Feb 14 20:35:19 2022 +Last Completed: Mon Feb 14 20:35:23 2022 +Phase: Succeeded +[...] +``` + +## 注意 + +- 你可以在单个yaml文件中定义尽可能多的测试或者分布在`templates/`目录中的多个yaml文件中。 +- 为了更好地隔离,欢迎你将测试套件嵌套放在`tests/`目录中,类似`/templates/tests/`。 +- 一个test就是一个[Helm 钩子](https://helm.sh/zh/docs/topics/charts_hooks),所以类似于 +`helm.sh/hook-weight`和`helm.sh/hook-delete-policy`的注释可以用于测试资源。 diff --git a/content/zh/docs/topics/charts.md b/content/zh/docs/topics/charts.md new file mode 100644 index 0000000000..f82f7d5ce5 --- /dev/null +++ b/content/zh/docs/topics/charts.md @@ -0,0 +1,930 @@ +--- +title: "Chart" +description: "阐述chart格式,并提供使用Helm构建chart的基本指导。" +weight: 1 +--- + +Helm使用的包格式称为 _chart_。 chart就是一个描述Kubernetes相关资源的文件集合。单个chart可以用来部署一些简单的, +类似于memcache pod,或者某些复杂的HTTP服务器以及web全栈应用、数据库、缓存等等。 + +Chart是作为特定目录布局的文件被创建的。它们可以打包到要部署的版本存档中。 + +如果你想下载和查看一个发布的chart,但不安装它,你可以用这个命令: `helm pull chartrepo/chartname`。 + +该文档解释说明了chart格式,并提供了用Helm构建chart的基本指导。 + +## Chart 文件结构 + +chart是一个组织在文件目录中的集合。目录名称就是chart名称(没有版本信息)。因而描述WordPress的chart可以存储在`wordpress/`目录中。 + +在这个目录中,Helm 期望可以匹配以下结构: + +```text +wordpress/ + Chart.yaml # 包含了chart信息的YAML文件 + LICENSE # 可选: 包含chart许可证的纯文本文件 + README.md # 可选: 可读的README文件 + values.yaml # chart 默认的配置值 + values.schema.json # 可选: 一个使用JSON结构的values.yaml文件 + charts/ # 包含chart依赖的其他chart + crds/ # 自定义资源的定义 + templates/ # 模板目录, 当和values 结合时,可生成有效的Kubernetes manifest文件 + templates/NOTES.txt # 可选: 包含简要使用说明的纯文本文件 +``` + +Helm保留使用 `charts/`,`crds/`, `templates/`目录,以及列举出的文件名。其他文件保持原样。 + +## Chart.yaml 文件 + +`Chart.yaml`文件是chart必需的。包含了以下字段: + +```yaml +apiVersion: chart API 版本 (必需) +name: chart名称 (必需) +version: 语义化2 版本(必需) +kubeVersion: 兼容Kubernetes版本的语义化版本(可选) +description: 一句话对这个项目的描述(可选) +type: chart类型 (可选) +keywords: + - 关于项目的一组关键字(可选) +home: 项目home页面的URL (可选) +sources: + - 项目源码的URL列表(可选) +dependencies: # chart 必要条件列表 (可选) + - name: chart名称 (nginx) + version: chart版本 ("1.2.3") + repository: (可选)仓库URL ("https://example.com/charts") 或别名 ("@repo-name") + condition: (可选) 解析为布尔值的yaml路径,用于启用/禁用chart (e.g. subchart1.enabled ) + tags: # (可选) + - 用于一次启用/禁用 一组chart的tag + import-values: # (可选) + - ImportValue 保存源值到导入父键的映射。每项可以是字符串或者一对子/父列表项 + alias: (可选) chart中使用的别名。当你要多次添加相同的chart时会很有用 +maintainers: # (可选) + - name: 维护者名字 (每个维护者都需要) + email: 维护者邮箱 (每个维护者可选) + url: 维护者URL (每个维护者可选) +icon: 用做icon的SVG或PNG图片URL (可选) +appVersion: 包含的应用版本(可选)。不需要是语义化,建议使用引号 +deprecated: 不被推荐的chart (可选,布尔值) +annotations: + example: 按名称输入的批注列表 (可选). +``` + +从[v3.3.2](https://github.com/helm/helm/releases/tag/v3.3.2),不再允许额外的字段。推荐的方法是在 +`annotations` 中添加自定义元数据。 + +### Chart和版本控制 + +每个chart都必须有个版本号。版本必须遵循 [语义化版本 2](https://semver.org/spec/v2.0.0.html) 标准。 +不像经典Helm, Helm v2以及后续版本会使用版本号作为发布标记。仓库中的包通过名称加版本号标识。 + +比如 `nginx` chart的版本字段`version: 1.2.3`按照名称被设置为: + +```text +nginx-1.2.3.tgz +``` + +更多复杂的语义化版本2 都是支持的,比如 `version: 1.2.3-alpha.1+ef365`。 但系统明确禁止非语义化版本名称。 + +**注意:** 鉴于经典Helm和部署管理器在使用chart时都非常倾向于GitHub,Helm v2 和后续版本不再依赖或需要GitHub甚至是Git。 +因此,它完全不使用Git SHA进行版本控制。 + +`Chart.yaml`文件中的`version`字段被很多Helm工具使用,包括CLI。当生成一个包时, +`helm package`命令可以用`Chart.yaml`文件中找到的版本号作为包名中的token。 +系统假设chart包名中的版本号可以与`Chart.yaml`文件中的版本号匹配。如果不满足这一假设会导致错误。 + +### `apiVersion` 字段 + +对于至少需要Helm 3的chart,`apiVersion` 字段应该是 `v2`。Chart支持之前`apiVersion` 设置为 `v1` 的Helm 版本, +并且在Helm 3中仍然可安装。 + +`v1` 到 `v2`的改变: + +- `dependencies`字段定义了chart的依赖,针对于`v1` 版本的chart被放置在分隔开的`requirements.yaml` 文件中 +(查看 [Chart 依赖](#chart-dependency)). +- `type`字段, 用于识别应用和库类型的chart(查看 [Chart 类型](#chart-types)). + +### `appVersion` 字段 + +注意这个`appVersion`字段与`version`字段并不相关。这是指定应用版本的一种方式。比如,这个`drupal` chart可能有一个 +`appVersion: "8.2.1"`,表示包含在chart(默认)的Drupal的版本是`8.2.1`。此字段仅供参考,对chart版本计算没有影响。 +强烈建议使用引号将版本括起来。它强制YAML解析器将版本号视为字符串。不加引号在某些场景会出现解析问题。 +比如,YAML将`1.0`解释为浮点值,且git提交的SHA类似`1234e10`是科学计数法。 + +从Helm v3.5.0开始,`helm create`会将默认的`appVersion`用引号括起来。 + +### `kubeVersion` 字段 + +可选的 `kubeVersion` 字段可以在支持的Kubernetes版本上定义语义化版本约束,Helm 在安装chart时会验证这个版本约束, +并在集群运行不支持的Kubernetes版本时显示失败。 + +版本约束可以包括空格分隔和比较运算符,比如: + +```yaml +>= 1.13.0 < 1.15.0 +``` + +或者它们可以用或操作符 `||` 连接,比如: + +```yaml +>= 1.13.0 < 1.14.0 || >= 1.14.1 < 1.15.0 +``` + +这个例子中排除了 `1.14.0` 版本,如果确定某些版本中的错误导致chart无法正常运行,这一点就很有意义。 + +除了版本约束外,使用运算符 `=` `!=` `>` `<` `>=` `<=` 支持一下速记符号: + +- 闭合间隔的连字符范围, `1.1 - 2.3.4` 等价于 `>= 1.1 <= 2.3.4` +- 通配符 `x`, `X` 和 `*`, `1.2.x` 等价于 `>= 1.2.0 < 1.3.0` +- 波浪符号~范围 (允许改变补丁版本), `~1.2.3` 等价于 `>= 1.2.3 < 1.3.0` +- 插入符号^范围 (允许改变次版本), `^1.2.3` 等价于 `>= 1.2.3 < 2.0.0` + +支持的语义化版本约束的细节说明请查看 [Masterminds/semver](https://github.com/Masterminds/semver) + +### 已弃用的Chart + +在Chart仓库管理chart时,有时需要废弃一个chart。 `Chart.yaml` 中可选的`deprecated`字段可以用来标记已弃用的chart。 +如果**latest**版本被标记为已弃用,则所有的chart都会被认为是已弃用的。以后可以通过发布未标记为已弃用的新版本来重新使用chart名称。 +弃用chart的工作流是: + +1. 升级chart的 `Chart.yaml` 文件,将这个chart标记为已弃用, 并更改版本 +2. 在chart仓库中发布新版的chart +3. 从源仓库中移除这个chart (比如用 git) + +### Chart Types + +`type`字段定义了chart的类型。有两种类型: `application` 和 `library`。 应用是默认类型,是可以完全操作的标准chart。 + [库类型 chart](http://helm.sh/zh/docs/topics/library_charts) 提供针对chart构建的实用程序和功能。 + 库类型chart与应用类型chart不同,因为它不能安装,通常不包含任何资源对象。 + +**注意:** 应用类型chart 可以作为库类型chart使用。可以通过将类型设置为 `library`来实现。 +然后这个库就被渲染成了一个库类型chart,所有的实用程序和功能都可以使用。所有的资源对象不会被渲染。 + +## Chart 许可证,自述和注释 + +Chart也可以包含描述安装,配置和使用文件,以及chart许可证。 + +许可证(LICENSE)是一个包含了chart [license](https://en.wikipedia.org/wiki/Software_license)的纯文本文件。 +chart可以包含一个许可证,因为在模板里不只是配置,还可能有编码逻辑。如果需要,还可以为chart安装的应用程序提供单独的许可证。 + +chart的自述文件README文件应该使用Markdown格式(README.md),一般应包含: + +- chart提供的应用或服务的描述 +- 运行chart的先决条件或要求 +- `values.yaml`的可选项和默认值的描述 +- 与chart的安装或配置相关的其他任何信息 + +`README.md` 文件会包含hub和用户接口显示的chart的详细信息。 + +chart也会包含一个简短的纯文本 `templates/NOTES.txt` 文件,这会在安装后及查看版本状态时打印出来。 +这个文件会作为一个 [模板](#templates-and-values)来评估,并用来显示使用说明,后续步骤,或者其他chart版本的相关信息。 +比如,可以提供连接数据库的说明,web UI的访问。由于此文件是在运行`helm install`或`helm status`时打印到STDOUT的, +因此建议保持内容简短,并指向自述文件以获取更多详细信息。 + +## Chart dependency + +Helm 中,chart可能会依赖其他任意个chart。 这些依赖可以使用`Chart.yaml`文件中的`dependencies` +字段动态链接,或者被带入到`charts/` 目录并手动配置。 + +### 使用 `dependencies` 字段管理依赖 + +当前chart依赖的其他chart会在`dependencies`字段定义为一个列表。 + +```yaml +dependencies: + - name: apache + version: 1.2.3 + repository: https://example.com/charts + - name: mysql + version: 3.2.1 + repository: https://another.example.com/charts +``` + +- `name`字段是你需要的chart的名称 +- `version`字段是你需要的chart的版本 +- `repository`字段是chart仓库的完整URL。注意你必须使用`helm repo add`在本地添加仓库 +- 你可以使用仓库的名称代替URL + +```console +$ helm repo add fantastic-charts https://fantastic-charts.storage.googleapis.com +``` + +```yaml +dependencies: + - name: awesomeness + version: 1.0.0 + repository: "@fantastic-charts" +``` + +一旦你定义好了依赖,运行 `helm dependency update` 就会使用你的依赖文件下载所有你指定的chart到你的`charts/`目录。 + +```console +$ helm dep up foochart +Hang tight while we grab the latest from your chart repositories... +...Successfully got an update from the "local" chart repository +...Successfully got an update from the "stable" chart repository +...Successfully got an update from the "example" chart repository +...Successfully got an update from the "another" chart repository +Update Complete. Happy Helming! +Saving 2 charts +Downloading apache from repo https://example.com/charts +Downloading mysql from repo https://another.example.com/charts +``` + +当 `helm dependency update` 拉取chart时,会在`charts/`目录中形成一个chart包。因此对于上面的示例,会在chart目录中期望看到以下文件: + +```text +charts/ + apache-1.2.3.tgz + mysql-3.2.1.tgz +``` + +#### 依赖的别名字段 + +除了上面的其他字段之外,每个需求项可以包含一个可选的字段 `alias`。 +为依赖chart添加一个别名,会使用别名作为新依赖chart的名称。 +需要使用其他名称访问chart时可以使用`alias`。 + +```yaml +# parentchart/Chart.yaml + +dependencies: + - name: subchart + repository: http://localhost:10191 + version: 0.1.0 + alias: new-subchart-1 + - name: subchart + repository: http://localhost:10191 + version: 0.1.0 + alias: new-subchart-2 + - name: subchart + repository: http://localhost:10191 + version: 0.1.0 +``` + +上述例子中,我们会获得`parentchart`所有的3个依赖项: + +```text +subchart +new-subchart-1 +new-subchart-2 +``` + +手动完成的方式是将同一个chart用不同的名称复制/粘贴多次到`charts/`目录中。 + +#### 依赖中的tag和条件字段 + +除了上面的其他字段外,每个需求项可以包含可选字段 `tags` 和 `condition`。 + +所有的chart会默认加载。如果存在 `tags` 或者 `condition` 字段,它们将被评估并用于控制它们应用的chart的加载。 + +Condition - 条件字段field 包含一个或多个YAML路径(用逗号分隔)。 +如果这个路径在上层values中已存在并解析为布尔值,chart会基于布尔值启用或禁用chart。 +只会使用列表中找到的第一个有效路径,如果路径为未找到则条件无效。 + +Tags - tag字段是与chart关联的YAML格式的标签列表。在顶层value中,通过指定tag和布尔值,可以启用或禁用所有的带tag的chart。 + +```yaml +# parentchart/Chart.yaml + +dependencies: + - name: subchart1 + repository: http://localhost:10191 + version: 0.1.0 + condition: subchart1.enabled,global.subchart1.enabled + tags: + - front-end + - subchart1 + - name: subchart2 + repository: http://localhost:10191 + version: 0.1.0 + condition: subchart2.enabled,global.subchart2.enabled + tags: + - back-end + - subchart2 +``` + +```yaml +# parentchart/values.yaml + +subchart1: + enabled: true +tags: + front-end: false + back-end: true +``` + +在上面的例子中,所有带 `front-end`tag的chart都会被禁用,但只要上层的value中 +`subchart1.enabled` 路径被设置为 'true',该条件会覆盖 `front-end`标签且 `subchart1` 会被启用。 + +一旦 `subchart2`使用了`back-end`标签并被设置为了 `true`,`subchart2`就会被启用。 +也要注意尽管`subchart2` 指定了一个条件字段, 但是上层value没有相应的路径和value,因此这个条件不会生效。 + +##### 使用带有标签和条件的CLI + +`--set` 参数一如既往可以用来设置标签和条件值。 + +```console +helm install --set tags.front-end=true --set subchart2.enabled=false +``` + +##### 标签和条件的解析 + +- **条件 (当设置在value中时)总是会覆盖标签** 第一个chart条件路径存在时会忽略后面的路径。 +- 标签被定义为 '如果任意的chart标签是true,chart就可以启用'。 +- 标签和条件值必须被设置在顶层value中。 +- value中的`tags:`键必须是顶层键。 全局和嵌套的`tags:`表现在不支持了。 + +#### 通过依赖导入子Value + +在某些情况下,允许子chart的值作为公共默认传递到父chart中是值得的。使用 +`exports`格式的额外好处是它可是将来的工具可以自检用户可设置的值。 + +被导入的包含值的key可以在父chart的 `dependencies` 中的 `import-values` 字段以YAML列表形式指定。 +列表中的每一项是从子chart中`exports`字段导入的key。 + +导入`exports` key中未包含的值,使用[子-父](#using-the-child-parent-format)格式。两种格式的示例如下所述。 + +##### 使用导出格式 + +如果子chart的`values.yaml`文件中在根节点包含了`exports`字段,它的内容可以通过指定的可以被直接导入到父chart的value中, +如下所示: + +```yaml +# parent's Chart.yaml file + +dependencies: + - name: subchart + repository: http://localhost:10191 + version: 0.1.0 + import-values: + - data +``` + +```yaml +# child's values.yaml file + +exports: + data: + myint: 99 +``` + +只要我们再导入列表中指定了键`data`,Helm就会在子chart的`exports`字段查找`data`键并导入它的内容。 + +最终的父级value会包含我们的导出字段: + +```yaml +# parent's values + +myint: 99 +``` + +注意父级键 `data` 没有包含在父级最终的value中,如果想指定这个父级键,要使用'子-父' 格式。 + +##### Using the child-parent format + +要访问子chart中未包含的 `exports` 键的值,你需要指定要导入的值的源键(`child`)和父chart(`parent`)中值的目标路径。 + +下面示例中的`import-values` 指示Helm去拿到能再`child:`路径中找到的任何值,并拷贝到`parent:`的指定路径。 + +```yaml +# parent's Chart.yaml file + +dependencies: + - name: subchart1 + repository: http://localhost:10191 + version: 0.1.0 + ... + import-values: + - child: default.data + parent: myimports +``` + +上面的例子中,在subchart1里面找到的`default.data`的值会被导入到父chart的`myimports`键中,细节如下: + +```yaml +# parent's values.yaml file + +myimports: + myint: 0 + mybool: false + mystring: "helm rocks!" +``` + +```yaml +# subchart1's values.yaml file + +default: + data: + myint: 999 + mybool: true +``` + +父chart的结果值将会是这样: + +```yaml +# parent's final values + +myimports: + myint: 999 + mybool: true + mystring: "helm rocks!" +``` + +父chart中的最终值包含了从 subchart1中导入的`myint`和`mybool`字段。 + +### 通过`charts/`目录手动管理依赖 + +如果对依赖进行更多控制,通过将有依赖关系的chart复制到`charts/`目录中来显式表达这些依赖关系。 + +依赖应该是一个解压的chart目录。但是名字不能以`_`或`.`开头,否则会被chart加载器忽略。 + +比如,如果WordPress chart依赖于Apache chart,那么(正确版本的)Apache chart需要放在WordPress chart 的`charts/`目录中: + +```yaml +wordpress: + Chart.yaml + # ... + charts/ + apache/ + Chart.yaml + # ... + mysql/ + Chart.yaml + # ... +``` + +上面的例子展示了WordPress chart 如何通过将这些chart包含在 `charts/` 目录中来表达它对Apache 和 MySQL的依赖。 + +**提示:** _要将依赖放入`charts/`目录,使用 `helm pull` 命令_ + +### 使用依赖的操作部分 + +上面的部分说明如何指定chart的依赖,但是对使用 `helm install` 和 `helm upgrade` 安装chart有什么影响? + +假设有个chart "A" 创建了下面的Kubernetes对象: + +- namespace "A-Namespace" +- statefulset "A-StatefulSet" +- service "A-Service" + +另外,A是依赖于chart B创建的对象: + +- namespace "B-Namespace" +- replicaset "B-ReplicaSet" +- service "B-Service" + +安装/升级chart A后,会创建/修改一个单独的Helm版本。这个版本会按顺序创建/升级以下所有的Kubernetes对象: + +- A-Namespace +- B-Namespace +- A-Service +- B-Service +- B-ReplicaSet +- A-StatefulSet + +这是因为当Helm安装/升级chart时,chart中所有的Kubernetes对象以及依赖会 + +- 聚合成一个单一的集合;然后 +- 按照类型和名称排序;然后 +- 按这个顺序创建/升级。 + +至此会为chart及其依赖创建一个包含所有对象的release版本。 + +Kubernetes类型的安装顺序会按照kind_sorter.go(查看 [Helm源文件](https://github.com/helm/helm/blob/484d43913f97292648c867b56768775a55e4bba6/pkg/releaseutil/kind_sorter.go))中给出的枚举顺序进行。 + +## Templates and Values + +Helm Chart 模板是按照[Go模板语言](https://golang.org/pkg/text/template/)书写, +增加了50个左右的附加模板函数[来自 Sprig库](https://github.com/Masterminds/sprig) +和一些其他[指定的函数](https://helm.sh/zh/docs/howto/charts_tips_and_tricks)。 + +所有模板文件存储在chart的 `templates/` 文件夹。 +当Helm渲染chart时,它会通过模板引擎遍历目录中的每个文件。 + +模板的Value通过两种方式提供: + +- Chart开发者可以在chart中提供一个命名为 `values.yaml` 的文件。这个文件包含了默认值。 +- Chart用户可以提供一个包含了value的YAML文件。可以在命令行使用 `helm install`命令时提供。 + +当用户提供自定义value时,这些value会覆盖chart的`values.yaml`文件中value。 + +### 模板文件 + +模板文件遵守书写Go模板的标准惯例(查看[文本/模板 Go 包文档](https://golang.org/pkg/text/template/)了解更多)。 +模板文件的例子看起来像这样: + +```yaml +apiVersion: v1 +kind: ReplicationController +metadata: + name: deis-database + namespace: deis + labels: + app.kubernetes.io/managed-by: deis +spec: + replicas: 1 + selector: + app.kubernetes.io/name: deis-database + template: + metadata: + labels: + app.kubernetes.io/name: deis-database + spec: + serviceAccount: deis-database + containers: + - name: deis-database + image: {{ .Values.imageRegistry }}/postgres:{{ .Values.dockerTag }} + imagePullPolicy: {{ .Values.pullPolicy }} + ports: + - containerPort: 5432 + env: + - name: DATABASE_STORAGE + value: {{ default "minio" .Values.storage }} +``` + +上面的例子,松散地基于[https://github.com/deis/charts](https://github.com/deis/charts), +是一个Kubernetes副本控制器的模板。可以使用下面四种模板值(一般被定义在`values.yaml`文件): + +- `imageRegistry`: Docker镜像的源注册表 +- `dockerTag`: Docker镜像的tag +- `pullPolicy`: Kubernetes的拉取策略 +- `storage`: 后台存储,默认设置为`"minio"` + +所有的值都是模板作者定义的。Helm不需要或指定参数。 + +要了解更多chart的工作,请查阅CNCF的 [Artifact Hub](https://artifacthub.io/packages/search?kind=0)。 + +### 预定义的Values + +Values通过模板中`.Values`对象可访问的`values.yaml`文件(或者通过 `--set` 参数)提供, +但可以模板中访问其他预定义的数据片段。 + +以下值是预定义的,对每个模板都有效,并且可以被覆盖。和所有值一样,名称 _区分大小写_。 + +- `Release.Name`: 版本名称(非chart的) +- `Release.Namespace`: 发布的chart版本的命名空间 +- `Release.Service`: 组织版本的服务 +- `Release.IsUpgrade`: 如果当前操作是升级或回滚,设置为true +- `Release.IsInstall`: 如果当前操作是安装,设置为true +- `Chart`: `Chart.yaml`的内容。因此,chart的版本可以从 `Chart.Version` 获得, + 并且维护者在`Chart.Maintainers`里。 +- `Files`: chart中的包含了非特殊文件的类图对象。这将不允许您访问模板, + 但是可以访问现有的其他文件(除非被`.helmignore`排除在外)。 + 使用`{{ index .Files "file.name" }}`可以访问文件或者使用`{{.Files.Get name }}`功能。 + 您也可以使用`{{ .Files.GetBytes }}`作为`[]byte`访问文件内容。 +- `Capabilities`: 包含了Kubernetes版本信息的类图对象。(`{{ .Capabilities.KubeVersion }}`) + 和支持的Kubernetes API 版本(`{{ .Capabilities.APIVersions.Has "batch/v1" }}`) + +**注意:** 任何未知的`Chart.yaml`字段会被抛弃。在`Chart`对象中无法访问。因此, +`Chart.yaml`不能用于将任意结构的数据传递到模板中。不过values文件可用于此。 + +### Values文件 + +考虑到前面部分的模板,`values.yaml`文件提供的必要值如下: + +```yaml +imageRegistry: "quay.io/deis" +dockerTag: "latest" +pullPolicy: "Always" +storage: "s3" +``` + +values文件被定义为YAML格式。chart会包含一个默认的`values.yaml`文件。 +Helm安装命令允许用户使用附加的YAML values覆盖这个values: + +```console +$ helm install --generate-name --values=myvals.yaml wordpress +``` + +以这种方式传递值时,它们会合并到默认的values文件中。比如,`myvals.yaml`文件如下: + +```yaml +storage: "gcs" +``` + +当在chart中这个值被合并到`values.yaml`文件中时,生成的内容是这样: + +```yaml +imageRegistry: "quay.io/deis" +dockerTag: "latest" +pullPolicy: "Always" +storage: "gcs" +``` + +注意只有最后一个字段会覆盖。 + +**注意:** chart包含的默认values文件 _必须_ 被命名为`values.yaml`。不过在命令行指定的文件可以是其他名称。 + +**注意:** 如果`helm install`或`helm upgrade`使用了`--set`参数,这些值在客户端会被简单地转换为YAML。 + +**注意:** 如果values 文件存在任何必需的条目,它们会在chart模板中使用['required' +函数](https://helm.sh/zh/docs/howto/charts_tips_and_tricks) 声明为必需的。 + +然后使用模板中的`.Values`对象就可以任意访问这些值了: + +```yaml +apiVersion: v1 +kind: ReplicationController +metadata: + name: deis-database + namespace: deis + labels: + app.kubernetes.io/managed-by: deis +spec: + replicas: 1 + selector: + app.kubernetes.io/name: deis-database + template: + metadata: + labels: + app.kubernetes.io/name: deis-database + spec: + serviceAccount: deis-database + containers: + - name: deis-database + image: {{ .Values.imageRegistry }}/postgres:{{ .Values.dockerTag }} + imagePullPolicy: {{ .Values.pullPolicy }} + ports: + - containerPort: 5432 + env: + - name: DATABASE_STORAGE + value: {{ default "minio" .Values.storage }} +``` + +### 范围,依赖和值 + +Values文件可以声明顶级chart的值,以及`charts/`目录中包含的其他任意chart。 +或者换个说法,values文件可以为chart及其任何依赖项提供值。比如,上面示范的WordPress chart同时有 +`mysql` 和 `apache` 作为依赖。values文件可以为以下所有这些组件提供依赖: + +```yaml +title: "My WordPress Site" # Sent to the WordPress template + +mysql: + max_connections: 100 # Sent to MySQL + password: "secret" + +apache: + port: 8080 # Passed to Apache +``` + +更高阶的chart可以访问下面定义的所有变量。因此WordPress chart可以用`.Values.mysql.password`访问MySQL密码。 +但是低阶的chart不能访问父级chart,所以MySQL无法访问`title`属性。同样也无法访问`apache.port`。 + +Values 被限制在命名空间中,但是命名空间被删减了。因此对于WordPress chart, +它可以用`.Values.mysql.password`访问MySQL的密码字段。但是对于MySQL chart,值的范围被缩减了且命名空间前缀被移除了, +因此它把密码字段简单地看作`.Values.password`。 + +#### 全局Values + +从2.0.0-Alpha.2开始,Helm 支持特殊的"global"值。设想一下前面的示例中的修改版本: + +```yaml +title: "My WordPress Site" # Sent to the WordPress template + +global: + app: MyWordPress + +mysql: + max_connections: 100 # Sent to MySQL + password: "secret" + +apache: + port: 8080 # Passed to Apache +``` + +上面添加了`global`部分和一个值`app: MyWordPress`。这个值以`.Values.global.app`在 _所有_ chart中有效。 + +比如,`mysql`模板可以以`{{.Values.global.app}}`访问`app`,同样`apache`chart也可以访问。 +实际上,上面的values文件会重新生成为这样: + +```yaml +title: "My WordPress Site" # Sent to the WordPress template + +global: + app: MyWordPress + +mysql: + global: + app: MyWordPress + max_connections: 100 # Sent to MySQL + password: "secret" + +apache: + global: + app: MyWordPress + port: 8080 # Passed to Apache +``` + +这提供了一种和所有的子chart共享顶级变量的方式,这在类似label设置`metadata`属性时会很有用。 + +如果子chart声明了一个全局变量,那这个变量会 _向下_ 传递(到子chart的子chart),但不会 _向上_ 传递到父级chart。 +子chart无法影响父chart的值。 + +并且,父chart的全局变量优先于子chart中的全局变量。 + +### 架构文件 + +有时候,chart容器可能想基于它们的values值定义一个结构,这可以在`values.schema.json`文件中定义一个架构实现。 +架构使用[JSON 架构](https://json-schema.org/)表示。看起来像这样: + +```json +{ + "$schema": "https://json-schema.org/draft-07/schema#", + "properties": { + "image": { + "description": "Container Image", + "properties": { + "repo": { + "type": "string" + }, + "tag": { + "type": "string" + } + }, + "type": "object" + }, + "name": { + "description": "Service name", + "type": "string" + }, + "port": { + "description": "Port", + "minimum": 0, + "type": "integer" + }, + "protocol": { + "type": "string" + } + }, + "required": [ + "protocol", + "port" + ], + "title": "Values", + "type": "object" +} +``` + +这个架构会应用values值并验证它。当执行以下任意命令时会进行验证: + +- `helm install` +- `helm upgrade` +- `helm lint` +- `helm template` + +一个符合此架构要求的`values.yaml`文件示例如下所示: + +```yaml +name: frontend +protocol: https +port: 443 +``` + +注意这个架构被应用到了最终的 `.Values` 对象,而不仅仅是`values.yaml`文件。 +这意味着下面的`yaml`文件是有效的,给定的chart是用下面显示的适当的`--set`选项安装的: + +```yaml +name: frontend +protocol: https +``` + +```console +helm install --set port=443 +``` + +此外,最终的`.Values`对象是根据*所有的*子chart架构检查。 这意味着父chart无法规避子chart的限制。 +这也是逆向的 - 如果子chart的`values.yaml`文件无法满足需求,父chart*必须* 满足这些限制才能有效。 + +### 参考 + +在编写模板,值和架构文件时,有几个标准的参考可以帮助您。 + +- [Go templates](https://godoc.org/text/template) +- [Extra template functions](https://godoc.org/github.com/Masterminds/sprig) +- [The YAML format](https://yaml.org/spec/) +- [JSON Schema](https://json-schema.org/) + +## 用户自定义资源(CRD) + +Kubernetes提供了一种声明Kubernetes新类型对象的机制。使用CustomResourceDefinition(CRD), +Kubernetes开发者可以声明自定义资源类型。 + +Helm 3中,CRD被视为一种特殊的对象。它们被安装在chart的其他部分之前,并受到一些限制。 + +CRD YAML文件应被放置在chart的`crds/`目录中。 +多个CRD(用YAML的开始和结束符分隔)可以被放置在同一个文件中。Helm会尝试加载CRD目录中 _所有的_ 文件到Kubernetes。 + +CRD 文件 _无法模板化_,必须是普通的YAML文档。 + +当Helm安装新chart时,会上传CRD,暂停安装直到CRD可以被API服务使用,然后启动模板引擎, +渲染chart其他部分,并上传到Kubernetes。因为这个顺序,CRD信息会在Helm模板中的 +`.Capabilities`对象中生效,并且Helm模板会创建在CRD中声明的新的实例对象。 + +比如,如果您的chart在`crds/`目录中有针对于`CronTab`的CRD,您可以在`templates/`目录中创建`CronTab`类型实例: + +```text +crontabs/ + Chart.yaml + crds/ + crontab.yaml + templates/ + mycrontab.yaml +``` + +`crontab.yaml`文件必须包含没有模板指令的CRD: + +```yaml +kind: CustomResourceDefinition +metadata: + name: crontabs.stable.example.com +spec: + group: stable.example.com + versions: + - name: v1 + served: true + storage: true + scope: Namespaced + names: + plural: crontabs + singular: crontab + kind: CronTab +``` + +然后模板`mycrontab.yaml`可以创建一个新的`CronTab`(照例使用模板): + +```yaml +apiVersion: stable.example.com +kind: CronTab +metadata: + name: {{ .Values.name }} +spec: + # ... +``` + +Helm在安装`templates/`内容之前会保证`CronTab`类型安装成功并对Kubernetes API可用。 + +### CRD的限制 + +不像大部分的Kubernetes对象,CRD是全局安装的。因此Helm管理CRD时会采取非常谨慎的方式。 +CRD受到以下限制: + +- CRD从不重新安装。 如果Helm确定`crds/`目录中的CRD已经存在(忽略版本),Helm不会安装或升级。 +- CRD从不会在升级或回滚时安装。Helm只会在安装时创建CRD。 +- CRD从不会被删除。自动删除CRD会删除集群中所有命名空间中的所有CRD内容。因此Helm不会删除CRD。 + +希望升级或删除CRD的操作员应该谨慎地手动执行此操作。 + +## 使用Helm管理Chart + +`helm`工具有一些命令用来处理chart。 + +它可以为您创建一个新chart: + +```console +$ helm create mychart +Created mychart/ +``` + +编辑了chart之后,`helm`能为您把它打包成一个chart存档: + +```console +$ helm package mychart +Archived mychart-0.1.-.tgz +``` + +您也可以使用`helm` 帮您找到chart的格式或信息的问题: + +```console +$ helm lint mychart +No issues found +``` + +## Chart仓库 + +_chart仓库_ 是一个HTTP服务器,包含了一个或多个打包的chart。当`helm`用来管理本地chart目录时, +共享chart时,首选的机制就是使用chart仓库。 + +任何可以服务于YAML文件和tar文件并可以响应GET请求的HTTP服务器都可以用做仓库服务器。 +Helm 团队已经测试了一些服务器,包括激活websit模组的Google Cloud 存储,以及使用website的S3。 + +仓库的主要特征存在一个名为 `index.yaml` 的特殊文件,文件中包含仓库提供的包的完整列表, +以及允许检索和验证这些包的元数据。 + +在客户端,仓库使用`helm repo`命令管理。然而,Helm不提供上传chart到远程仓库的工具。 +这是因为这样做会给执行服务器增加大量的必要条件,也就增加了设置仓库的障碍。 + +## Chart Starter 包 + +`helm create`命令可以附带一个可选的 `--starter` 选项让您指定一个 "starter chart"。 + +Starter就只是普通chart,但是被放置在`$XDG_DATA_HOME/helm/starters`。作为一个chart开发者, +您可以编写被特别设计用来作为启动的chart。设计此类chart应注意以下考虑因素: + +- `Chart.yaml`会被生成器覆盖。 +- 用户将希望修改此类chart的内容,所以文档应该说明用户如果做到这一点。 +- 所有出现的``都会被替换为指定为chart名称,以便chart可以作为模板使用。 + +当前增加一个chart的唯一方式就是拷贝chart到`$XDG_DATA_HOME/helm/starters`。在您的chart文档中,您可能需要解释这个过程。 diff --git a/content/zh/docs/topics/charts_hooks.md b/content/zh/docs/topics/charts_hooks.md new file mode 100644 index 0000000000..bc08829704 --- /dev/null +++ b/content/zh/docs/topics/charts_hooks.md @@ -0,0 +1,163 @@ +--- +title: "Chart Hook" +description: "详述如何使用chart hook" +weight: 2 +--- + +Helm 提供了一个 _hook_ 机制允许chart开发者在发布生命周期的某些点进行干预。比如你可以使用hook用于: + +- 安装时在加载其他chart之前加载配置映射或密钥 +- 安装新chart之前执行备份数据库的任务,然后在升级之后执行第二个任务用于存储数据。 +- 在删除发布之前执行一个任务以便在删除服务之前退出滚动。 + +钩子的工作方式与常规模板类似,但因为Helm对其不同的使用方式,会有一些特殊的注释。这部分会讲述钩子的基本使用模式。 + +## 可用的钩子 + +定义了以下钩子: + +| 注释值 | 描述 | +| ---------------- | ----------------------------------------------------------------------------------------------------- | +| `pre-install` | 在模板渲染之后,Kubernetes资源创建之前执行 | +| `post-install` | 在所有资源加载到Kubernetes之后执行 | +| `pre-delete` | 在Kubernetes删除之前,执行删除请求 | +| `post-delete` | 在所有的版本资源删除之后执行删除请求 | +| `pre-upgrade` | 在模板渲染之后,资源更新之前执行一个升级请求 | +| `post-upgrade` | 所有资源升级之后执行一个升级请求 | +| `pre-rollback` | 在模板渲染之后,资源回滚之前,执行一个回滚请求 | +| `post-rollback` | 在所有资源被修改之后执行一个回滚请求 | +| `test` | 调用Helm test子命令时执行 ([test文档](https://helm.sh/zh/docs/topics/chart_tests/)) | + +_注意`crd-install`钩子已被移除以支持Helm 3的`crds/`目录。_ + +## 钩子和发布生命周期 + +钩子允许你在发布生命周期的关键节点上有机会执行操作。比如,考虑`helm install`的生命周期。默认的,生命周期看起来是这样: + +1. 用户执行`helm install foo` +2. Helm库调用安装API +3. 在一些验证之后,库会渲染`foo`模板 +4. 库会加载结果资源到Kubernetes +5. 库会返回发布对象(和其他数据)给客户端 +6. 客户端退出 + +Helm 为`install`周期定义了两个钩子:`pre-install`和`post-install`。如果`foo` chart的开发者两个钩子都执行, +周期会被修改为这样: + +1. 用户返回 `helm install foo` +2. Helm库调用安装API +3. 在 `crds/`目录中的CRD会被安装 +4. 在一些验证之后,库会渲染`foo`模板 +5. 库准备执行`pre-install`钩子(将hook资源加载到Kubernetes中) +6. 库按照权重对钩子排序(默认将权重指定为0),然后在资源种类排序,最后按名称正序排列。 +7. 库先加载最小权重的钩子(从负到正) +8. 库会等到钩子是 "Ready"状态(CRD除外) +9. 库将生成的资源加载到Kubernetes中。注意如果设置了`--wait`参数,库会等所有资源是ready状态, + 且所有资源准备就绪后才会执行`post-install`钩子。 +10. 库执行`post-install`钩子(加载钩子资源)。 +11. 库会等到钩子是"Ready"状态 +12. 库会返回发布对象(和其他数据)给客户端 +13. 客户端退出 + +  等钩子准备好是什么意思? 这取决于钩子声明的资源。如果资源是 `Job` 或 `Pod`类型,Helm会等到直到他成功运行完成。 +如果钩子失败,发布就会失败。这是一个 _阻塞操作_,所以Helm客户端会在这个任务执行时暂停。 + +  针对其他种类,一旦Kubernetes将资源标记为已加载(已添加或已更新),资源会被认为是"Ready"。 当一个钩子中声明了很多资源时, +资源会串行执行。如果有钩子权重,会按照权重顺序执行。从Helm 3.2.0开始,具有相同权重的钩子资源会和普通非钩子资源以相同的顺序安装。 +否则,顺序就无法保证。(Helm 2.3.0及之后,它们按照字母排序。不过该行为并不会绑定,将来可能会改变。)增加钩子权重被认为是很好的做法, +如果权重不重要,可以设置为`0`。 + +### 钩子资源不使用对应版本管理 + +钩子创建的资源无法作为发布的一部分进行跟踪和管理。一旦Helm验证hook达到ready状态,将不使用钩子资源。 +当对应发布删除后,钩子资源的垃圾回收会在将来添加到Helm 3中,因此不能被删除的钩子资源应该添加注释: +`helm.sh/resource-policy: keep`。 + +实际上,如果你在钩子中创建了资源,不能依靠`helm uninstall`去删除资源。要删除这些资源,要么在钩子模板文件中[添加一个自定义的`helm.sh/hook-delete-policy` +注释](#hook-deletion-policies),要么[设置任务资源的生存时间(TTL)字段](https://kubernetes.io/docs/concepts/workloads/controllers/ttlafterfinished/)。 + +## 编写一个钩子 + +钩子就是在`metadata`部分指定了特殊注释的Kubernetes清单文件。因为是模板文件,你可以使用所有的普通模板特性,包括读取 `.Values`, +`.Release`,和 `.Template`。 + +比如这个模板,存储在`templates/post-install-job.yaml`,声明了一个要运行在`post-install`上的任务: + +```yaml +apiVersion: batch/v1 +kind: Job +metadata: + name: "{{ .Release.Name }}" + labels: + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + annotations: + # This is what defines this resource as a hook. Without this line, the + # job is considered part of the release. + "helm.sh/hook": post-install + "helm.sh/hook-weight": "-5" + "helm.sh/hook-delete-policy": hook-succeeded +spec: + template: + metadata: + name: "{{ .Release.Name }}" + labels: + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + spec: + restartPolicy: Never + containers: + - name: post-install-job + image: "alpine:3.3" + command: ["/bin/sleep","{{ default "10" .Values.sleepyTime }}"] + +``` + +使模板称为钩子的是注释: + +```yaml +annotations: + "helm.sh/hook": post-install +``` + +一个资源可以实现多个钩子: + +```yaml +annotations: + "helm.sh/hook": post-install,post-upgrade +``` + +类似的,执行一个给定钩子的不同资源的数量也没有限制。比如,一个pre-install钩子可以同时声明密钥和配置映射。 + +当子chart声明钩子时,这些也会被评估。顶级chart无法禁用子chart声明的钩子。 + +可以为钩子定义权重,这有助于建立一个确定性的执行顺序。权重使用以下注释定义: + +```yaml +annotations: + "helm.sh/hook-weight": "5" +``` + +钩子权重可以正数也可以是负数,但一定要是字符串。Helm开始执行特定种类的钩子时,会正序排列这些钩子。 + +### Hook deletion policies + +可以定义策略来决定何时删除对应的钩子资源。钩子的删除策略使用以下注释定义: + +```yaml +annotations: + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +``` + +可以选择一个或多个定义的注释值: + +| 注释值 | 描述 | +| ---------------------- | -------------------------------------------------------------------- | +| `before-hook-creation` | 新钩子启动前删除之前的资源 (默认) | +| `hook-succeeded` | 钩子成功执行之后删除资源 | +| `hook-failed` | 如果钩子执行失败,删除资源 | + +如果没有指定钩子删除策略的注释,默认使用`before-hook-creation`。 diff --git a/content/zh/docs/topics/kubernetes_apis.md b/content/zh/docs/topics/kubernetes_apis.md new file mode 100644 index 0000000000..ae5fa6302c --- /dev/null +++ b/content/zh/docs/topics/kubernetes_apis.md @@ -0,0 +1,110 @@ +--- +title: "弃用的 Kubernetes API" +description: "解释Helm不推荐使用的Kubernetes API" +--- + +Kubernetes是一个API驱动系统,且API会随着时间的推移而变化,以反映对问题理解的不断推移。这是系统及API的普遍做法。 +API推移的一个重要部分时良好的弃用策略和通知用户更改API是如何实现的。换句话说,你的API使用者需要提前知道要发布的API +删除或更改了什么。这消除了重大改变对用户造成的恐惧。 + +[Kubernetes弃用策略](https://kubernetes.io/docs/reference/using-api/deprecation-policy/) +文档描述了如何处理API版本的变化。弃用策略声明了在弃用声明之后支持的API版本的时间范围。因此关注弃用声明并知道API何时被移除很重要。 +有助于将影响降到最低。 + +这是一个声明示例, [针对Kubernetes 1.6弃用的API版本](https://kubernetes.io/blog/2019/07/18/api-deprecations-in-1-16/), +而且是在版本发布的几个月之前公布。在这之前,这些API版本可能已经宣布不再使用了。这表明一个好的策略可以通知用户API的版本支持。 + +Helm模板定义Kubernetes对象时指定了一个 [Kubernetes +API组](https://kubernetes.io/docs/concepts/overview/kubernetes-api/#api-groups),类似于Kubernetes的manifest文件。 +在模板的`apiVersion`字段指定并标识了Kubernetes对象的API版本。这意味着Helm用户和chart维护者需要关注Kubernetes的API版本 +何时会被弃用且在哪个Kubernetes版本中被移除。 + +## Chart Maintainers + +你应该审核chart,检查Kubernetes中已弃用或已删除的Kubernetes API版本。如果API版本不再被支持,应该更新为支持版本并发布新的 +chart版本。API版本由`kind`和`apiVersion`字段定义。比如,Kubernetes 1.16 中有个被移除的`Deployment`对象API版本: + +```yaml +apiVersion: apps/v1beta1 +kind: Deployment +``` + +## Helm用户 + +你应该审核你使用的chart(类似于[chart维护者](#chart-maintainers)),并识别所有的chart中Kubernetes版本弃用或移除的API版本。 +针对确定的chart,需要检查(有支持的API版本的)chart最新的版本,或者手动更新。 + +另外,你还需要审核已经部署的chart(即Helm版本)还有没有弃用或移除的API版本。可以使用`helm get manifest`获取详细信息。 + +将Helm更新为支持的API取决于你通过以下方式找到的: + +1. 如果你只找到弃用的API版本,则: + + - 执行`helm upgrade`升级Kubernetes API版本支持的chart版本 + - 在升级中添加一个描述,在当前版本之前不执行Helm版本回滚 + +2. 如果你发现了在Kubernetes版本中被移除的API版本,则: + + - 如果你运行的Kubernetes版本中API版本依然可用(比如,你在Kubernetes 1.15 且你发现使用的API会在1.16中移除): + - 遵循第1步的步骤 + - 否则(比如,你运行的Kubernetes 版本中某些API版本通过`helm get manifest`显示不可用): + - 需要编辑存储在集群中的版本清单,更新API版本到支持的API。查看[更新版本清单的API版本](#updating-api-versions-of-a-release-manifest) + +> 注意:在所有使用支持的API更新Helm版本的场景中,决不应该将发布版本回滚到API版本支持的之前的版本 + +> 建议:最佳实践是将正在使用的弃用版本升级到支持的API版本,在升级Kubernetes 集群之前删除这些API版本。 + +如果你没有按照之前的建议更新版本, 当升级的Kubernetes版本中API的版本已经移除,会出现类似下面的错误: + +```console +Error: UPGRADE FAILED: current release manifest contains removed kubernetes api(s) +for this kubernetes version and it is therefore unable to build the kubernetes +objects for performing the diff. error from kubernetes: unable to recognize "": +no matches for kind "Deployment" in version "apps/v1beta1" +``` + +Helm在这个情况中会失败,因为试图它在当前部署的和你传了更新/支持的API版本的chart之间创建一个diff补丁(包含在这个Kubernetes +版本中删除的Kubernetes API)。失败的根本原因是,当Kubernetes删除了一个API版本时,Kubernetes的Go客户端库不再解析弃用的对象, +所以Helm调用库时会失败。不幸的是,Helm无法从这种情况下恢复,且无法再管理这样的版本。查看 +[升级发布清单的API版本](#updating-api-versions-of-a-release-manifest) 获取更多如何从这种情况恢复的细节信息。 + +## Updating API Versions of a Release Manifest + +清单manifest是Helm发布对象的一个特性,存储在集群中的密钥(默认)或配置映射的数据字段中。数据字段包含了一个base64编码的gzip压缩的对象 +(对于密钥是一个额外的base 64 编码)。在版本的命名空间中每个版本或修订都对应一个密钥或配置映射。 + +可以使用Helm [mapkubeapis](https://github.com/helm/helm-mapkubeapis) 插件对支持API执行版本升级。查看readme获取更多信息。 + +或者,可以按照这些步骤手动执行发布清单的API版本升级。根据你的配置,应该遵循密钥或配置映射的后台步骤。 + +- 获取最近部署的版本的密钥或配置映射: + - Secrets后台: `kubectl get secret -l + owner=helm,status=deployed,name= --namespace + | awk '{print $1}' | grep -v NAME` + - ConfigMap后台: `kubectl get configmap -l + owner=helm,status=deployed,name= --namespace + | awk '{print $1}' | grep -v NAME` +- 获取最新部署版本细节: + - Secrets后台: `kubectl get secret -n + -o yaml > release.yaml` + - ConfigMap后台: `kubectl get configmap -n + -o yaml > release.yaml` +- 备份版本以便出错时恢复: + - `cp release.yaml release.bak` + - 在紧急情况下恢复: `kubectl apply -f release.bak -n + ` +- 解码发布版本对象: + - Secrets后台: `cat release.yaml | grep -oP '(?<=release: ).*' | base64 -d + | base64 -d | gzip -d > release.data.decoded` + - ConfigMap后台: `cat release.yaml | grep -oP '(?<=release: ).*' | base64 + -d | gzip -d > release.data.decoded` +- 修改清单的API版本。可以使用任意工具(如编辑器)修改。在你解码的发布对象的`manifest`字段。 + (`release.data.decoded`) +- 编码发布对象: + - Secrets 后台: `cat release.data.decoded | gzip | base64 | base64` + - ConfigMap 后台: `cat release.data.decoded | gzip | base64` +- 用新编码的发布对象替换部署的发布文件(`release.yaml`)中`data.release`的值 +- 将文件部署到命名空间: `kubectl apply -f release.yaml -n + ` +- 用支持Kubernetes API版本的chart执行 `helm upgrade` +- 在升级中添加一个描述,不要执行回滚到当前版本之前的版本 diff --git a/content/zh/docs/topics/kubernetes_distros.md b/content/zh/docs/topics/kubernetes_distros.md new file mode 100644 index 0000000000..78fcfc3d0b --- /dev/null +++ b/content/zh/docs/topics/kubernetes_distros.md @@ -0,0 +1,86 @@ +--- +title: "Kubernetes分发指南" +description: "捕获在特定Kubernetes环境中使用Helm的有关信息" +weight: 10 +--- + + +Helm 应该适用于任何[符合标准的Kubernetes版本](https://github.com/cncf/k8s-conformance)(无论是否经过[认证](https://www.cncf.io/certification/software-conformance/))。 + +该文档捕获在特定Kubernetes环境中使用Helm的有关信息。如果需要,请提供更多有关发行版的详细信息(按字母排序)。 + +## AKS + +Helm 使用 [Azure Kubernetes +Service](https://docs.microsoft.com/en-us/azure/aks/kubernetes-helm)。 + +## DC/OS + +Helm 已经测试并工作在 Mesospheres DC/OS 1.11 Kubernetes平台,且不需要额外的配置。 + +## EKS + +Helm 使用Amazon Elastic Kubernetes Service (Amazon EKS): +[Helm 使用 Amazon EKS](https://docs.aws.amazon.com/eks/latest/userguide/helm.html)。 + +## GKE + +Google的GKE托管的Kubernetes平台可以使用Helm工作,且不需要额外配置。 + +## `scripts/local-cluster` 和 Hyperkube + +Hyperkube 通过`scripts/local-cluster.sh`配置的可以正常工作。对于原始Hyperkube你可能需要一些手动配置。 + +## IKS + +Helm 使用[IBM Cloud Kubernetes Service](https://cloud.ibm.com/docs/containers?topic=containers-helm)。 + +## KIND (Docker中Kubernetes) + +Helm 会在 [KIND](https://github.com/kubernetes-sigs/kind) 上定期测试。 + +## KubeOne + +Helm 在用KubeOne配置的集群中可以无警告地工作。 + +## Kubermatic + +Helm在用Kubermatic配置的用户集群中可以无警告地工作。由于种子集群可以以不同的方式建立,因此Helm的支持取决于它们的配置。 + +## MicroK8s + +Helm 可以在[MicroK8s](https://microk8s.io) 使用命令启用:`microk8s.enable helm3` + +## Minikube + +Helm经过测试可以与[Minikube](https://github.com/kubernetes/minikube)一起使用,不需要额外配置。 + +## Openshift + +Helm 在OpenShift Online上工作非常简单, OpenShift Dedicated, OpenShift +Container Platform (version >= 3.6) 或 OpenShift Origin (version >= 3.6)。通过 +[blog](https://blog.openshift.com/getting-started-helm-openshift/)了解更多。 + +## Platform9 + +Helm 预装在 [Platform9 Managed Kubernetes](https://platform9.com/managed-kubernetes/?utm_source=helm_distro_notes)。 +Platform9 通过App Catalog UI和本地Kubernetes CLI访问所有的官方Helm chart。可以手动添加其他仓库。 +更多细节可以参考 [Platform9 App +Catalog](https://platform9.com/support/deploying-kubernetes-apps-platform9-managed-kubernetes/?utm_source=helm_distro_notes)。 + +## Ubuntu 和 `kubeadm` + +Kubernetes 已知在以下Linux分发版本中由`kubeadm`引导启动: + +- Ubuntu 16.04 +- Fedora release 25 + +有些Helm版本 (v2.0.0-beta2) 需要 `export KUBECONFIG=/etc/kubernetes/admin.conf` +或创建一个`~/.kube/config`。 + +## VMware Tanzu Kubernetes Grid + +Helm在VMware Tanzu Kubernetes Grid即TKG上运行时不需要改变配置。 +Tanzu CLI可以管理 [helm-controller](https://fluxcd.io/flux/components/helm/) 的安装包, +允许以声明的方式管理Helm chart 版本。 +TKG文档提供了关于[CLI-Managed Packages](https://docs.vmware.com/en/VMware-Tanzu-Kubernetes-Grid/1.6/vmware-tanzu-kubernetes-grid-16/GUID-packages-user-managed-index.html#package-locations-and-dependencies-5) 的更多详细内容。 diff --git a/content/zh/docs/topics/library_charts.md b/content/zh/docs/topics/library_charts.md new file mode 100644 index 0000000000..4abcb7e190 --- /dev/null +++ b/content/zh/docs/topics/library_charts.md @@ -0,0 +1,362 @@ +--- +title: "库类型Chart" +description: "阐述库类型chart及使用案例" +weight: 4 +--- + +库类型chart是一种[Helm chart](https://helm.sh/zh/docs/topics/charts),定义了可以由其他chart中Helm +模板共享的chart原语或定义。这允许用户通过chart分享可复用得代码片段来避免重复并保持chart +[干燥](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself)。 + +在Helm 3中引用了库chart,从形式上区别于Helm 2中chart维护的通用或辅助chart。 +作为一个chart类型引入,可以提供: + +- 一种明确区分通用和应用chart的方法 +- 逻辑上阻止安装通用chart +- 通用chart中的未渲染模板可以包含版本组件 +- 允许依赖的chart使用导入的上下文 + +chart维护者可以定义一个通用的chart作为库并且现在可以确信Helm将以标准一致的方式处理chart。 +也意味着通过改变chart类型来分享应用chart中的定义。 + +## 创建一个简单的库chart + +像之前提到的,库chart是一种[Helm chart](https://helm.sh/zh/docs/topics/charts)类型。意味着你可以从创建脚手架chart开始: + +```console +$ helm create mylibchart +Creating mylibchart +``` + +本示例中创建自己的模板需要先删除`templates`目录中的所有文件。 + +```console +$ rm -rf mylibchart/templates/* +``` + +不再需要values文件。 + +```console +$ rm -f mylibchart/values.yaml +``` + +在创建通用代码之前,先快速回顾一下相关Helm概念。[已命名的模板](https://helm.sh/zh/docs/chart_template_guide/named_templates/) +(有时称为局部模板或子模板)是定义在一个文件中的简单模板,并分配了一个名称。在`templates/`目录中, +所有以下划线开始的文件(_)不会输出到Kubernetes清单文件中。因此依照惯例,辅助模板和局部模板被放置在`_*.tpl`或`_*.yaml`文件中。 + +这个示例中,我们要写一个通用的配置映射来创建一个空的配置映射源。在`mylibchart/templates/_configmap.yaml`文件中定义如下: + +```yaml +{{- define "mylibchart.configmap.tpl" -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name | printf "%s-%s" .Chart.Name }} +data: {} +{{- end -}} +{{- define "mylibchart.configmap" -}} +{{- include "mylibchart.util.merge" (append . "mylibchart.configmap.tpl") -}} +{{- end -}} +``` + +这个配置映射结构被定义在名为`mylibchart.configmap.tpl`的模板文件中。`data`是一个空源的配置映射, +这个文件中另一个命名的模板是`mylibchart.configmap`。这个模板包含了另一个模板`mylibchart.util.merge`, +会使用两个命名的模板作为参数,称为`mylibchart.configmap`和`mylibchart.configmap.tpl`。 + +复制方法`mylibchart.util.merge`是`mylibchart/templates/_util.yaml`文件中的一个命名模板。 +是[通用Helm辅助Chart](#the-common-helm-helper-chart)的实用工具。因为它合并了两个模板并覆盖了两个模板的公共部分。 + +```yaml +{{- /* +mylibchart.util.merge will merge two YAML templates and output the result. +This takes an array of three values: +- the top context +- the template name of the overrides (destination) +- the template name of the base (source) +*/}} +{{- define "mylibchart.util.merge" -}} +{{- $top := first . -}} +{{- $overrides := fromYaml (include (index . 1) $top) | default (dict ) -}} +{{- $tpl := fromYaml (include (index . 2) $top) | default (dict ) -}} +{{- toYaml (merge $overrides $tpl) -}} +{{- end -}} +``` + +当chart希望使用通过配置自定义其通用代码时,这一点就非常重要。 + +最后,将chart类型修改为`library`。需要按以下方式编辑`mylibchart/Chart.yaml`: + +```yaml +apiVersion: v2 +name: mylibchart +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +# type: application +type: library + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application and it is recommended to use it with quotes. +appVersion: "1.16.0" +``` + +这个库chart现在可以分享了,并且配置映射定义可以复用了。 + +此时,有必要去检测一下chart是否变成了库chart: + +```console +$ helm install mylibchart mylibchart/ +Error: library charts are not installable +``` + +## 使用简单的库chart + +现在可以使用库chart了,这意味着要创建另一个脚手架chart: + +```console +$ helm create mychart +Creating mychart +``` + +只需创建一个配置映射,需要再次清空模板文件: + +```console +$ rm -rf mychart/templates/* +``` + +我们需要在Helm模板中创建简单的配置映射,看起来类似下面这样: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name | printf "%s-%s" .Chart.Name }} +data: + myvalue: "Hello World" +``` + +我们将复用已经在`mylibchart`中创建的公共代码。在`mychart/templates/configmap.yaml`文件中构建配置映射如下: + +```yaml +{{- include "mylibchart.configmap" (list . "mychart.configmap") -}} +{{- define "mychart.configmap" -}} +data: + myvalue: "Hello World" +{{- end -}} +``` + +可以看到这简化了我们通过继承为添加了标准属性的公共配置映射定义必须要做的事情。在模板中添加了配置,在这个示例中的数据key +`myvalue`和值。这个配置会覆盖公共配置映射中的空源。因为我们在上一节中提到的辅助方法`mylibchart.util.merge`,这是可行的。 + +为了能使用通用代码,我们需要添加`mylibchart`作为依赖。将以下内容添加到`mychart/Chart.yaml`文件的末尾: + +```yaml +# My common code in my library chart +dependencies: +- name: mylibchart + version: 0.1.0 + repository: file://../mylibchart +``` + +这包含了作为文件系统动态依赖的库chart,和我们的应用chart位于同一父路径下。由于将库chart作为动态依赖, +我们需要执行`helm dependency update`,它会拷贝库chart到你的`charts/`目录。 + +```console +$ helm dependency update mychart/ +Hang tight while we grab the latest from your chart repositories... +...Successfully got an update from the "stable" chart repository +Update Complete. ⎈Happy Helming!⎈ +Saving 1 charts +Deleting outdated charts +``` + +现在我们准备好部署chart了。安装之前,需要先检测渲染过的模板。 + +```console +$ helm install mydemo mychart/ --debug --dry-run +install.go:159: [debug] Original chart version: "" +install.go:176: [debug] CHART PATH: /root/test/helm-charts/mychart + +NAME: mydemo +LAST DEPLOYED: Tue Mar 3 17:48:47 2020 +NAMESPACE: default +STATUS: pending-install +REVISION: 1 +TEST SUITE: None +USER-SUPPLIED VALUES: +{} + +COMPUTED VALUES: +affinity: {} +fullnameOverride: "" +image: + pullPolicy: IfNotPresent + repository: nginx +imagePullSecrets: [] +ingress: + annotations: {} + enabled: false + hosts: + - host: chart-example.local + paths: [] + tls: [] +mylibchart: + global: {} +nameOverride: "" +nodeSelector: {} +podSecurityContext: {} +replicaCount: 1 +resources: {} +securityContext: {} +service: + port: 80 + type: ClusterIP +serviceAccount: + annotations: {} + create: true + name: null +tolerations: [] + +HOOKS: +MANIFEST: +--- +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +data: + myvalue: Hello World +kind: ConfigMap +metadata: + labels: + app: mychart + chart: mychart-0.1.0 + release: mydemo + name: mychart-mydemo +``` + +这个看起来像是我们需要的用`myvalue: Hello World`覆盖的配置映射。现在安装: + +```console +$ helm install mydemo mychart/ +NAME: mydemo +LAST DEPLOYED: Tue Mar 3 17:52:40 2020 +NAMESPACE: default +STATUS: deployed +REVISION: 1 +TEST SUITE: None +``` + +我们可以检索这个版本并看到实际的版本已经加载。 + +```console +$ helm get manifest mydemo +--- +# Source: mychart/templates/configmap.yaml +apiVersion: v1 +data: + myvalue: Hello World +kind: ConfigMap +metadata: + labels: + app: mychart + chart: mychart-0.1.0 + release: mydemo + name: mychart-mydemo + ``` + +## Library Chart Benefits + +由于它们不能作为独立的chart,库chart可以利用一下功能: + +- `.Files` 对象引用父chart的文件路径,而不是库chart的本地路径 +- `.Values` 对象与父chart相同,但与[subcharts](https://helm.sh/zh/docs/chart_template_guide/subcharts_and_globals)(接收在父级的header中配置的值)相反。 + +## The Common Helm Helper Chart + +```markdown +注意:GitHub上的公共Helm辅助Chart不再被积极维护了,且该仓库已弃用并归档。 +``` + +这个[chart](https://github.com/helm/charts/tree/master/incubator/common)是公共chart的初始模式。 +它提供的应用程序反映了Kubernetes chart开发的最佳实践。最棒的是你开发chart时可以立即使用易用的共享代码。 + +这里有一种快速使用它的方法。更多细节请查看[README](https://github.com/helm/charts/blob/master/incubator/common/README.md)。 + +再创建一个脚手架: + +```console +$ helm create demo +Creating demo +``` + +使用辅助chart中的公共代码。首先编辑负载文件`demo/templates/deployment.yaml`如下: + +```yaml +{{- template "common.deployment" (list . "demo.deployment") -}} +{{- define "demo.deployment" -}} +## Define overrides for your Deployment resource here, e.g. +apiVersion: apps/v1 +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + {{- include "demo.selectorLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "demo.selectorLabels" . | nindent 8 }} + +{{- end -}} +``` + +现在这个service文件`demo/templates/service.yaml`变成了下面这样: + +```yaml +{{- template "common.service" (list . "demo.service") -}} +{{- define "demo.service" -}} +## Define overrides for your Service resource here, e.g. +# metadata: +# labels: +# custom: label +# spec: +# ports: +# - port: 8080 +{{- end -}} +``` + +这些模板显示了如何从辅助模板中继承公共代码来将你的代码简化到资源的配置或自定义。 + +为了能使用公共代码,我们需要添加一个`common`依赖。在`demo/Chart.yaml`文件最后啊添加以下内容: + +```yaml +dependencies: +- name: common + version: "^0.0.5" + repository: "https://charts.helm.sh/incubator/" +``` + +注意:需要添加`incubator`仓库到Helm仓库列表中(`helm repo add`)。 + +由于我们引用了一个chart作为动态依赖,需要执行`helm dependency update`。这样会将辅助chart拷贝到你的`charts/`目录。 + +由于辅助chart使用了一些Helm2的结构,所以需要在`demo/values.yaml`中添加以下内容,确保在Helm +3脚手架中chart更新时可以加载`nginx`镜像: + +```yaml +image: + tag: 1.16.0 +``` + +在部署之前可以使用 `helm lint` 和 `helm template` 命令测试chart模板是否正确。 + +如果可以正常运行,使用 `helm install` 部署。 diff --git a/content/zh/docs/topics/permissions_sql_storage_backend.md b/content/zh/docs/topics/permissions_sql_storage_backend.md new file mode 100644 index 0000000000..35ee50a235 --- /dev/null +++ b/content/zh/docs/topics/permissions_sql_storage_backend.md @@ -0,0 +1,49 @@ +--- +title: "SQL存储后端的权限管理" +description: "了解SQL存储后端的权限设置" +--- + +该文档旨在提供用户使用SQL存储后端时设置和管理权限的指导。 + +## 介绍 + +为了处理权限,Helm利用了Kubernetes的RBAC特性。使用SQL存储后端时, +Kubernetes的角色不能被用于确认用户是否可以访问给定的资源。该文档会展示如果创建和管理权限。 + +## 初始化 + +Helm CLI 首先会连接您的数据库。客户端会确认数据库是否已经预先初始化,如果没有, +它会自动处理必要的安装。初始化需要在public架构的admin权限,或者至少可以做以下事情: + +* 创建一个表 +* 在public架构授予权限 + +当你的数据库执行过迁移操作之后,其他角色就可以使用客户端了。 + +## PostgreSQL向非管理员用户授权 + +管理权限时,SQL后端驱动会利用PostgreSQL的[RLS](https://www.postgresql.org/docs/9.5/ddl-rowsecurity.html)( +行安全级别)特性。RLS允许所有用户读/写同一张表,如果没有明确说明,不允许操作相同的行。 +默认情况下,运行`helm list`时任何角色如果没有明确授权正确的权限会返回空列表,并且不能检索或修改集群中的任何资源。 + +我们来看看如何为给定角色授予访问特定命名空间的权限: + +```sql +CREATE POLICY ON releases_v1 FOR ALL TO USING (namespace = 'default'); +``` + +这个命令在使用`namespace = 'default'`条件时会授权给角色`role`所有资源读和写操作权限。 +在创建这个策略时,运行`helm list`时会代表角色`role`在默认的命名空间中连接数据库, +因而能看到命名空间中所有的版本,并能修改和删除它们。 + +权限可以按照RLS粒度进行管理,人们可能会对表的不同列的访问限制感兴趣: +* key +* type +* body +* name +* namespace +* version +* status +* owner +* createdAt +* modifiedAt diff --git a/content/zh/docs/topics/plugins.md b/content/zh/docs/topics/plugins.md new file mode 100644 index 0000000000..097091e82f --- /dev/null +++ b/content/zh/docs/topics/plugins.md @@ -0,0 +1,312 @@ +--- +title: "Helm插件指南" +description: "介绍如何使用和创建插件来扩展Helm功能。" +weight: 12 +--- + +Helm插件是一个可以通过`helm` CLI访问的工具,但不是Helm的内置代码。 + +已有插件可以搜索[GitHub](https://github.com/search?q=topic%3Ahelm-plugin&type=Repositories)。 + +该指南描述如何使用和创建插件。 + +## 概述 + +Helm插件是与Helm无缝集成的附加工具。插件提供一种扩展Helm核心特性集的方法,但不需要每个新的特性都用Go编写并加入核心工具中。 + +Helm插件有以下特性: + +- 可以在不影响Helm核心工具的情况下添加和移除。 +- 可以用任意编程语言编写。 +- 与Helm集成,并展示在`helm help`和其他地方。 + +Helm插件存在与`$HELM_PLUGINS`。你可以找到该变量的当前值,包括不设置环境变量的默认值,使用`helm env`命令。 + +Helm插件模型部分基于Git的插件模型。为此,你有时可能听到`helm`已插件为基础被用作_porcelain_ 层。这是一种Helm提供用户体验和顶级处理逻辑的简写方式。 +而插件执行所需操作的“细节工作”。 + +## 安装一个插件 + +插件使用 `$ helm plugin install ` 命令安装插件。你可以在本地文件系统上传一个路径或远程仓库url给插件。The `helm plugin install` +命令会克隆或拷贝给定路径的插件到 `$HELM_PLUGINS`。 + +```console +$ helm plugin install https://github.com/adamreese/helm-env +``` + +如果是插件tar包,仅需解压插件到`$HELM_PLUGINS`目录。也可以用tar包的url直接安装: +`helm plugin install https://domain/path/to/plugin.tar.gz`。 + +## 构建插件 + +在很多方面,插件类似于chart。每个插件有个顶级目录和一个`plugin.yaml`文件。 + +```console +$HELM_PLUGINS/ + |- last/ + | + |- plugin.yaml + |- last.sh + +``` + +上述示例中,`last`插件包含在`last`目录中。有两个文件:`plugin.yaml`(必需)和一个可执行脚本,`last.sh`(可选)。 + +插件的核心是一个简单的YAML文件`plugin.yaml`。下面是一个插件YAML,用于获取最新的release名称: + +```yaml +name: "last" +version: "0.1.0" +usage: "get the last release name" +description: "get the last release name" +ignoreFlags: false +command: "$HELM_BIN --host $TILLER_HOST list --short --max 1 --date -r" +platformCommand: + - os: linux + arch: i386 + command: "$HELM_BIN list --short --max 1 --date -r" + - os: linux + arch: amd64 + command: "$HELM_BIN list --short --max 1 --date -r" + - os: windows + arch: amd64 + command: "$HELM_BIN list --short --max 1 --date -r" +``` + +`name`是插件名称。当Helm执行此插件时使用此名称。(比如,`helm NAME`会调用此插件)。 + +上述示例中,_`name`应该匹配目录名称_,意味着`last`目录中应该包含 `name: last` 插件。 + +`name`的限制: + +- `name` 无法复用现有的 `helm` 顶级命令。 +- `name` 的字符必须限制为ASCII a-z, A-Z, 0-9, `_` 和 `-`。 + +`version` 是插件的语义化2的版本。 `usage` 和 `description` 用于生成命令的帮助文本。 + +`ignoreFlags` 开关告诉 Helm _不要_ 给插件传递的参数。因此如果一个插件使用 `helm myplugin --foo`调用且 +`ignoreFlags: true`,那么`--foo`会被悄悄忽略。 + +最后,尤其重要的是 `platformCommand` 或 `command` 是插件调用时执行的命令。`platformCommand` 部分定义了命令在 +系统/架构的特定变体。以下规则用于决定使用哪个命令: + +- 如果`platformCommand`存在,会优先被搜索。 +- 如果`os` 和 `arch` 匹配了当前平台,搜索会停止并使用命令。 +- 如果`os`匹配且没有匹配 `arch` ,命令会被使用。 +- 如果没有匹配`platformCommand`,会使用默认的`command`。 +- 如果没有匹配 `platformCommand` 且不存在 `command`,Helm会报错退出。 + +环境变量会在插件执行前被插入。上述模式说明了表示插件所在位置的首选方法。 + +有一些使用插件命令的策略: + +- 如果插件中包含可执行文件,可执行文件针对于 `platformCommand:`或`command:`命令,应该打包到插件目录中。 +- `platformCommand:` 或者 `command:` 行会在执行之前展开任何环境变量。`$HELM_PLUGIN_DIR`会指向插件目录。 +- 命令本身不是在shell中执行的。 所以不能一行一个shell脚本。 +- Helm在环境变量中插入很多配置。查看环境变量获取可用信息。 +- Helm对插件语言不做任何假设。你想写什么写什么。 +- `-h` 和 `--help`命令负责实现特定的帮助文本。Helm会在`helm help` 和 `helm help myplugin`中使用`usage` + 和 `description`,但不处理`helm myplugin --help`。 + +## 下载插件 + +默认情况下,Helm能够使用HTTP/S拉取chart。从Helm 2.4.0开始,插件有一种能力从任意来源下载chart。 + +插件应该在`plugin.yaml`(顶层的)文件中声明这个特殊能力: + +```yaml +downloaders: +- command: "bin/mydownloader" + protocols: + - "myprotocol" + - "myprotocols" +``` + +如果这个插件已经安装,Helm可以通过调用`command`可以使用指定的协议方案与存储仓库进行交互。 +特殊仓库的添加与常规仓库类似:`helm repo add favorite myprotocol://example.com/`。 +特殊仓库的的规则也和常规仓库相同:为了发现和缓存chart的可用列表,Helm必须下载`index.yaml`文件。 + +已定义的命令可以通过以下结构调用: `command certFile keyFile caFile full-URL`。SSL证书有仓库定义,存储在 +`$HELM_REPOSITORY_CONFIG`(即:`$HELM_CONFIG_HOME/repositories.yaml`)。 +下载器插件将原始内容使用stdout输出并使用stderr报告错误。 + +下载器命令也支持子命令和参数,允许在`plugin.yaml`指定,比如`bin/mydownloader subcommand -d`。 +如果你想在相同的可执行文件中执行主要的插件命令和下载器命令,这就变得很有用,但每个命令都有不同的子命令。 + +## 环境变量 + +当Helm执行插件时,会传递外部环境变量给插件,且会加入一些额外的环境变量。 + +像 `KUBECONFIG` 这样的变量,如果是在外部环境中设置的,则是为插件设置的。 + +要保证设置以下变量: + +- `HELM_PLUGINS`: 插件目录路径。 +- `HELM_PLUGIN_NAME`: `helm`调用的插件名称。 +- `HELM_PLUGIN_DIR`: 包含插件的目录。 +- `HELM_BIN`: (当前用户的)`helm`命令的路径。 +- `HELM_DEBUG`: 表示helm是否设置了debug。 +- `HELM_REGISTRY_CONFIG`: 注册配置的位置(如果启用)。注意Helm使用注册中心是实验特性。 +- `HELM_REPOSITORY_CACHE`: 缓存文件路径。 +- `HELM_REPOSITORY_CONFIG`: 配置文件路径。 +- `HELM_NAMESPACE`: `helm`命令指定的命名空间(一般使用`-n`参数)。 +- `HELM_KUBECONTEXT`: `helm`命令给定的Kubernetes配置上下文的名称。 + +另外,如果明确指定Kubernetes配置文件,需要配置成 `KUBECONFIG`变量。 + +## 参数解析说明 + +当执行插件时,Helm会解析自己的全局参数。这些参数都不会传递给插件。 + +- `--debug`: 如果指定, `$HELM_DEBUG` 设置为 `1` +- `--registry-config`: 链接到了 `$HELM_REGISTRY_CONFIG` +- `--repository-cache`: 链接到了 `$HELM_REPOSITORY_CACHE` +- `--repository-config`: 链接到了 `$HELM_REPOSITORY_CONFIG` +- `--namespace` 和 `-n`: 链接到了 `$HELM_NAMESPACE` +- `--kube-context`: 链接到了 `$HELM_KUBECONTEXT` +- `--kubeconfig`: 链接到了 `$KUBECONFIG` + +插件 _应该_ 使用`-h` 和 `--help`显示帮助文本然后退出。在所有其他情况下,插件根据需要使用参数。 + +## 提供shell自动补全 + +从Helm 3.2开始,作为Helm现有的自动补全机制的一部分,插件可以选择性提供对shell自动补全的支持。 + +### 静态自动补全 + +如果插件提供了自己的参数或者子命令,可以通过位于插件根目录的`completion.yaml`文件通知 Helm。 +`completion.yaml`格式如下: + +```yaml +name: +flags: +- +- +validArgs: +- +- +commands: + name: + flags: + - + - + validArgs: + - + - + commands: + +``` + +注意: + +1. 所有部分都是可选的,应该在适用时提供。 +2. 参数不该包含`-` 或 `--`前缀。 +3. 可以而且应该指定端的和长的参数。短参数不需要与其对应的长格式关联,但是都应被列出。 +4. 参数不需要以任何方式排序,但是需要列举在文件子命令层次结构的正确位置。 +5. Helm现有的全局参数已经由Helm的自动补全机制处理,因此插件不需要指定以下参数:`--debug`,`--namespace`或`-n`, + `--kube-context`,以及`--kubeconfig`,或者其他全局参数。 +6. `validArgs`列表提供了一个以下子命令的第一个参数可能补全的静态列表。并不总是能事先提供这样一份清单。 + (查看下面的[动态补全](#dynamic-completion)部分),这种情况下`validArgs`部分可以省略。 + +`completion.yaml`文件是完全可选的。如果没有提供,Helm不会为插件提供shell自动补全功能(除非插件支持 [动态补全](#dynamic-completion))。 +并且,添加`completion.yaml`文件是向后兼容的,而且不会影响到插件使用helm旧版本的操作。 + +举个例子,针对[`fullstatus plugin`](https://github.com/marckhouzam/helm-fullstatus),没有子命令但是接受 +与`helm status`命令相同的参数,`completion.yaml`文件如下: + +```yaml +name: fullstatus +flags: +- o +- output +- revision +``` + +一个使用[`2to3 plugin`](https://github.com/helm/helm-2to3)更复杂的例子,`completion.yaml`文件如下: + +```yaml +name: 2to3 +commands: +- name: cleanup + flags: + - config-cleanup + - dry-run + - l + - label + - release-cleanup + - s + - release-storage + - tiller-cleanup + - t + - tiller-ns + - tiller-out-cluster +- name: convert + flags: + - delete-v2-releases + - dry-run + - l + - label + - s + - release-storage + - release-versions-max + - t + - tiller-ns + - tiller-out-cluster +- name: move + commands: + - name: config + flags: + - dry-run +``` + +### Dynamic completion + +也是从Helm 3.2开始,插件可以提供它们自己的动态shell补全。动态补全是补全事先没有定义的参数值或标签值。比如说,补全集群中现在可用的helm发布的名称。 + +对于支持动态补全的插件,必须在根目录中提供一个命名为`plugin.complete`的**可执行**文件。当Helm的自动补全脚本需要为这个插件动态补全时,会执行 +`plugin.complete`文件,传递需要补全的命令行。`plugin.complete`可执行文件需要有判断核实补全选项的逻辑并将其通过Helm补全脚本输出到标准输出。 + +`plugin.complete`文件是完全可选的。如果没有提供,Helm不会为插件提供动态自动补全。并且,添加`plugin.complete`文件是向后兼容的, +而且不会影响到插件使用Helm旧版本的操作。 + +`plugin.complete`脚本的输出应该是以行分隔的列表,例如: + +```console +rel1 +rel2 +rel3 +``` + +当调用`plugin.complete`时,插件环境的设置与调用插件的主脚本时一样。因此,变量 `$HELM_NAMESPACE`,`$HELM_KUBECONTEXT`, +以及所有其他插件变量都已经设置好了,且它们对应的全局标志会被移除。 + +`plugin.complete`文件可以是任何可执行格式;可以是shell脚本,Go程序,或者任何其他Helm可以执行的类型。`plugin.complete`文件 +***必须***有对用户的可执行权限。`plugin.complete`文件 ***必须*** 以成功码退出(0)。 + +在有些场景中,动态补全需要从Kubernetes集群中获取信息。比如,`helm fullstatus`插件需要发布名称作为输入。在`fullstatus`插件中, +针对它的`plugin.complete`脚本提供当前发布名称的补全,执行`helm list -q`即可输出结果。 + +如果想插件执行和插件补全使用同一个可执行文件,`plugin.complete`脚本可以使用特殊的参数或标签调用主插件执行文件;当主插件执行文件检测到特殊的参数或标签, +它就知道应该执行补全。在以下示例中,`plugin.complete`执行如下: + +```sh +#!/usr/bin/env sh + +# "$@" is the entire command-line that requires completion. +# It is important to double-quote the "$@" variable to preserve a possibly empty last parameter. +$HELM_PLUGIN_DIR/status.sh --complete "$@" +``` + +`fullstatus`脚本的实际脚本(`status.sh`)必须查找`--complete`,如果存在,打印出合适的补全。 + +### 提示和技巧 + +1. 脚本会自动过滤掉不匹配输入的补全。因此,插件会返回所有相关的补全,而不删除与用户输入不匹配的补全。比如,如果命令行是 + `helm fullstatus ngin`,不仅仅是以`ngin`开头的,`plugin.complete` 脚本可以打印 *所有* (`default`默认命名空间)的发布名称, + 脚本只会保留以`ngin`开头的。 +2. 为了简化动态补全支持,尤其是如果你有个复杂的插件,你可以有你的`plugin.complete`脚本调用你的主插件脚本并请求补全选项。查看上面 + [动态补全](#dynamic-completion)的例子。 +3. 要调试动态补全和`plugin.complete`文件,可以运行以下命令查看补全效果: + - `helm __complete `。比如: + - `helm __complete fullstatus --output js`, + - `helm __complete fullstatus -o json ""` diff --git a/content/zh/docs/topics/provenance.md b/content/zh/docs/topics/provenance.md new file mode 100644 index 0000000000..5a1531fcb1 --- /dev/null +++ b/content/zh/docs/topics/provenance.md @@ -0,0 +1,227 @@ +--- +title: "Helm来源和完整性" +description: "描述如何验证Chart的完整性和来源。" +weight: 5 +--- + +Helm有一个来源工具帮助chart用户检测包的完整性和来源。使用基于PKI,GnuPG及流行包管理器的行业标准工具,Helm可以生成和检测签名文件。 + +## 概述 + +完整性是通过比较chart的出处记录来建立的。出处记录存储在 _出处文件_,和打包好的chart放在一起。比如, +如果有个名为`myapp-1.2.3.tgz`的chart,则它的出处文件是`myapp-1.2.3.tgz.prov`。 + +出处文件会在打包时生成(`helm package --sign ...`),并可以通过多重命名检查,尤其是`helm install --verify`。 + +## 工作流 + +这部分描述有效使用源数据的潜在工作流。 + +前置条件: + +- 合法的二进制格式(非ASCII包裹)的PGP密钥对 +- `helm`命令行工具 +- GnuPG命令行工具(可选) +- Keybase命令行工具(可选) + +**注意:** 如果你的PGP私钥有密码,系统将提示你为所有支持`--sign`选项的命令输入密码。 + +创建新的chart与之前一样: + +```console +$ helm create mychart +Creating mychart +``` + +一旦准备好打包了,使用`helm package`命令时添加`--sign`参数,并且指定已知的字符串key和包含相应私钥的秘钥环: + +```console +$ helm package --sign --key 'John Smith' --keyring path/to/keyring.secret mychart +``` + +**注意:** `--key`参数的值必须是对应key的`uid`(在`gpg --list-keys`输出列表中)的子字符串,比如名字或者email。 +**指纹码 _不能_ 使用。** + +**提示:** 针对GnuPG用户,你的私钥的keyring在`~/.gnupg/secring.gpg`。你可以使用`gpg --list-secret-keys`列出你需要的key。 + +**警告:** GnuPG v2版在默认位置`~/.gnupg/pubring.kbx`使用了新格式`kbx`存储私钥的keyring。使用以下命令将你的keyring转换到传统的gpg格式: + +```console +$ gpg --export >~/.gnupg/pubring.gpg +$ gpg --export-secret-keys >~/.gnupg/secring.gpg +``` + +此时,您应该同时看到了`mychart-0.1.0.tgz`和`mychart-0.1.0.tgz.prov`。 这两个文件最终都会被上传到对应的chart仓库。 + +您可以使用`helm verify`验证chart: + +```console +$ helm verify mychart-0.1.0.tgz +``` + +失败的验证如下: + +```console +$ helm verify topchart-0.1.0.tgz +Error: sha256 sum does not match for topchart-0.1.0.tgz: "sha256:1939fbf7c1023d2f6b865d137bbb600e0c42061c3235528b1e8c82f4450c12a7" != "sha256:5a391a90de56778dd3274e47d789a2c84e0e106e1a37ef8cfa51fd60ac9e623a" +``` + +在安装时同时验证,使用`--verify`参数。 + +```console +$ helm install --generate-name --verify mychart-0.1.0.tgz +``` + +如果keyring包含的与签名chart关联的公钥不在默认位置,需要在打包`helm package`时使用`--keyring PATH`指定keyring的path。 + +如果验证失败,chart的安装会在渲染前中止。 + +### 使用Keybase.io证书 + +[Keybase.io](https://keybase.io) 服务使得建立加密身份的信任链变得很容易。 + +前置条件: + +- 配置 Keybase.io 账户 +- 本地已安装GnuPG +- 本地已安装`keybase` CLI + +#### 对包签名 + +第一步是将keybase秘钥导入本地的GnuPG的秘钥环keyring: + +```console +$ keybase pgp export -s | gpg --import +``` + +这会将你的Keybase秘钥转成OpenPGP格式,然后将其导入本地的`~/.gnupg/secring.gpg`文件。 + +可以运行`gpg --list-secret-keys`进行双重检测。 + +```console +$ gpg --list-secret-keys +/Users/mattbutcher/.gnupg/secring.gpg +------------------------------------- +sec 2048R/1FC18762 2016-07-25 +uid technosophos (keybase.io/technosophos) +ssb 2048R/D125E546 2016-07-25 +``` + +注意你的秘钥会有一个标识字符串: + +```console +technosophos (keybase.io/technosophos) +``` + +这个是秘钥的全名。 + +然后,可以使用`helm package`打包和签名。确保在`--key`参数中使用名称的一部分。 + +```console +$ helm package --sign --key technosophos --keyring ~/.gnupg/secring.gpg mychart +``` + +`package`命令会生成一个`.tgz`文件和一个`.tgz.prov`文件。 + +#### 验证包 + +您可以使用类似的方法验证被其他Keybase秘钥签名的chart。比如你要验证使用`keybase.io/technosophos`签名的包,可使用`keybase`工具: + +```console +$ keybase follow technosophos +$ keybase pgp pull +``` + +上面第一个命令追踪了用户`technosophos`。然后使用`keybase pgp pull`下载你追踪的所有的账户的OpenPGP秘钥,并把它们放置在GnuPG秘钥环中(`~/.gnupg/pubring.gpg`)。 + +此时,就可以使用`helm verify`或者其他带`--verify`的命令: + +```console +$ helm verify somechart-1.2.3.tgz +``` + +### chart无法验证的原因 + +一般失败的原因有这些: + +- The `.prov` file is missing or corrupt. 说明有配置错误或者原有维护者没有创建源文件。 +- The key used to sign the file is not in your keyring. 说明这个签名chart的秘钥不是你已经注明为信任的秘钥。 +- The verification of the `.prov` file failed. 这说明chart或者源数据有错误。 +- The file hashes in the provenance file do not match the hash of the archive + file. 表明chart包已经被篡改。 + +如果验证失败,就有理由不信任该包。 + +## 来源文件 + +来源文件包含chart的YAML文件加上一些验证信息。来源文件会自动生成。 + +会添加下列源数据: + +- chart文件(`Chart.yaml`) 让人和工具都可以看到chart中的内容。 +- chart包(`.tgz`文件)签名(SHA256,就像Docker),可以用来验证chart包的完整性。 +- 使用了OpenPGP算法签名所有内容(查看[Keybase.io](https://keybase.io),一种使签名和验证更简单的新式方法)。 + +这些内容的结合给予了用户以下保证: + +- 包本身不会被篡改(`.tgz`包的校验和). +- 发布包的人是可知的(通过GnuPG/PGP签名). + +文件格式类似这样: + +```console +Hash: SHA512 + +apiVersion: v2 +appVersion: "1.16.0" +description: Sample chart +name: mychart +type: application +version: 0.1.0 + +... +files: + mychart-0.1.0.tgz: sha256:d31d2f08b885ec696c37c7f7ef106709aaf5e8575b6d3dc5d52112ed29a9cb92 +-----BEGIN PGP SIGNATURE----- + +wsBcBAEBCgAQBQJdy0ReCRCEO7+YH8GHYgAAfhUIADx3pHHLLINv0MFkiEYpX/Kd +nvHFBNps7hXqSocsg0a9Fi1LRAc3OpVh3knjPfHNGOy8+xOdhbqpdnB+5ty8YopI +mYMWp6cP/Mwpkt7/gP1ecWFMevicbaFH5AmJCBihBaKJE4R1IX49/wTIaLKiWkv2 +cR64bmZruQPSW83UTNULtdD7kuTZXeAdTMjAK0NECsCz9/eK5AFggP4CDf7r2zNi +hZsNrzloIlBZlGGns6mUOTO42J/+JojnOLIhI3Psd0HBD2bTlsm/rSfty4yZUs7D +qtgooNdohoyGSzR5oapd7fEvauRQswJxOA0m0V+u9/eyLR0+JcYB8Udi1prnWf8= +=aHfz +-----END PGP SIGNATURE----- +``` + +注意YAML部分包含了两个文档,(用`...\n`分隔)。第一个文档是`Chart.yaml`内容。第二个是文件内容打包时文件名的SHA-256校验和。 + +签名是标准的PGP签名,用于[防篡改](https://www.rossde.com/PGP/pgp_signatures.html)。 + +## Chart仓库 + +Chart仓库是一个Helm chart的集合。 + +Chart仓库必须要保证通过指定的http请求提供源文件,同时要确保使用同样URI路径的chart是可用的。 + +比如,如果包的基础URL是`https://example.com/charts/mychart-1.2.3.tgz`,则若是存在的源文件地址`https://example.com/charts/mychart-1.2.3.tgz.prov`必须能访问。 + +从终端用户的角度来看,`helm install --verify myrepo/mychart-1.2.3`应该同时下载chart和源文件,且不需要额外的用户配置或操作。 + +## 建立权威和真实性 + +当处理信任链系统时,建立签名者的权威变得非常重要。或者简单来说,上面的系统实际上取决于你信任的签名chart的人。也就意味着你需要信任签名者的公钥。 + +Helm的一个设计决策是Helm项目不会将自己作为必须的一方插入到信任链中。我们不想针对所有的chart签名者成为“证书颁发机构”, +而是更喜欢分布式模型,这是我们选择OpenPGP作为我们的基础技术的原因之一。所以在建立权威的问题上,在chart 2中或多或少没有定义这一步(会在接下来的Helm +3中决定)。 + +当然,对于使用源系统感兴趣的人,我们有一些提示和建议: + +- [Keybase](https://keybase.io)平台为可靠信息提供了一个公共的中心化的仓库。 + - 你可以使用Keybase存储你的key或者获取其他人的公钥。 + - Keybase还有非常好的文档 + - 我们还没有测试的时候,Keybase的“安全站点”特性可以提供Helm chart。 + - 基础想法是一个官方的“chart审核人”使用他(她)的私钥签名,然后上传源文件到chart仓库。 + - 该想法的一些做法是在仓库的`index.yaml`文件中列出一些合法的秘钥。 + diff --git a/content/zh/docs/topics/rbac.md b/content/zh/docs/topics/rbac.md new file mode 100644 index 0000000000..0db5490b45 --- /dev/null +++ b/content/zh/docs/topics/rbac.md @@ -0,0 +1,159 @@ +--- +title: "基于角色的访问控制" +description: "解释Helm如何与Kubernetes基于角色的访问控制交互。" +weight: 11 +--- + +在Kubernetes中,向用户或应用程序特定的服务账户授予角色是确保你的应用程序在指定范围运行的最佳实践。 +有关服务账户权限的更多信息请查看[官方Kubernetes文档](https://kubernetes.io/docs/admin/authorization/rbac/#service-account-permissions)。 + +从Kubernetes 1.6开始,基于角色的访问控制默认是启用的。RBAC允许你根据你组织中的用户和角色指定行为类型。 + +有了RBAC,您可以: + +- 授权特殊操作 (创建集群范围内的资源,比如新角色) 给管理员 +- 限制用户在指定命名空间创建资源的能力 (pod,持久卷,工作负载),或者是集群范围内(资源配额,角色,自定义资源) +- 限制用户在特定命名空间或集群范围内查看资源的能力 + +该指南适用于希望限制用户与Kubernetes API交互范围的管理员。 + +## 管理用户账户 + +所有的Kubernetes集群有两类用户:Kubernetes管理的服务账户和普通用户。 + +普通用户被认为是有外部独立的服务管理。一个管理员分发私钥,用户的Keystone或者Google账户,甚至用户名密码列表的文件。 +在这方面,Kubernetes没有表示普通用户账户的对象。普通用户无法通过API调用添加到集群中。 + +相反,服务账户是由Kubernetes API管理的账户。被绑定到指定的命名空间,且有API服务或手动调用API自动创建。 +服务账户绑定到了一组作为密钥存储的凭据。它们被挂载到pod中,允许集群内进程与Kubernetes API交互。 + +API请求被绑定到了普通用户或者服务账户,或者被视作匿名请求。意味着集群内或外部的每个来自人类用户使用`kubectl`的进程, +到node的kubelet,或到control plane的成员,向API server 发送请求时必须进行身份验证。否则被视为匿名用户。 + +## 角色,集群角色,角色绑定,及集群角色绑定 + +在Kubernetes中,用户账户和服务账户只能查看和编辑允许他们访问的资源。通过使用角色和角色绑定授予访问权限。 +角色和角色绑定是绑定在特定的命名空间,授予用户查看和/或编辑角色提供访问的命名空间的资源。 + +在集群范围内,称为集群角色和集群角色绑定。授予用户集群角色则允许他们有查看和编辑整个集群资源的权限。同样也需要查看和编辑 +集群范围的资源(命名空间,资源配额,节点)。 + +集群角色可以通过角色绑定中引用被绑定到一个特定的命名空间,通常以这种方式使用管理`admin`,编辑`edit`和查看`view`默认的集群角色。 + +有一些集群中默认可用的集群角色。旨在成为面向用户的角色。包括超级用户角色(`cluster-admin`), 以及具有更细粒度访问权限的角色 (`admin`, +`edit`,`view`)。 + +| 默认集群角色 | 默认集群角色绑定 | 描述 +|---------------------|----------------------------|------------- +| `cluster-admin` | `system:masters` group | 允许超级用户访问任意资源并执行任意操作。在集群角色绑定中使用时,它提供了对集群和所有命名空间中的每个资源的完全控制。在角色绑定中使用时,提供了对角色绑定的命名空间的每个资源完全控制,包括命名空间本身。 +| `admin` | None | 允许管理员访问,旨在使用角色绑定在命名空间中授权。如果使用一个角色绑定,允许对命名空间中的大部分资源进行读、写,包括在命名空间中创建角色和角色绑定。不允许对资源配额或命名空间本身进行写操作。 +| `edit` | None | 允许对命名空间中大部分的对象进行读写。不允许查看或修改角色或角色绑定。 +| `view` | None | 允许对命名空间中大部分的对象进行读操作。不允许查看角色或角色绑定。由于密钥需要升级查看,所以不允许该角色查看。 + +## 使用RBAC限制用户账户的访问 + +现在我们明白了基本的基于角色的访问控制,让我们讨论一下管理员如何限制用户的访问范围。 + +### 示例:授权用户特定命名空间的读写操作 + +限制用户访问特定的命名空间,可以使用`edit`或`admin`角色。如果你的chart是用角色或角色绑定创建或交互,应该使用`admin`集群角色。 + +另外,也可以用`cluster-admin`创建个角色绑定。授予用户命名空间范围内的`cluster-admin`操作,提供了命名空间内每个资源的完全访问,包括命名空间本身。 + +对于这个示例,我们可以使用`edit`角色创建一个用户。首先,创建一个命名空间: + +```console +$ kubectl create namespace foo +``` + +现在在命名空间中创建一个角色绑定,授予用户 `edit` 角色。 + +```console +$ kubectl create rolebinding sam-edit + --clusterrole edit \​ + --user sam \​ + --namespace foo +``` + +### 示例:授予用户集群范围内的读写操作 + +如果用户希望安装一个chart来安装集群范围的资源(命名空间,角色,自定义资源等等),则需要集群范围的写操作。 + +这样需要授予用户`admin`或者`cluster-admin`权限。 + +授予用户`cluster-admin`访问权限允许他们访问Kubernetes的所有可用资源,包括使用`kubectl drain`访问节点和其他管理员任务。 +强烈推荐考虑用`admin`权限代替,或者创建一个量身定做的自定义集群角色。 + +```console +$ kubectl create clusterrolebinding sam-view + --clusterrole view \​ + --user sam + +$ kubectl create clusterrolebinding sam-secret-reader + --clusterrole secret-reader \​ + --user sam +``` + +### 示例:授予用户特定命名空间的只读权限 + +你可能已经留意到没有查看密钥的集群角色。处于升级的考虑,`view`集群角色不允许用户读取密钥。Helm默认将版本元数据作为密钥存储。 + +为了用户可以运行`helm list`,他们需要读取这些密钥。为此我们创建一个特殊的 `secret-reader` 集群角色。 + +创建 `cluster-role-secret-reader.yaml`文件并写入以下内容: + +```yaml +apiVersion: rbac.authorization.k8s.io/v1​ +kind: ClusterRole​ +metadata:​ + name: secret-reader​ +rules:​ +- apiGroups: [""]​ + resources: ["secrets"]​ + verbs: ["get", "watch", "list"] +``` + +然后创建集群角色使用: + +```console +$ kubectl create -f clusterrole-secret-reader.yaml​ +``` + +创建完成之后,我们就可以授予一个用户大多数资源的读权限,然后授予他们读取密钥的权限: + +```console +$ kubectl create namespace foo + +$ kubectl create rolebinding sam-view + --clusterrole view \​ + --user sam \​ + --namespace foo + +$ kubectl create rolebinding sam-secret-reader + --clusterrole secret-reader \​ + --user sam \​ + --namespace foo +``` + +### 示例:授予用户集群范围的只读权限 + +在某些情况下,授予用户集群范围的访问权限是有益的。比如,如果一个用户想运行 `helm list --all-namespaces`, +API需要用户有集群范围的访问权限。 + +授予用户上述的 `view` 和 `secret-reader`访问权限,但使用集群角色绑定。 + +```console +$ kubectl create clusterrolebinding sam-view + --clusterrole view \​ + --user sam + +$ kubectl create clusterrolebinding sam-secret-reader + --clusterrole secret-reader \​ + --user sam +``` + +## 其他想法 + +上述示例使用了Kubernetes提供的默认集群角色。The examples shown above utilize the default ClusterRoles provided with +Kubernetes. 对用户授予更细粒度的资源访问权限,请查看创建自定义的角色和集群角色的[Kubernetes +文档](https://kubernetes.io/docs/reference/access-authn-authz/rbac/)。 diff --git a/content/zh/docs/topics/registries.md b/content/zh/docs/topics/registries.md new file mode 100644 index 0000000000..5e0fe4c46c --- /dev/null +++ b/content/zh/docs/topics/registries.md @@ -0,0 +1,232 @@ +--- +title: "使用基于OCI的注册中心" +description: "描述如何使用 OCI 进行Chart的分发。" +weight: 7 +--- + +从Helm 3开始,可以使用具有[OCI](https://www.opencontainers.org/)支持的容器注册中心来存储和共享chart包。从Helm v3.8.0开始,默认启用OCI支持。 + +## v3.8.0版本之前对 OCI 的支持 + +OCI 支持在Helm v3.8.0版本从试验阶段过渡成为普遍可用。在之前版本中,对OCI支持会有不同的地方。如果你在v3.8.0之前的版本使用OCI,需要着重了解不同Helm版本之间OCI的变化。 + +### 在v3.8.0之前的版本启用OCI支持 + +Helm v3.8.0版本之前, OCI支持是*试验性*的且必须显式启用。 + +为了在之前版本中启用OCI试验性支持,需要在环境变量中设置`HELM_EXPERIMENTAL_OCI`,例如: + +```console +export HELM_EXPERIMENTAL_OCI=1 +``` + +### OCI在v3.8.0中的弃用和行为变化 + +[Helm v3.8.0](https://github.com/helm/helm/releases/tag/v3.8.0)版本中,以下行为和特性与之前版本不同: + +- 在依赖中将chart设置为OCI时,版本号可以像其他依赖一样设置成范围。 +- 包含构建信息的SemVer tag可以被推送和使用。OCI注册中心的tag字符不支持`+`。如果有,Helm会将`+` 转成 `_`。 +- `helm registry login` 命令现在采用与Docker CLI相同的结构存储凭证。Helm和Docker CLI的注册表配置使用一样的路径。 + +### OCI在v3.7.0中的弃用和行为变化 + +[Helm v3.7.0](https://github.com/helm/helm/releases/tag/v3.7.0)版本包含了针对支持OCI的[HIP +6](https://github.com/helm/community/blob/main/hips/hip-0006.md)执行策略。因此以下行为和特性与之前版本不同: + +- 移除了 `helm chart` 子命令。 +- 移除了chart缓存(没有了 `helm chart list` 等等)。 +- OCI注册引用现在需要以 `oci://` 开头。 +- 注册引用的基础名称*必须*和chart名称匹配。 +- 注册引用的tag*必须*和chart的语义版本匹配(比如没有`latest`这种tag)。 +- chart层的媒体类型从`application/tar+gzip`转换成了`application/vnd.cncf.helm.chart.content.v1.tar+gzip`。 + +## 使用基于OCI的注册中心 + +### 基于OCI注册中心的Helm仓库 + +[Helm 仓库](https://helm.sh/zh/docs/topics/chart_repository)是一种制作和分发打包好的Helm +chart的方式。基于OCI的的注册中心包含0个或多个Helm仓库,且每个都会有0个或多个Helm chart。 + +### 使用托管的注册中心 + +以下是几种chart可以使用的托管容器注册中心,都支持OCI,例如: + +- [Amazon ECR](https://docs.aws.amazon.com/AmazonECR/latest/userguide/push-oci-artifact.html) +- [Azure Container Registry](https://docs.microsoft.com/azure/container-registry/container-registry-helm-repos#push-chart-to-registry-as-oci-artifact) +- [Docker Hub](https://docs.docker.com/docker-hub/oci-artifacts/) +- [Google Artifact Registry](https://cloud.google.com/artifact-registry/docs/helm/manage-charts) +- [IBM Cloud Container Registry](https://cloud.ibm.com/docs/Registry?topic=Registry-registry_helm_charts) +- [JFrog Artifactory](https://www.jfrog.com/confluence/display/JFROG/Docker+Registry) + +参照托管平台提供的文档来创建和配置支持OCI的注册中心。 + +**注:** 你可以在开发电脑上运行基于OCI的注册中心 [Docker Registry](https://docs.docker.com/registry/deploying/) +或者 [`zot`](https://github.com/project-zot/zot)。在开发电脑上运行只能用于测试目的。 + +## 用于处理注册中心的命令 + +### `registry` 子命令 + +#### `login` + +登录到注册中心 (手动输入密码) + +```console +$ helm registry login -u myuser localhost:5000 +Password: +Login succeeded +``` + +#### `logout` + +从注册中心注销 + +```console +$ helm registry logout localhost:5000 +Logout succeeded +``` + +### The `push` 子命令 + +上传chart到基于OCI的注册中心 + +```console +$ helm push mychart-0.1.0.tgz oci://localhost:5000/helm-charts +Pushed: localhost:5000/helm-charts/mychart:0.1.0 +Digest: sha256:ec5f08ee7be8b557cd1fc5ae1a0ac985e8538da7c93f51a51eff4b277509a723 +``` + +`push`子命令只能用于`helm package`提前创建的`.tgz`文件。 + +使用`helm push`上传chart到OCI注册表时,引用必须以`oci://`开头,且不能包含基础名称或tag。 + +注册表引用的基础名称是由chart名称推断而来,tag是由chart语义版本推断而来。现在是强制要求。 + +某些注册表(如果指定)要求事先创建仓库或者命名空间,或者两者都需要创建。否则,`helm push` 会出现错误。 + +如果您已经创建了一个[源文件](https://helm.sh/zh/docs/topics/provenance) (`.prov`), +且和`.tgz`文件在同一文件下,会通过`push`自动上传到注册表。会在 [Helm chart manifest](#helm-chart-manifest)生成一个额外的层。 + +[helm-push plugin](https://github.com/chartmuseum/helm-push)的用户 (用于上传chart到 +[ChartMuseum](https://helm.sh/zh/docs/topics/provenance#chartmuseum-repository-server))可能会遇到问题,因为与内置的新的`push`插件有冲突。 +从v0.10.0版本开始,该插件已被命名为`cm-push`。 + +### 其他命令 + +对`oci://`协议的支持同样适用于很多其他子命令。以下是完整列表: + +- `helm pull` +- `helm show` +- `helm template` +- `helm install` +- `helm upgrade` + +注册表的基础名称(chart name)*包含*了涉及chart下载的任意类型的操作。(相对于`helm push`被省略的位置)。 + +下面是一些基于OCI的chart使用上述子命令的示例: + +```console +$ helm pull oci://localhost:5000/helm-charts/mychart --version 0.1.0 +Pulled: localhost:5000/helm-charts/mychart:0.1.0 +Digest: sha256:0be7ec9fb7b962b46d81e4bb74fdcdb7089d965d3baca9f85d64948b05b402ff + +$ helm show all oci://localhost:5000/helm-charts/mychart --version 0.1.0 +apiVersion: v2 +appVersion: 1.16.0 +description: A Helm chart for Kubernetes +name: mychart +... + +$ helm template myrelease oci://localhost:5000/helm-charts/mychart --version 0.1.0 +--- +# Source: mychart/templates/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount +... + +$ helm install myrelease oci://localhost:5000/helm-charts/mychart --version 0.1.0 +NAME: myrelease +LAST DEPLOYED: Wed Oct 27 15:11:40 2021 +NAMESPACE: default +STATUS: deployed +REVISION: 1 +NOTES: +... + +$ helm upgrade myrelease oci://localhost:5000/helm-charts/mychart --version 0.2.0 +Release "myrelease" has been upgraded. Happy Helming! +NAME: myrelease +LAST DEPLOYED: Wed Oct 27 15:12:05 2021 +NAMESPACE: default +STATUS: deployed +REVISION: 2 +NOTES: +... +``` + +## 指定依赖项 + +chart的依赖项可用从使用了`dependency update`命令的注册中心拉取。 + +`Chart.yaml`中给定的`repository`被指定为没有基础名称注册表引用: + +```yaml +dependencies: + - name: mychart + version: "2.7.0" + repository: "oci://localhost:5000/myrepo" +``` + +这会在执行`dependency update`时获取`oci://localhost:5000/myrepo/mychart:2.7.0`。 + +## Helm chart manifest + +在注册表中表示的Helm chart manifest示例(注意`mediaType`字段): + +```json +{ + "schemaVersion": 2, + "config": { + "mediaType": "application/vnd.cncf.helm.config.v1+json", + "digest": "sha256:8ec7c0f2f6860037c19b54c3cfbab48d9b4b21b485a93d87b64690fdb68c2111", + "size": 117 + }, + "layers": [ + { + "mediaType": "application/vnd.cncf.helm.chart.content.v1.tar+gzip", + "digest": "sha256:1b251d38cfe948dfc0a5745b7af5ca574ecb61e52aed10b19039db39af6e1617", + "size": 2487 + } + ] +} +``` + +下面的示例包含一个[源文件](https://helm.sh/zh/docs/topics/provenance)(注意额外层): + +```json +{ + "schemaVersion": 2, + "config": { + "mediaType": "application/vnd.cncf.helm.config.v1+json", + "digest": "sha256:8ec7c0f2f6860037c19b54c3cfbab48d9b4b21b485a93d87b64690fdb68c2111", + "size": 117 + }, + "layers": [ + { + "mediaType": "application/vnd.cncf.helm.chart.content.v1.tar+gzip", + "digest": "sha256:1b251d38cfe948dfc0a5745b7af5ca574ecb61e52aed10b19039db39af6e1617", + "size": 2487 + }, + { + "mediaType": "application/vnd.cncf.helm.chart.provenance.v1.prov", + "digest": "sha256:3e207b409db364b595ba862cdc12be96dcdad8e36c59a03b7b3b61c946a5741a", + "size": 643 + } + ] +} +``` + +## 从chart仓库迁移 + +从经典 [chart 仓库](https://helm.sh/zh/docs/topics/chart_repository)(基于index.yaml)和使用 +`helm pull`一样简单,然后使用`helm push`上传生成的`.tgz`文件到注册表。 diff --git a/content/zh/docs/topics/release_policy.md b/content/zh/docs/topics/release_policy.md new file mode 100644 index 0000000000..fe6bbd6b90 --- /dev/null +++ b/content/zh/docs/topics/release_policy.md @@ -0,0 +1,44 @@ +--- +title: "发布计划策略" +description: "描述Helm的版本发布的策略" +--- + +为了用户的利益,Helm提前定义和宣布发布日期。本文档描述了控制Helm发布计划的策略。 + +## 发布日历 + +可以在[这里](https://helm.sh/calendar/release)找到显示即将发布的Helm公共日历 + +## 语义化版本 + +Helm的版本描述为`x.y.z`,其中`x`是主版本,`y`是次版本,`z`是补丁版本,遵循[语义化版本](https://semver.org/spec/v2.0.0.html)术语。 + +## 补丁发布 + +补丁版本为用户提供bug修复和安全修复。不会包含新的特性。 + +与最新的次要/主要版本相关的新补丁通常每月的第二个星期三进行发布一次。 + +补丁版本会修复需要处理的高优先级回归或安全问题。 + +补丁版本会因为以下原因取消: + +- 如果自上一个版本没有新内容加入 +- 如果补丁版本的发布日期在第一候选版本发布之前一周之内 +- 如果补丁版本在次版本发布后的四周内 + +## 次版本发布 + +次版本包含安全和bug修复以及新特性。它们对API和CLI用法向后兼容。 + +为了与Kubernetes版本保持一致,次要版本会每四个月发布一次(一年三版)。 + +如果需要的话,可以发布额外的次版本,但不会影响已经宣布的未来版本的时间线,除非宣布的发布时间不到7天。 + +版本发布的同时,下一个次版本的发布时间也宣布并发布在Helm的主页上。 + +## 主版本发布 + +主版本包含了突破性的更改。这种版本很少,但是有时需要允许helm在重要的新方向上持续改善。 + +主版本很难计划。考虑到这一点,最终发布时间只能在第一个beta版本可用时选择和宣布。 diff --git a/content/zh/docs/topics/v2_v3_migration.md b/content/zh/docs/topics/v2_v3_migration.md new file mode 100644 index 0000000000..5c28aa51fe --- /dev/null +++ b/content/zh/docs/topics/v2_v3_migration.md @@ -0,0 +1,85 @@ +--- +title: "Helm v2 迁移到 v3" +description: "了解如何将Helm v2 迁移到v3。" +weight: 13 +--- + +该指南介绍如何将Helm v2迁移到v3。Helm v2需要被安装且在一个或多个集群中管理版本。 + +## Helm 3变化概述 + +Helm 2 to 3完整的变化列表在 [FAQ 部分](https://v3.helm.sh/docs/faq/#changes-since-helm-2)。 +以下是用户在迁移之前应该要注意的一些改变的概述: + +1. 移除了Tiller: + - 用client/library结构(仅仅`helm`)替换了 client/server + - 安全性现在是每个用户的基础(委托给了Kubernetes用户集群安全) + - 发布版本现在作为集群内的密钥存储且改变了发布对象的元数据 + - 发布版本是在版本命名空间的基础上持久化的并且不再是Tiller的命名空间 +2. 升级了Chart仓库: + - `helm search` 现在支持本地仓库搜索和Artifact Hub查询 +3. 对于以下更新的规范,Chart的apiVersion升级到了"v2": + - 动态依赖的chart依赖移动到了`Chart.yaml` + (删除了`requirements.yaml` 且 requirements --> dependencies) + - 库chart (辅助/公共库) 现在可以添加为动态链接的chart依赖 + - Chart有个`type`元数据字段将chart定义为`application`或`library`的chart。默认是可渲染和安装的应用 + - Helm 2 的chart (apiVersion=v1) 依然可用 +4. 添加了XDG目录规范: + - Helm根目录针对存储配置文件删除和替换了XDG目录规范 + - 不再需要初始化Helm + - 移除了`helm init` 和 `helm home` +5. 其他更改: + - 简化了Helm的安装和设置: + - 仅针对Helm客户端 (二进制) + - 按照已有范式运行 + - 不再默认设置`local`或`stable`仓库 + - 删除了`crd-install`钩子并用chart中的`crds`目录替换了,在渲染chart之前会安装所有的crd + - 删除了`test-failure`钩子注释值,且弃用了`test-success`。使用`test`代替 + - 删除/替换/添加的命令: + - delete --> uninstall : 默认删除所有的发布记录(之前需要`--purge`) + - fetch --> pull + - home (已删除) + - init (已删除) + - install: 需要发布名称或者`--generate-name` 参数 + - inspect --> show + - reset (已删除) + - serve (已删除) + - template: `-x`/`--execute` 参数重命名为 `-s`/`--show-only` + - upgrade: 添加了参数 `--history-max`,限制每个版本保存的最大记录数量(0表示不限制) + - Helm 3 Go库经历了很多变化,不再兼容Helm 2库 + - 发行版二进制包现在托管在 `get.helm.sh` + +## 迁移用例 + +迁移用例如下: + +1. Helm v2和v3 来管理相同的集群: + - 只有打算逐步淘汰Helm v2时,才建议使用此用例,且不需要使用v3管理任何v2部署的发布。所有的新发布都应该使用v3部署且现有v2部署的只能用v2删除和升级 + - Helm v2 和 v3 可以很欢快地管理同一个集群。Helm 版本可以安装在相同或单独的系统上。 + - 如果将Helm v3安装在相同的系统上,需要执行额外的步骤来保证两个客户端版本可以共存,直到删除Helm v2客户端。重命名或者将Helm + v3执行文件放在不同的文件夹中以避免冲突 + - 否则由于以下区别两个版本不存在冲突: + - v2 和 v3 发布(历史)存储是独立的。修改包括存储的Kubernetes资源和包含在资源中的发布对象元数据。发布版本会在每个用户命名空间而不是 + Tiller命名空间(比如,v2默认的命名空间kube-system)。v2使用Tiller命名空间中的"ConfigMaps"或"Secrets"和 + `TILLER`所有权。v3在用户命名空间中使用"Secrets"和`helm`所有权。发布版本在v2和v3中都是增量的。 + - 唯一的问题是如果Kubernetes集群范围内的资源(比如`clusterroles.rbac`)定义在chart中。即使资源在命名空间中是唯一的, + 因为冲突v3部署会失败。 + - v3配置不再使用`$HELM_HOME`并使用XDG目录规范代替。还可以根据需要动态创建。因此它独立于v2配置。这仅适用于两个版本安装在同一个系统上的情况。 + +2. 将Helm v2迁移到Helm v3: + - 此案例适用于你希望用Helm v3管理现有Helm v2版本时 + - 需要注意的是Helm v2 客户端: + - 可以管理1个或多个Kubernetes集群 + - 可以为一个集权连接1个或多个Tiller实例 + - 这意味着你必须注意当通过Tiller和它的命名空间迁移部署在集群中的发布。因此你必须注意使用Helm v2客户端实例管理的每个集群和Tiller实例的迁移 + - 推荐的数据迁移步骤如下: + 1. 备份v2数据 + 2. 迁移Helm v2配置 + 3. 迁移Helm v2发布 + 4. 当确信Helm v3按预期管理所有的Helm v2 数据时(针对Helm v2 客户端实例的所有集群和Tiller实例) + - 迁移过程有Helm v3的[2to3](https://github.com/helm/helm-2to3)插件自动完成 + +## 参考 + +- Helm v3 [2to3](https://github.com/helm/helm-2to3) 插件 +- [post](https://helm.sh/blog/migrate-from-helm-v2-to-helm-v3/) 附带示例阐述了 `2to3`插件的使用 diff --git a/content/zh/docs/topics/version_skew.md b/content/zh/docs/topics/version_skew.md new file mode 100644 index 0000000000..76e68dd137 --- /dev/null +++ b/content/zh/docs/topics/version_skew.md @@ -0,0 +1,64 @@ +--- +title: "Helm版本支持策略" +description: "描述Helm的补丁发布策略,以及Helm和Kubernetes之间支持的最大版本偏差" +--- + +该文档描述了在Helm和Kubernetes之间支持的最大版本偏差。 + +## 支持的版本 + +Helm的版本用 `x.y.z` 描述,`x`是主版本,`y`是次版本,`z`是补丁版本,遵循 +[语义化版本](https://semver.org/spec/v2.0.0.html) 术语。 + +Helm项目维护了一个针对最近次要版本的发布分支。适当的修复,包括安全修复、从发布分支中的cherry-pick, +视严重程度而定。更多细节请查看[Helm版本策略](https://helm.sh/zh/docs/topics/release_policy)。 + +## 可支持的版本偏差 + +当一个Helm的新版本发布时,它是针对Kubernetes的一个特定的次版本编译的。比如,Helm 3.0.0 +与Kubernetes的1.16.2的客户端版本交互,一次可以兼容Kubernetes 1.16。 + +从Helm 3开始,Helm 编译时假定与针对`n-3`版本的Kubernetes兼容。由于Helm 2对Kubernetes次版本变更的支持稍微严格一点, +则假定与Kubernetes的`n-1`版本兼容。 + +例如,如果您在使用一个针对Kubernetes 1.17客户端API版本编译的Helm 3版本,那么它应该可以安全地使用Kubernetes 1.17, +1.16,1.15,以及1.14。如果您在使用一个针对Kubernetes 1.16客户端API版本编译的Helm 2版本,那么它应该可以安全地使用 +Kubernetes 1.16 和 1.15。 + +不推荐将Helm用于比编译它所依赖的版本更高的Kubernetes版本,因为Helm并没有做出任何向前兼容的保证。 + +如果您选择了一个Kubernetes版本不支持的Helm,需自负风险。 + +请参考下表来确定哪个版本的Helm与您的集群兼容。 + +| Helm 版本 | 支持的 Kubernetes 版本 | +|--------------|-------------------------------| +| 3.11.x | 1.26.x - 1.23.x | +| 3.10.x | 1.25.x - 1.22.x | +| 3.9.x | 1.24.x - 1.21.x | +| 3.8.x | 1.23.x - 1.20.x | +| 3.7.x | 1.22.x - 1.19.x | +| 3.6.x | 1.21.x - 1.18.x | +| 3.5.x | 1.20.x - 1.17.x | +| 3.4.x | 1.19.x - 1.16.x | +| 3.3.x | 1.18.x - 1.15.x | +| 3.2.x | 1.18.x - 1.15.x | +| 3.1.x | 1.17.x - 1.14.x | +| 3.0.x | 1.16.x - 1.13.x | +| 2.16.x | 1.16.x - 1.15.x | +| 2.15.x | 1.15.x - 1.14.x | +| 2.14.x | 1.14.x - 1.13.x | +| 2.13.x | 1.13.x - 1.12.x | +| 2.12.x | 1.12.x - 1.11.x | +| 2.11.x | 1.11.x - 1.10.x | +| 2.10.x | 1.10.x - 1.9.x | +| 2.9.x | 1.10.x - 1.9.x | +| 2.8.x | 1.9.x - 1.8.x | +| 2.7.x | 1.8.x - 1.7.x | +| 2.6.x | 1.7.x - 1.6.x | +| 2.5.x | 1.6.x - 1.5.x | +| 2.4.x | 1.6.x - 1.5.x | +| 2.3.x | 1.5.x - 1.4.x | +| 2.2.x | 1.5.x - 1.4.x | +| 2.1.x | 1.5.x - 1.4.x | +| 2.0.x | 1.4.x - 1.3.x | diff --git a/docs.helm.sh/Makefile b/docs.helm.sh/Makefile deleted file mode 100644 index ba47cf22b8..0000000000 --- a/docs.helm.sh/Makefile +++ /dev/null @@ -1,52 +0,0 @@ -# CONTAINER_SOURCE: container-relative mount for the source directory -CONTAINER_SOURCE := /src -# CONTAINER_BUILD_DEST: container-relative mount for LOCAL_BUILD_DEST -CONTAINER_BUILD_DEST := /dest -# LOCAL_BUILD_DEST: destination directory for website -LOCAL_BUILD_DEST := $(CURDIR)/rootfs/public - -SHORT_NAME ?= gutenberg -VERSION ?= 0.6.0 -IMAGE_PREFIX ?= jhansen -DEV_REGISTRY ?= quay.io -DEIS_REGISTRY ?= ${DEV_REGISTRY}/ -IMAGE := ${DEIS_REGISTRY}${IMAGE_PREFIX}/${SHORT_NAME}:${VERSION} - -DOCKER_RUN_CMD := docker run -p 1313:1313 -v $(CURDIR):$(CONTAINER_SOURCE) -v $(LOCAL_BUILD_DEST):$(CONTAINER_BUILD_DEST) --rm ${IMAGE} -DOCKER_SHELL_CMD := docker run -p 1313:1313 -v $(CURDIR):$(CONTAINER_SOURCE) -v $(LOCAL_BUILD_DEST):$(CONTAINER_BUILD_DEST) -it --rm ${IMAGE} - -HELMSH_DOCS_SHORT_NAME ?= helmsh-docs -HELMSH_DOCS_VERSION ?= latest -HELMSH_DOCS_IMAGE_PREFIX ?= deis -HELMSH_DOCS_IMAGE := ${DEIS_REGISTRY}${HELMSH_DOCS_IMAGE_PREFIX}/${HELMSH_DOCS_SHORT_NAME}:${HELMSH_DOCS_VERSION} - -clean: - rm -rf $(LOCAL_BUILD_DEST) - -prep: - $(CURDIR)/script/prep $(LOCAL_BUILD_DEST) - -test: prep - $(DOCKER_RUN_CMD) /src/script/test $(CONTAINER_BUILD_DEST) - -build: prep - $(DOCKER_RUN_CMD) /src/script/build $(CONTAINER_BUILD_DEST) - -build-image: - docker build \ - --pull \ - --build-arg BUILD_DATE=`date -u +'%Y-%m-%dT%H:%M:%SZ'` \ - -t ${HELMSH_DOCS_IMAGE} rootfs - -push: - docker push ${HELMSH_DOCS_IMAGE} - -deploy: - deis login ${DEIS_URL} --username="${DEIS_USERNAME}" --password="${DEIS_PASSWORD}" - deis pull ${HELMSH_DOCS_IMAGE} -a docs-helm-sh - -serve: - $(DOCKER_SHELL_CMD) /src/script/serve - -shell: - $(DOCKER_SHELL_CMD) /bin/bash diff --git a/docs.helm.sh/README.md b/docs.helm.sh/README.md deleted file mode 100644 index 7964ecb057..0000000000 --- a/docs.helm.sh/README.md +++ /dev/null @@ -1,54 +0,0 @@ -# docs.helm.sh - -[docs.helm.sh](https://helm.sh) is the documentation website for Helm. - -* [Project Docs: github.com/kubernetes/helm](https://github.com/kubernetes/helm/tree/master/docs) -* [Docs Website: docs.helm.sh](https://docs.helm.sh/) - --- - -## Website Development - -The site is built on top of [Hugo](https://gohugo.io/), and uses [Gulp](https://gulpjs.com/) to build and manage the asset pipeline. - -### Install Dependancies - -This site uses [Hugo](https://gohugo.io), a static site generator. It can be installed via homebrew: - -`brew update && brew install hugo` - -then install the packages needed for Gulp to run: - -``` -npm install -g gulp -npm install && bower install -``` - -### Running the site - -When these packages are installed, you can generate the Docs site by: - -`hugo && hugo server --watch` - -### Local Dev - -The site uses Gulp to build and optimize the site assets. If you're work on the styles or scripts in the site, re-compile and reload your changes with: - -`gulp && gulp watch` - -## Structure - -The documentation contents are pulled in from their home in the [kubernetes/helm](https://github.com/kubernetes/helm/tree/master/docs) repo, as part of the Gulp build process. - -Gulp clones the files to the `/source` directory. -Hugo then targets the `/source/docs` directory to generate the website, applying the theme (html layouts and css/js assets) in `/themes/hugodocs`. - -## Editing Docs - -Edits to the Docs themselves should be carried out via pull requests on the [kubernetes/helm](https://github.com/kubernetes/helm/tree/master/docs) repo. This Docs site will then extract those files and publish them to [docs.helm.sh](https://docs.helm.sh). - -## Deployment - -The helm website is deployed to an ACS cluster using the [Deis team credentials](https://github.com/deis/deployment/tree/master/production/workflow). Helm core members and folks within ACS should have access to this subscription. - -Normally the site is deployed via Jenkins CI when changes are merged to master, though this process is currently being updated. Manual deploys are possible using Deis Workflow and the above creds. diff --git a/docs.helm.sh/bower.json b/docs.helm.sh/bower.json deleted file mode 100644 index 6cdb879afd..0000000000 --- a/docs.helm.sh/bower.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "name": "helm-docs", - "description": "Helm Docs", - "main": "gulpfile.js/index.js", - "authors": [ - "Ronan Flynn-Curran" - ], - "license": "MIT", - "keywords": [ - "css", - "framework", - "helm", - "grid" - ], - "homepage": "https://github.com/helm/helm-www", - "private": true, - "ignore": [ - "**/.*", - "node_modules", - "bower_components", - "test", - "tests" - ], - "devDependencies": { - "foundation": "^5.5.3", - "font-awesome": "^4.7.0" - } -} diff --git a/docs.helm.sh/config.toml b/docs.helm.sh/config.toml deleted file mode 100644 index 8d4c4c9ecd..0000000000 --- a/docs.helm.sh/config.toml +++ /dev/null @@ -1,577 +0,0 @@ -baseurl = "https://docs.helm.sh/" -languageCode = "en-us" -title = "Helm Docs" -theme = "helmdocs" - -contentDir = "source/docs" -publishdir = "app" - -[params] - title = "Helm Docs" - author = "Ronan Flynn-Curran" - description = "Documentation for Helm - The Kubernetes Package Manager." - -canonifyURLs = "false" -relativeURLs = "true" -pluralizeListTitles = "false" -plainIdAnchors = "true" -defaultContentLanguage = "en" - - -[[menu.main]] - name = "Using Helm" - url = "using_helm" - identifier = "using_helm" - weight = 2 - [[menu.main]] - name = "Quickstart" - url = "quickstart-guide" - identifier = "quickstart-guide" - weight = 11 - parent = "using_helm" - [[menu.main]] - name = "Installing Helm" - url = "installing-helm" - identifier = "installing-helm" - weight = 12 - parent = "using_helm" - [[menu.main]] - name = "Kubernetes Distro Notes" - url = "kubernetes-distribution-guide" - identifier = "kubernetes-distribution-guide" - weight = 13 - parent = "using_helm" - [[menu.main]] - name = "Install FAQ" - url = "installation-frequently-asked-questions" - identifier = "installation-frequently-asked-questions" - weight = 14 - parent = "using_helm" - [[menu.main]] - name = "Using Helm" - url = "using-helm" - identifier = "using-helm" - weight = 15 - parent = "using_helm" - [[menu.main]] - name = "Plugins" - url = "the-helm-plugins-guide" - identifier = "the-helm-plugins-guide" - weight = 16 - parent = "using_helm" - [[menu.main]] - name = "Role-Based Access Control" - url = "role-based-access-control" - identifier = "role-based-access-control" - weight = 17 - parent = "using_helm" - [[menu.main]] - name = "Securing Helm" - url = "securing-your-helm-installation" - identifier = "securing-your-helm-installation" - weight = 18 - parent = "using_helm" - -[[menu.main]] - name = "Helm Commands" - url = "helm" - identifier = "helm" - weight = 102 - [[menu.main]] - name = "Helm" - url = "helm" - identifier = "helm-command" - weight = 121 - parent = "helm" - [[menu.main]] - name = "Helm Completion" - url = "helm-completion" - identifier = "helm-completion" - weight = 122 - parent = "helm" - [[menu.main]] - name = "Helm Create" - url = "helm-create" - identifier = "helm-create" - weight = 123 - parent = "helm" - [[menu.main]] - name = "Helm Delete" - url = "helm-delete" - identifier = "helm-delete" - weight = 124 - parent = "helm" - [[menu.main]] - name = "Helm Dependency" - url = "helm-dependency" - identifier = "helm-dependency" - weight = 125 - parent = "helm" - [[menu.main]] - name = "Helm Dependency Build" - url = "helm-dependency-build" - identifier = "helm-dependency-build" - weight = 126 - parent = "helm" - [[menu.main]] - name = "Helm Dependency List" - url = "helm-dependency-list" - identifier = "helm-dependency-list" - weight = 127 - parent = "helm" - [[menu.main]] - name = "Helm Dependency Update" - url = "helm-dependency-update" - identifier = "helm-dependency-update" - weight = 128 - parent = "helm" - [[menu.main]] - name = "Helm Fetch" - url = "helm-fetch" - identifier = "helm-fetch" - weight = 129 - parent = "helm" - [[menu.main]] - name = "Helm Get" - url = "helm-get" - identifier = "helm-get" - weight = 130 - parent = "helm" - [[menu.main]] - name = "Helm Get Hooks" - url = "helm-get-hooks" - identifier = "helm-get-hooks" - weight = 131 - parent = "helm" - [[menu.main]] - name = "Helm Get Manifest" - url = "helm-get-manifest" - identifier = "helm-get-manifest" - weight = 132 - parent = "helm" - [[menu.main]] - name = "Helm Get Values" - url = "helm-get-values" - identifier = "helm-get-values" - weight = 133 - parent = "helm" - [[menu.main]] - name = "Helm History" - url = "helm-history" - identifier = "helm-history" - weight = 134 - parent = "helm" - [[menu.main]] - name = "Helm Home" - url = "helm-home" - identifier = "helm-home" - weight = 135 - parent = "helm" - [[menu.main]] - name = "Helm Init" - url = "helm-init" - identifier = "helm-init" - weight = 136 - parent = "helm" - [[menu.main]] - name = "Helm Inspect" - url = "helm-inspect" - identifier = "helm-inspect" - weight = 137 - parent = "helm" - [[menu.main]] - name = "Helm Inspect Chart" - url = "helm-inspect-chart" - identifier = "helm-inspect-chart" - weight = 138 - parent = "helm" - [[menu.main]] - name = "Helm Inspect Values" - url = "helm-inspect-values" - identifier = "helm-inspect-values" - weight = 139 - parent = "helm" - [[menu.main]] - name = "Helm Install" - url = "helm-install" - identifier = "helm-install" - weight = 140 - parent = "helm" - [[menu.main]] - name = "Helm Lint" - url = "helm-lint" - identifier = "helm-lint" - weight = 141 - parent = "helm" - [[menu.main]] - name = "Helm List" - url = "helm-list" - identifier = "helm-list" - weight = 142 - parent = "helm" - [[menu.main]] - name = "Helm Package" - url = "helm-package" - identifier = "helm-package" - weight = 143 - parent = "helm" - [[menu.main]] - name = "Helm Plugin" - url = "helm-plugin" - identifier = "helm-plugin" - weight = 144 - parent = "helm" - [[menu.main]] - name = "Helm Plugin Install" - url = "helm-plugin-install" - identifier = "helm-plugin-install" - weight = 145 - parent = "helm" - [[menu.main]] - name = "Helm Plugin List" - url = "helm-plugin-list" - identifier = "helm-plugin-list" - weight = 146 - parent = "helm" - [[menu.main]] - name = "Helm Plugin Remove" - url = "helm-plugin-remove" - identifier = "helm-plugin-remove" - weight = 147 - parent = "helm" - [[menu.main]] - name = "Helm Plugin Update" - url = "helm-plugin-update" - identifier = "helm-plugin-update" - weight = 148 - parent = "helm" - [[menu.main]] - name = "Helm Repo" - url = "helm-repo" - identifier = "helm-repo" - weight = 149 - parent = "helm" - [[menu.main]] - name = "Helm Repo Add" - url = "helm-repo-add" - identifier = "helm-repo-add" - weight = 150 - parent = "helm" - [[menu.main]] - name = "Helm Repo Index" - url = "helm-repo-index" - identifier = "helm-repo-index" - weight = 151 - parent = "helm" - [[menu.main]] - name = "Helm Repo List" - url = "helm-rep-list" - identifier = "helm-repo-list" - weight = 152 - parent = "helm" - [[menu.main]] - name = "Helm Repo Remove" - url = "helm-repo-remove" - identifier = "helm-repo-remove" - weight = 153 - parent = "helm" - [[menu.main]] - name = "Helm Repo Update" - url = "helm-repo-update" - identifier = "helm-repo-update" - weight = 154 - parent = "helm" - [[menu.main]] - name = "Helm Reset" - url = "helm-reset" - identifier = "helm-reset" - weight = 155 - parent = "helm" - [[menu.main]] - name = "Helm Rollback" - url = "helm-rollback" - identifier = "helm-rollback" - weight = 156 - parent = "helm" - [[menu.main]] - name = "Helm Search" - url = "helm-search" - identifier = "helm-search" - weight = 157 - parent = "helm" - [[menu.main]] - name = "Helm Serve" - url = "helm-serve" - identifier = "helm-serve" - weight = 158 - parent = "helm" - [[menu.main]] - name = "Helm Status" - url = "helm-status" - identifier = "helm-status" - weight = 159 - parent = "helm" - [[menu.main]] - name = "Helm Template" - url = "helm-template" - identifier = "helm-template" - weight = 160 - parent = "helm" - [[menu.main]] - name = "Helm Test" - url = "helm-test" - identifier = "helm-test" - weight = 161 - parent = "helm" - [[menu.main]] - name = "Helm Upgrade" - url = "helm-upgrade" - identifier = "helm-upgrade" - weight = 162 - parent = "helm" - [[menu.main]] - name = "Helm Verify" - url = "helm-verify" - identifier = "helm-verify" - weight = 163 - parent = "helm" - [[menu.main]] - name = "Helm Version" - url = "helm-version" - identifier = "helm-version" - weight = 164 - parent = "helm" - -[[menu.main]] - name = "Charts" - url = "developing_charts" - identifier = "developing_charts" - weight = 200 - [[menu.main]] - name = "Intro to Charts" - url = "charts" - identifier = "charts" - weight = 201 - parent = "developing_charts" - [[menu.main]] - name = "Chart Lifecycle Hooks" - url = "hooks" - identifier = "hooks" - weight = 202 - parent = "developing_charts" - [[menu.main]] - name = "Charts Tips and Tricks" - url = "chart-development-tips-and-tricks" - identifier = "chart-development-tips-and-tricks" - weight = 203 - parent = "developing_charts" - [[menu.main]] - name = "Charts Repository Guide" - url = "the-chart-repository-guide" - identifier = "chart-repo-guide" - weight = 204 - parent = "developing_charts" - [[menu.main]] - name = "Syncing Your Chart Repo" - url = "syncing-your-chart-repository" - identifier = "syncing-your-chart-repo" - weight = 205 - parent = "developing_charts" - [[menu.main]] - name = "Signing Charts" - url = "helm-provenance-and-integrity" - identifier = "helm-provenance-and-integrity" - weight = 206 - parent = "developing_charts" - [[menu.main]] - name = "Chart Tests" - url = "chart-tests" - identifier = "chart-tests" - weight = 207 - parent = "developing_charts" - [[menu.main]] - name = "Chart Repository FAQ" - url = "chart-repositories-frequently-asked-questions" - identifier = "chart-repositories-frequently-asked-questions" - weight = 208 - parent = "developing_charts" - -[[menu.main]] - name = "Developing Templates" - url = "chart_template_guide" - identifier = "chart_template_guide" - weight = 300 - [[menu.main]] - name = "Intro" - url = "the-chart-template-developer-s-guide" - identifier = "the-chart-template-developer-s-guide" - weight = 301 - parent = "chart_template_guide" - [[menu.main]] - name = "Getting Started" - url = "getting-started-with-a-chart-template" - identifier = "getting-started-with-a-chart-template" - weight = 302 - parent = "chart_template_guide" - [[menu.main]] - name = "Built-In Objects" - url = "built-in-objects" - identifier = "built-in-objects" - weight = 303 - parent = "chart_template_guide" - [[menu.main]] - name = "Values Files" - url = "values-files" - identifier = "values-files" - weight = 304 - parent = "chart_template_guide" - [[menu.main]] - name = "Template Functions and Pipelines" - url = "template-functions-and-pipelines" - identifier = "template-functions-and-pipelines" - weight = 305 - parent = "chart_template_guide" - [[menu.main]] - name = "Flow Control" - url = "flow-control" - identifier = "flow-control" - weight = 306 - parent = "chart_template_guide" - [[menu.main]] - name = "Variables" - url = "variables" - identifier = "variables" - weight = 307 - parent = "chart_template_guide" - [[menu.main]] - name = "Named Templates" - url = "named-templates" - identifier = "named-templates" - weight = 308 - parent = "chart_template_guide" - [[menu.main]] - name = "Accessing Files Inside Templates" - url = "accessing-files-inside-templates" - identifier = "accessing-files-inside-templates" - weight = 310 - parent = "chart_template_guide" - [[menu.main]] - name = "Creating a NOTES.txt File" - url = "creating-a-notes-txt-file" - identifier = "creating-a-notes-txt-file" - weight = 311 - parent = "chart_template_guide" - [[menu.main]] - name = "Subcharts and Global Values" - url = "subcharts-and-global-values" - identifier = "subcharts-and-global-values" - weight = 312 - parent = "chart_template_guide" - [[menu.main]] - name = "Debugging Templates" - url = "debugging-templates" - identifier = "debugging-templates" - weight = 313 - parent = "chart_template_guide" - [[menu.main]] - name = "Next Steps" - url = "wrapping-up" - identifier = "wrapping-up" - weight = 314 - parent = "chart_template_guide" - [[menu.main]] - name = "Appendix: YAML Techniques" - url = "yaml-techniques" - identifier = "yaml-techniques" - weight = 315 - parent = "chart_template_guide" - [[menu.main]] - name = "Appendix: Go Data Types and Templates" - url = "appendix-go-data-types-and-templates" - identifier = "appendix-go-data-types-and-templates" - weight = 316 - parent = "chart_template_guide" - -[[menu.main]] - name = "Best Practices" - url = "/chart_best_practices/" - identifier = "chart_best_practices" - weight = 401 - [[menu.main]] - name = "Intro" - url = "the-chart-best-practices-guide" - identifier = "the-chart-best-practices-guide" - weight = 402 - parent = "chart_best_practices" - [[menu.main]] - name = "General Conventions" - url = "general-conventions" - identifier = "general-conventions" - weight = 403 - parent = "chart_best_practices" - [[menu.main]] - name = "Values" - url = "values" - identifier = "values" - weight = 404 - parent = "chart_best_practices" - [[menu.main]] - name = "Templates" - url = "templates" - identifier = "templates" - weight = 405 - parent = "chart_best_practices" - [[menu.main]] - name = "Requirements" - url = "requirements-files" - identifier = "requirements-files" - weight = 406 - parent = "chart_best_practices" - [[menu.main]] - name = "Labels & Annotations" - url = "labels-and-annotations" - identifier = "labels-and-annotations" - weight = 407 - parent = "chart_best_practices" - [[menu.main]] - name = "Pods & PodTemplates" - url = "pods-and-podtemplates" - identifier = "pods-and-podtemplates" - weight = 408 - parent = "chart_best_practices" - [[menu.main]] - name = "Third Party Resources" - url = "third-party-resources" - identifier = "third-party-resources" - weight = 409 - parent = "chart_best_practices" - -[[menu.main]] - name = "Related Projects" - url = "/related/" - identifier = "related-projects" - weight = 500 -[[menu.main]] - name = "Architecture" - url = "/architecture/" - identifier = "architecture" - weight = 501 -[[menu.main]] - name = "Developer Guide" - url = "/developers/" - identifier = "developer-guide" - weight = 502 -[[menu.main]] - name = "History" - url = "/history/" - identifier = "history" - weight = 503 -[[menu.main]] - name = "Glossary" - url = "/glossary/" - identifier = "glossary" - weight = 504 -[[menu.main]] - name = "Find Charts" - url = "https://hub.kubeapps.com/" - weight = 505 diff --git a/docs.helm.sh/gulpfile.js b/docs.helm.sh/gulpfile.js deleted file mode 100644 index feeae7ba4a..0000000000 --- a/docs.helm.sh/gulpfile.js +++ /dev/null @@ -1,312 +0,0 @@ -var destination = process.env.GULP_DESTINATION || 'static'; - -// Load plugins -var gulp = require('gulp'), - sass = require('gulp-ruby-sass'), - autoprefixer = require('gulp-autoprefixer'), - minifycss = require('gulp-minify-css'), - rename = require('gulp-rename'), - concat = require('gulp-concat'), - notify = require('gulp-notify'), - cache = require('gulp-cache'), - jshint = require('gulp-jshint'), - uglify = require('gulp-uglify'), - imagemin = require('gulp-imagemin'), - livereload = require('gulp-livereload'), - del = require('del'), - streamqueue = require('streamqueue'), - cssnano = require('gulp-cssnano'), - sourcemaps = require('gulp-sourcemaps'), - git = require('gulp-git'), - foreach = require('gulp-foreach'), - tap = require("gulp-tap"), - filenames = require("gulp-filenames"), - inject = require('gulp-inject-string'), - replace = require('gulp-replace'), - stringreplace = require('gulp-string-replace'), - runSequence = require('run-sequence'); - - -// Copy -gulp.task('copy', function () { - return gulp.src('themes/helmdocs/static/src/fonts/*') - .pipe(gulp.dest(destination + '/src/fonts')) - .pipe(notify({message: 'Fonts moved.'})); -}); -gulp.task('copyall', function () { - return gulp.src('static/src/**/*') - .pipe(gulp.dest('app/src')) - .pipe(notify({message: 'Copied all.'})); -}); - - -// Styles -gulp.task('styles', function () { - return sass('themes/helmdocs/static/src/sass/styles.scss', {style: 'compressed'}) - .pipe(autoprefixer('last 2 version')) - .pipe(rename({suffix: '.min'})) - .pipe(minifycss()) - .pipe(sourcemaps.init()) - .pipe(cssnano()) - .pipe(sourcemaps.write('.')) - .pipe(gulp.dest(destination + '/src/css')) - .pipe(notify({message: 'Styles compiled.'})); -}); - - -// Scripts -gulp.task('scriptconcat', function () { - return gulp.src([ - 'themes/helmdocs/static/src/js/custom/jquery.js', - 'themes/helmdocs/static/src/js/custom/foundation.js', - 'themes/helmdocs/static/src/js/custom/foundation.topbar.js', - 'themes/helmdocs/static/src/js/custom/foundation.offcanvas.js', - 'themes/helmdocs/static/src/js/custom/foundation.accordion.js', - 'themes/helmdocs/static/src/js/custom/foundation.dropdown.js', - 'themes/helmdocs/static/src/js/custom/foundation.slider.js', - 'themes/helmdocs/static/src/js/custom/foundation.tooltip.js', - 'themes/helmdocs/static/src/js/custom/headroom.min.js', - ]) - .pipe(concat('main.js')) - .pipe(gulp.dest('themes/helmdocs/static/src/js')) - .pipe(notify({message: 'Scripts concated.'})); -}); -gulp.task('scriptminify', function () { - return gulp.src([ - 'themes/helmdocs/static/src/js/main.js', - 'themes/helmdocs/static/src/js/custom/app_init.js' - ]) - .pipe(jshint()) - .pipe(jshint.reporter('default')) - // .pipe(concat()) - .pipe(rename({suffix: '.min'})) - .pipe(uglify()) - .pipe(gulp.dest(destination + '/src/js')) - .pipe(notify({message: 'Scripts minified.'})); -}); -gulp.task('scripts', function () { - gulp.start('scriptconcat', 'scriptminify'); -}); - - -// Images -gulp.task('images', function () { - return streamqueue({objectMode: true}, - gulp.src('themes/helmdocs/static/src/img/**/*{.jpg, .png, .gif}') - .pipe(cache(imagemin({optimizationLevel: 3, progressive: true, interlaced: true}))) - .pipe(notify({message: 'Images minifed.'})), - gulp.src('themes/helmdocs/static/src/img/**/*') - .pipe(notify({message: 'Images moved.'})) - .pipe(gulp.dest(destination + '/src/img')) - ) -}); - - -// Clean -gulp.task('clean', function () { - return del([ - destination + '/src/**/*', - 'source/' - ], {force: true}); -}); - - -// Clone Docs for Hugo -gulp.task('clone', function() { - git.clone('https://github.com/kubernetes/helm', {args: './source'}, function(err) { - // handle err - }); -}); - - -/* - Edits to control how Hugo outputs the .md content: - - * concat contents for each subsection, to enforce the sort order - (in lieu of TOML that defines the weight of each page) - * remove the index chart_template_guide to avoid conflict - * - -*/ - - // Reorg Docs for Hugo - gulp.task('reorg-using', function() { - return streamqueue({ objectMode: true }, - gulp.src('source/docs/quickstart.md'), - gulp.src('source/docs/install.md'), - gulp.src('source/docs/kubernetes_distros.md'), - gulp.src('source/docs/install_faq.md'), - gulp.src('source/docs/using_helm.md'), - gulp.src('source/docs/plugins.md'), - gulp.src('source/docs/rbac.md'), - gulp.src('source/docs/securing_installation.md') - ) - .pipe(concat('index.md')) - .pipe(gulp.dest('source/docs/using_helm/')) - }); - - gulp.task('reorg-charts', function() { - return streamqueue({ objectMode: true }, - gulp.src('source/docs/charts.md'), - gulp.src('source/docs/charts_hooks.md'), - gulp.src('source/docs/charts_tips_and_tricks.md'), - gulp.src('source/docs/chart_repository.md'), - gulp.src('source/docs/chart_repository_sync_example.md'), - gulp.src('source/docs/provenance.md'), - gulp.src('source/docs/chart_tests.md'), - gulp.src('source/docs/chart_repository_faq.md') - ) - .pipe(concat('index.md')) - .pipe(gulp.dest('source/docs/developing_charts/')) - }); - - var templatefiles = 'source/docs/chart_template_guide/**.md'; - gulp.task('template-rename', function() { - return gulp.src('source/docs/chart_template_guide/index.md') - .pipe(rename('intro.md')) - .pipe(gulp.dest('source/docs/chart_template_guide/')) - del([templatefiles, '!source/docs/chart_template_guide/index.md']) - }); - gulp.task('template-move', function() { - return gulp.src(templatefiles) - .pipe(gulp.dest('source/docs/chart_template_guide/tmp/')) - }); - gulp.task('template-concat', function() { - return streamqueue({ objectMode: true }, - gulp.src('source/docs/chart_template_guide/tmp/intro.md'), - gulp.src('source/docs/chart_template_guide/tmp/getting_started.md'), - gulp.src('source/docs/chart_template_guide/tmp/builtin_objects.md'), - gulp.src('source/docs/chart_template_guide/tmp/values_files.md'), - gulp.src('source/docs/chart_template_guide/tmp/functions_and_pipelines.md'), - gulp.src('source/docs/chart_template_guide/tmp/control_structures.md'), - gulp.src('source/docs/chart_template_guide/tmp/variables.md'), - gulp.src('source/docs/chart_template_guide/tmp/named_templates.md'), - gulp.src('source/docs/chart_template_guide/tmp/accessing_files.md'), - gulp.src('source/docs/chart_template_guide/tmp/notes_files.md'), - gulp.src('source/docs/chart_template_guide/tmp/subcharts_and_globals.md'), - gulp.src('source/docs/chart_template_guide/tmp/debugging.md'), - gulp.src('source/docs/chart_template_guide/tmp/wrapping_up.md'), - gulp.src('source/docs/chart_template_guide/tmp/yaml_techniques.md'), - gulp.src('source/docs/chart_template_guide/tmp/data_types.md') - ) - .pipe(concat('index.md')) - .pipe(gulp.dest('source/docs/chart_template_guide/')) - }); - gulp.task('template-del', function() { - return del([ - templatefiles, - 'source/docs/index.md', - 'source/docs/chart_template_guide/tmp/', - '!source/docs/chart_template_guide/index.md' - ], {force: true}); - }); - gulp.task('reorg-templates', function () { - runSequence('template-rename', - 'template-move', - 'template-concat', - 'template-del'); - }); - gulp.task('reorg', function () { - gulp.start('reorg-using', 'reorg-charts', 'reorg-templates'); - }); - - // inject TOML redirects for Hugo, to point '**/*.md' to '**/' - gulp.task('redirect-inject', function() { - return gulp.src(('source/docs/**/*.md', '!source/docs/**/index.md'), {base: './'}) - .pipe(foreach(function(stream, file){ - var aliasname = file.path.replace(/^.*[\\\/]/, ''); - var diraliasname = file.path.split("/").slice(-2).join("/"); - return stream - .pipe(inject.prepend('+++\naliases = [\n\"' + aliasname + '\"\,\n\"' + diraliasname + '\"\,\n\"using\_helm\/' + aliasname + '\"\,\n\"developing\_charts\/' + aliasname + '\"\n]\n+++\n\n')) - })) - .pipe(gulp.dest('./')) - }); - - // links - gulp.task('redirect-anchor', function() { - return gulp.src('source/docs/**/*.md') - .pipe(foreach(function(stream, file){ - var anchorurl = (/(\)\])(.*)\.md/, "g")[1]; - return stream - .pipe(stringreplace( anchorurl, '](#' )) - })) - .pipe(gulp.dest('source/docs/')) - }); - - gulp.task('redirect-subfolder', function() { - return gulp.src('source/docs/helm/*.md') - // update internal urls within the helm_commands - .pipe(replace('](helm', '](../../helm/#helm')) - .pipe(replace('.md)', ')')) - .pipe(gulp.dest('source/docs/helm/')) - }); - - gulp.task('redirect-anchor', function() { - return gulp.src('source/docs/**/*.md') - // update installation guides - .pipe(replace(/\]\(.*install\.md/, '](../using_helm/#installing-helm')) - // update charts urls - .pipe(replace('chart_repository', 'developing_charts')) - // update internal links from '*.md' to '#*' - .pipe(replace(/(\]\()(.*)(\.md\))/g, '](./#$2)')) - // update the provenance urls - .pipe(replace('#provenance', '#helm-provenance-and-integrity')) - // update the image paths in 'developing_charts' - .pipe(replace('](images/', '](https://raw.githubusercontent.com/kubernetes/helm/master/docs/images/')) - .pipe(replace('.png)', '.png)')) - // update tips and tricks link - .pipe(replace('charts_tips_and_tricks', 'chart-development-tips-and-tricks')) - // update security anchor link - .pipe(replace('securing_installation', 'securing-your-helm-installation')) - .pipe(gulp.dest('source/docs/')) - }); - - - gulp.task('copyall', function () { - return gulp.src('static/src/**/*') - .pipe(gulp.dest('app/src')) - .pipe(notify({message: 'Copied all.'})); - }); - - -// gulp clonedocs - use in conjunction with gulp build -gulp.task('clonedocs', function(callback) { - runSequence('clean', - 'clone', - callback); -}); -gulp.task('build', function(callback) { - runSequence(['styles', 'scripts', 'images', 'copy'], - 'copyall', - 'redirect-inject', - 'redirect-subfolder', - ['reorg-using', 'reorg-charts'], - 'template-rename', - 'template-move', - 'template-concat', - 'template-del', - 'redirect-anchor', - callback); -}); - -// 'gulp' default task to build the site assets -gulp.task('default', function(callback) { - runSequence('clonedocs', - 'build', - callback); -}); - - -// 'gulp watch' to watch for changes during dev -gulp.task('watch', function () { - - gulp.watch('themes/helmdocs/static/src/js/custom/init.js', ['scripts']); - - gulp.watch('themes/helmdocs/static/img/src/**/*.{png,gif,jpg}', ['images']); - - gulp.watch('themes/helmdocs/static/src/sass/**/*.scss', ['styles']); - - livereload.listen(); - - gulp.watch([destination + '/**', destination + '/src/**']).on('change', livereload.changed); -}); diff --git a/docs.helm.sh/package-lock.json b/docs.helm.sh/package-lock.json deleted file mode 100644 index e14346e18a..0000000000 --- a/docs.helm.sh/package-lock.json +++ /dev/null @@ -1,11279 +0,0 @@ -{ - "name": "helm-docs", - "version": "0.0.1", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@gulp-sourcemaps/map-sources": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/map-sources/-/map-sources-1.0.0.tgz", - "integrity": "sha1-iQrnxdjId/bThIYCFazp1+yUW9o=", - "dev": true, - "requires": { - "normalize-path": "2.1.1", - "through2": "2.0.3" - } - }, - "acorn": { - "version": "4.0.13", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", - "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", - "dev": true - }, - "align-text": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", - "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", - "dev": true, - "requires": { - "kind-of": "3.2.2", - "longest": "1.0.1", - "repeat-string": "1.6.1" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "alphanum-sort": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", - "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=", - "dev": true - }, - "amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", - "dev": true - }, - "ansi-cyan": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-cyan/-/ansi-cyan-0.1.1.tgz", - "integrity": "sha1-U4rlKK+JgvKK4w2G8vF0VtJgmHM=", - "dev": true, - "requires": { - "ansi-wrap": "0.1.0" - } - }, - "ansi-gray": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", - "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=", - "requires": { - "ansi-wrap": "0.1.0" - } - }, - "ansi-red": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-red/-/ansi-red-0.1.1.tgz", - "integrity": "sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw=", - "dev": true, - "requires": { - "ansi-wrap": "0.1.0" - } - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" - }, - "ansi-wrap": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", - "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=" - }, - "ansicolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.2.1.tgz", - "integrity": "sha1-vgiVmQl7dKXJxKhKDNvNtivYeu8=", - "dev": true - }, - "any-shell-escape": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/any-shell-escape/-/any-shell-escape-0.1.1.tgz", - "integrity": "sha1-1Vq5ciRMcaml4asIefML8RCAaVk=", - "dev": true - }, - "archive-type": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/archive-type/-/archive-type-3.2.0.tgz", - "integrity": "sha1-nNnABpV+vpX62tW9YJiUKoE3N/Y=", - "dev": true, - "requires": { - "file-type": "3.9.0" - } - }, - "archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", - "dev": true - }, - "argparse": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", - "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", - "dev": true, - "requires": { - "sprintf-js": "1.0.3" - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-differ": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", - "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=" - }, - "array-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", - "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", - "dev": true - }, - "array-find-index": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", - "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", - "dev": true - }, - "array-slice": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", - "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", - "dev": true - }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "1.0.3" - } - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "async": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", - "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=", - "dev": true - }, - "async-each-series": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/async-each-series/-/async-each-series-1.1.0.tgz", - "integrity": "sha1-9C/YFV048hpbjqB8KOBj7RcAsTg=", - "dev": true, - "optional": true - }, - "atob": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.0.3.tgz", - "integrity": "sha1-GcenYEc3dEaPILLS0DNyrX1Mv10=", - "dev": true - }, - "autoprefixer": { - "version": "6.7.7", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-6.7.7.tgz", - "integrity": "sha1-Hb0cg1ZY41zj+ZhAmdsAWFx4IBQ=", - "dev": true, - "requires": { - "browserslist": "1.7.7", - "caniuse-db": "1.0.30000793", - "normalize-range": "0.1.2", - "num2fraction": "1.2.2", - "postcss": "5.2.18", - "postcss-value-parser": "3.3.0" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "1.0.1", - "class-utils": "0.3.6", - "component-emitter": "1.2.1", - "define-property": "1.0.0", - "isobject": "3.0.1", - "mixin-deep": "1.3.0", - "pascalcase": "0.1.1" - } - }, - "beeper": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", - "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=" - }, - "bin-build": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/bin-build/-/bin-build-2.2.0.tgz", - "integrity": "sha1-EfjdYfcP/Por3KpbRvXo/t1CIcw=", - "dev": true, - "optional": true, - "requires": { - "archive-type": "3.2.0", - "decompress": "3.0.0", - "download": "4.4.3", - "exec-series": "1.0.3", - "rimraf": "2.6.2", - "tempfile": "1.1.1", - "url-regex": "3.2.0" - } - }, - "bin-check": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/bin-check/-/bin-check-2.0.0.tgz", - "integrity": "sha1-hvjm9CU4k99g3DFpV/WvAqywWTA=", - "dev": true, - "optional": true, - "requires": { - "executable": "1.1.0" - } - }, - "bin-version": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/bin-version/-/bin-version-1.0.4.tgz", - "integrity": "sha1-nrSY7m/Xb3q5p8FgQ2+JV5Q1144=", - "dev": true, - "optional": true, - "requires": { - "find-versions": "1.2.1" - } - }, - "bin-version-check": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/bin-version-check/-/bin-version-check-2.1.0.tgz", - "integrity": "sha1-5OXfKQuQaffRETJAMe/BP90RpbA=", - "dev": true, - "optional": true, - "requires": { - "bin-version": "1.0.4", - "minimist": "1.2.0", - "semver": "4.3.6", - "semver-truncate": "1.1.2" - } - }, - "bin-wrapper": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/bin-wrapper/-/bin-wrapper-3.0.2.tgz", - "integrity": "sha1-Z9MwYmLksaXy+I7iNGT2plVneus=", - "dev": true, - "optional": true, - "requires": { - "bin-check": "2.0.0", - "bin-version-check": "2.1.0", - "download": "4.4.3", - "each-async": "1.1.1", - "lazy-req": "1.1.0", - "os-filter-obj": "1.0.3" - } - }, - "binaryextensions": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/binaryextensions/-/binaryextensions-1.0.1.tgz", - "integrity": "sha1-HmN0iLNbWL2l9HdL+WpSEqjJB1U=", - "dev": true - }, - "bl": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.1.tgz", - "integrity": "sha1-ysMo977kVzDUBLaSID/LWQ4XLV4=", - "dev": true, - "requires": { - "readable-stream": "2.3.3" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - } - } - }, - "bluebird": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", - "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==", - "dev": true - }, - "body-parser": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.14.2.tgz", - "integrity": "sha1-EBXLH+LEQ4WCWVgdtTMy+NDPUPk=", - "dev": true, - "requires": { - "bytes": "2.2.0", - "content-type": "1.0.4", - "debug": "2.2.0", - "depd": "1.1.2", - "http-errors": "1.3.1", - "iconv-lite": "0.4.13", - "on-finished": "2.3.0", - "qs": "5.2.0", - "raw-body": "2.1.7", - "type-is": "1.6.15" - }, - "dependencies": { - "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", - "dev": true, - "requires": { - "ms": "0.7.1" - } - }, - "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", - "dev": true - }, - "qs": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-5.2.0.tgz", - "integrity": "sha1-qfMRQq9GjLcrJbMBNrokVoNJFr4=", - "dev": true - } - } - }, - "boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" - }, - "bower": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/bower/-/bower-1.8.2.tgz", - "integrity": "sha1-rfU1KcjUrwLvJPuNU0HBQZ0z4vc=", - "dev": true - }, - "brace-expansion": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", - "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", - "dev": true, - "requires": { - "balanced-match": "1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.0.tgz", - "integrity": "sha512-P4O8UQRdGiMLWSizsApmXVQDBS6KCt7dSexgLKBmH5Hr1CZq7vsnscFh8oR1sP1ab1Zj0uCHCEzZeV6SfUf3rA==", - "dev": true, - "requires": { - "arr-flatten": "1.1.0", - "array-unique": "0.3.2", - "define-property": "1.0.0", - "extend-shallow": "2.0.1", - "fill-range": "4.0.0", - "isobject": "3.0.1", - "repeat-element": "1.1.2", - "snapdragon": "0.8.1", - "snapdragon-node": "2.1.1", - "split-string": "3.1.0", - "to-regex": "3.0.1" - } - }, - "browserslist": { - "version": "1.7.7", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz", - "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", - "dev": true, - "requires": { - "caniuse-db": "1.0.30000793", - "electron-to-chromium": "1.3.31" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true - }, - "buffer-to-vinyl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-to-vinyl/-/buffer-to-vinyl-1.1.0.tgz", - "integrity": "sha1-APFfruOreh3aLN5tkSG//dB7ImI=", - "dev": true, - "requires": { - "file-type": "3.9.0", - "readable-stream": "2.3.3", - "uuid": "2.0.3", - "vinyl": "1.2.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - }, - "vinyl": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", - "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", - "dev": true, - "requires": { - "clone": "1.0.3", - "clone-stats": "0.0.1", - "replace-ext": "0.0.1" - } - } - } - }, - "bufferstreams": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/bufferstreams/-/bufferstreams-1.0.1.tgz", - "integrity": "sha1-z7GtlWjTujz+k1upq92VLeiKqyo=", - "dev": true, - "requires": { - "readable-stream": "1.1.14" - } - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "bytes": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.2.0.tgz", - "integrity": "sha1-/TVGSkA/b5EXwt42Cez/nK4ABYg=", - "dev": true - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "1.0.0", - "component-emitter": "1.2.1", - "get-value": "2.0.6", - "has-value": "1.0.0", - "isobject": "3.0.1", - "set-value": "2.0.0", - "to-object-path": "0.3.0", - "union-value": "1.0.0", - "unset-value": "1.0.0" - } - }, - "cache-swap": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/cache-swap/-/cache-swap-0.3.0.tgz", - "integrity": "sha1-HFQaoQilAQb2ML3Zj+HeyLoTP1E=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "mkdirp": "0.5.1", - "object-assign": "4.1.1", - "rimraf": "2.6.2" - }, - "dependencies": { - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - } - } - }, - "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", - "dev": true - }, - "camelcase-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", - "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", - "dev": true, - "requires": { - "camelcase": "2.1.1", - "map-obj": "1.0.1" - } - }, - "caniuse-api": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-1.6.1.tgz", - "integrity": "sha1-tTTnxzTE+B7F++isoq0kNUuWLGw=", - "dev": true, - "requires": { - "browserslist": "1.7.7", - "caniuse-db": "1.0.30000793", - "lodash.memoize": "4.1.2", - "lodash.uniq": "4.5.0" - } - }, - "caniuse-db": { - "version": "1.0.30000793", - "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000793.tgz", - "integrity": "sha1-PADGbkI6ehkHx92Wdpp4sq+opy4=", - "dev": true - }, - "capture-stack-trace": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz", - "integrity": "sha1-Sm+gc5nCa7pH8LJJa00PtAjFVQ0=", - "dev": true - }, - "cardinal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-1.0.0.tgz", - "integrity": "sha1-UOIcGwqjdyn5N33vGWtanOyTLuk=", - "dev": true, - "requires": { - "ansicolors": "0.2.1", - "redeyed": "1.0.1" - } - }, - "caw": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/caw/-/caw-1.2.0.tgz", - "integrity": "sha1-/7Im/n78VHKI3GLuPpcHPCEtEDQ=", - "dev": true, - "requires": { - "get-proxy": "1.1.0", - "is-obj": "1.0.1", - "object-assign": "3.0.0", - "tunnel-agent": "0.4.3" - } - }, - "center-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", - "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", - "dev": true, - "requires": { - "align-text": "0.1.4", - "lazy-cache": "1.0.4" - }, - "dependencies": { - "lazy-cache": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", - "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", - "dev": true - } - } - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - }, - "cheerio": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.19.0.tgz", - "integrity": "sha1-dy5wFfLuKZZQltcepBdbdas1SSU=", - "requires": { - "css-select": "1.0.0", - "dom-serializer": "0.1.0", - "entities": "1.1.1", - "htmlparser2": "3.8.3", - "lodash": "3.10.1" - } - }, - "clap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/clap/-/clap-1.2.3.tgz", - "integrity": "sha512-4CoL/A3hf90V3VIEjeuhSvlGFEHKzOz+Wfc2IVZc+FaUgU0ZQafJTP49fvnULipOPcAfqhyI2duwQyns6xqjYA==", - "dev": true, - "requires": { - "chalk": "1.1.3" - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "3.1.0", - "define-property": "0.2.5", - "isobject": "3.0.1", - "static-extend": "0.1.2" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "0.1.6" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "clean-css": { - "version": "3.4.28", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-3.4.28.tgz", - "integrity": "sha1-vxlF6C/ICPVWlebd6uwBQA79A/8=", - "dev": true, - "requires": { - "commander": "2.8.1", - "source-map": "0.4.4" - }, - "dependencies": { - "source-map": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", - "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", - "dev": true, - "requires": { - "amdefine": "1.0.1" - } - } - } - }, - "cli": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cli/-/cli-1.0.1.tgz", - "integrity": "sha1-IoF1NPJL+klQw01TLUjsvGIbjBQ=", - "dev": true, - "requires": { - "exit": "0.1.2", - "glob": "7.1.2" - } - }, - "cli-table": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.1.tgz", - "integrity": "sha1-9TsFJmqLGguTSz0IIebi3FkUriM=", - "dev": true, - "requires": { - "colors": "1.0.3" - }, - "dependencies": { - "colors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", - "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", - "dev": true - } - } - }, - "cli-usage": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/cli-usage/-/cli-usage-0.1.7.tgz", - "integrity": "sha512-x/Q52iLSZsRrRb2ePmTsVYXrGcrPQ8G4yRAY7QpMlumxAfPVrnDOH2X6Z5s8qsAX7AA7YuIi8AXFrvH0wWEesA==", - "dev": true, - "requires": { - "marked": "0.3.12", - "marked-terminal": "2.0.0" - } - }, - "cliui": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", - "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", - "dev": true, - "requires": { - "center-align": "0.1.3", - "right-align": "0.1.3", - "wordwrap": "0.0.2" - } - }, - "clone": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.3.tgz", - "integrity": "sha1-KY1+IjFmD0DAA8LtMUDezz9TCF8=" - }, - "clone-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", - "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=", - "dev": true - }, - "clone-stats": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", - "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=" - }, - "cloneable-readable": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.0.0.tgz", - "integrity": "sha1-pikNQT8hemEjL5XkWP84QYz7ARc=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "process-nextick-args": "1.0.7", - "through2": "2.0.3" - } - }, - "co": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/co/-/co-3.1.0.tgz", - "integrity": "sha1-TqVOpaCJOBUxheFSEMaNkJK8G3g=", - "dev": true - }, - "coa": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/coa/-/coa-1.0.4.tgz", - "integrity": "sha1-qe8VNmDWqGqL3sAomlxoTSF0Mv0=", - "dev": true, - "requires": { - "q": "1.5.1" - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "1.0.0", - "object-visit": "1.0.1" - } - }, - "color": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/color/-/color-0.11.4.tgz", - "integrity": "sha1-bXtcdPtl6EHNSHkq0e1eB7kE12Q=", - "dev": true, - "requires": { - "clone": "1.0.3", - "color-convert": "1.9.1", - "color-string": "0.3.0" - } - }, - "color-convert": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", - "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "color-string": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-0.3.0.tgz", - "integrity": "sha1-J9RvtnAlxcL6JZk7+/V55HhBuZE=", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==" - }, - "colormin": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/colormin/-/colormin-1.1.2.tgz", - "integrity": "sha1-6i90IKcrlogaOKrlnsEkpvcpgTM=", - "dev": true, - "requires": { - "color": "0.11.4", - "css-color-names": "0.0.4", - "has": "1.0.1" - } - }, - "colors": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", - "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", - "dev": true - }, - "commander": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz", - "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=", - "dev": true, - "requires": { - "graceful-readlink": "1.0.1" - } - }, - "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", - "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "readable-stream": "2.3.3", - "typedarray": "0.0.6" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - } - } - }, - "concat-with-sourcemaps": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/concat-with-sourcemaps/-/concat-with-sourcemaps-1.0.5.tgz", - "integrity": "sha512-YtnS0VEY+e2Khzsey/6mra9EoM6h/5gxaC0e3mcHpA5yfDxafhygytNmcJWodvUgyXzSiL5MSkPO6bQGgfliHw==", - "dev": true, - "requires": { - "source-map": "0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "console-browserify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", - "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", - "dev": true, - "requires": { - "date-now": "0.1.4" - } - }, - "console-stream": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/console-stream/-/console-stream-0.1.1.tgz", - "integrity": "sha1-oJX+B7IEZZVfL6/Si11yvM2UnUQ=", - "dev": true, - "optional": true - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", - "dev": true - }, - "convert-source-map": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz", - "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=", - "dev": true - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "create-error-class": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", - "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", - "dev": true, - "requires": { - "capture-stack-trace": "1.0.0" - } - }, - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "dev": true, - "requires": { - "lru-cache": "4.1.1", - "shebang-command": "1.2.0", - "which": "1.3.0" - }, - "dependencies": { - "lru-cache": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", - "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", - "dev": true, - "requires": { - "pseudomap": "1.0.2", - "yallist": "2.1.2" - } - } - } - }, - "css": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/css/-/css-2.2.1.tgz", - "integrity": "sha1-c6TIHehdtmTU7mdPfUcIXjstVdw=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "source-map": "0.1.43", - "source-map-resolve": "0.3.1", - "urix": "0.1.0" - }, - "dependencies": { - "atob": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/atob/-/atob-1.1.3.tgz", - "integrity": "sha1-lfE2KbEsOlGl0hWr3OKqnzL4B3M=", - "dev": true - }, - "source-map": { - "version": "0.1.43", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", - "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", - "dev": true, - "requires": { - "amdefine": "1.0.1" - } - }, - "source-map-resolve": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.3.1.tgz", - "integrity": "sha1-YQ9hIqRFuN1RU1oqcbeD38Ekh2E=", - "dev": true, - "requires": { - "atob": "1.1.3", - "resolve-url": "0.2.1", - "source-map-url": "0.3.0", - "urix": "0.1.0" - } - }, - "source-map-url": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.3.0.tgz", - "integrity": "sha1-fsrxO1e80J2opAxdJp2zN5nUqvk=", - "dev": true - } - } - }, - "css-color-names": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", - "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=", - "dev": true - }, - "css-select": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.0.0.tgz", - "integrity": "sha1-sRIcpRhI3SZOIkTQWM7iVN7rRLA=", - "requires": { - "boolbase": "1.0.0", - "css-what": "1.0.0", - "domutils": "1.4.3", - "nth-check": "1.0.1" - } - }, - "css-what": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-1.0.0.tgz", - "integrity": "sha1-18wt9FGAZm+Z0rFEYmOUaeAPc2w=" - }, - "cssnano": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-3.10.0.tgz", - "integrity": "sha1-Tzj2zqK5sX+gFJDyPx3GjqZcHDg=", - "dev": true, - "requires": { - "autoprefixer": "6.7.7", - "decamelize": "1.2.0", - "defined": "1.0.0", - "has": "1.0.1", - "object-assign": "4.1.1", - "postcss": "5.2.18", - "postcss-calc": "5.3.1", - "postcss-colormin": "2.2.2", - "postcss-convert-values": "2.6.1", - "postcss-discard-comments": "2.0.4", - "postcss-discard-duplicates": "2.1.0", - "postcss-discard-empty": "2.1.0", - "postcss-discard-overridden": "0.1.1", - "postcss-discard-unused": "2.2.3", - "postcss-filter-plugins": "2.0.2", - "postcss-merge-idents": "2.1.7", - "postcss-merge-longhand": "2.0.2", - "postcss-merge-rules": "2.1.2", - "postcss-minify-font-values": "1.0.5", - "postcss-minify-gradients": "1.0.5", - "postcss-minify-params": "1.2.2", - "postcss-minify-selectors": "2.1.1", - "postcss-normalize-charset": "1.1.1", - "postcss-normalize-url": "3.0.8", - "postcss-ordered-values": "2.2.3", - "postcss-reduce-idents": "2.4.0", - "postcss-reduce-initial": "1.0.1", - "postcss-reduce-transforms": "1.0.4", - "postcss-svgo": "2.1.6", - "postcss-unique-selectors": "2.0.2", - "postcss-value-parser": "3.3.0", - "postcss-zindex": "2.2.0" - }, - "dependencies": { - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - } - } - }, - "csso": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/csso/-/csso-2.3.2.tgz", - "integrity": "sha1-3dUsWHAz9J6Utx/FVWnyUuj/X4U=", - "dev": true, - "requires": { - "clap": "1.2.3", - "source-map": "0.5.7" - } - }, - "currently-unhandled": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", - "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", - "dev": true, - "requires": { - "array-find-index": "1.0.2" - } - }, - "dargs": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/dargs/-/dargs-2.1.0.tgz", - "integrity": "sha1-RsJ/+rH/sTeO8hJZchNxn+YCvJM=", - "dev": true - }, - "date-now": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", - "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", - "dev": true - }, - "dateformat": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.2.0.tgz", - "integrity": "sha1-QGXiATz5+5Ft39gu+1Bq1MZ2kGI=" - }, - "deap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/deap/-/deap-1.0.0.tgz", - "integrity": "sha1-sUi/gkMKJ2mbdIOgPra2dYW/yIg=", - "dev": true - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "debug-fabulous": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/debug-fabulous/-/debug-fabulous-0.0.4.tgz", - "integrity": "sha1-+gccXYdIRoVCSAdCHKSxawsaB2M=", - "dev": true, - "requires": { - "debug": "2.6.9", - "lazy-debug-legacy": "0.0.1", - "object-assign": "4.1.0" - }, - "dependencies": { - "object-assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz", - "integrity": "sha1-ejs9DpgGPUP0wD8uiubNUahog6A=", - "dev": true - } - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "decompress": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/decompress/-/decompress-3.0.0.tgz", - "integrity": "sha1-rx3VDQbjv8QyRh033hGzjA2ZG+0=", - "dev": true, - "requires": { - "buffer-to-vinyl": "1.1.0", - "concat-stream": "1.6.0", - "decompress-tar": "3.1.0", - "decompress-tarbz2": "3.1.0", - "decompress-targz": "3.1.0", - "decompress-unzip": "3.4.0", - "stream-combiner2": "1.1.1", - "vinyl-assign": "1.2.1", - "vinyl-fs": "2.4.4" - }, - "dependencies": { - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "1.1.0" - } - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "1.8.2", - "preserve": "0.2.0", - "repeat-element": "1.1.2" - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "0.1.1" - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "1.0.0" - } - }, - "glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", - "dev": true, - "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "glob-stream": { - "version": "5.3.5", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-5.3.5.tgz", - "integrity": "sha1-pVZlqajM3EGRWofHAeMtTgFvrSI=", - "dev": true, - "requires": { - "extend": "3.0.1", - "glob": "5.0.15", - "glob-parent": "3.1.0", - "micromatch": "2.3.11", - "ordered-read-streams": "0.3.0", - "through2": "0.6.5", - "to-absolute-glob": "0.1.1", - "unique-stream": "2.2.1" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" - } - } - } - }, - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - }, - "gulp-sourcemaps": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-1.6.0.tgz", - "integrity": "sha1-uG/zSdgBzrVuHZ59x7vLS33uYAw=", - "dev": true, - "requires": { - "convert-source-map": "1.5.1", - "graceful-fs": "4.1.11", - "strip-bom": "2.0.0", - "through2": "2.0.3", - "vinyl": "1.2.0" - } - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "2.0.0", - "array-unique": "0.2.1", - "braces": "1.8.5", - "expand-brackets": "0.1.5", - "extglob": "0.3.2", - "filename-regex": "2.0.1", - "is-extglob": "1.0.0", - "is-glob": "2.0.1", - "kind-of": "3.2.2", - "normalize-path": "2.1.1", - "object.omit": "2.0.1", - "parse-glob": "3.0.4", - "regex-cache": "0.4.4" - } - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "ordered-read-streams": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.3.0.tgz", - "integrity": "sha1-cTfmmzKYuzQiR6G77jiByA4v14s=", - "dev": true, - "requires": { - "is-stream": "1.1.0", - "readable-stream": "2.3.3" - } - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "0.2.1" - } - }, - "strip-bom-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-stream/-/strip-bom-stream-1.0.0.tgz", - "integrity": "sha1-5xRDmFd9Uaa+0PoZlPoF9D/ZiO4=", - "dev": true, - "requires": { - "first-chunk-stream": "1.0.0", - "strip-bom": "2.0.0" - } - }, - "unique-stream": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.2.1.tgz", - "integrity": "sha1-WqADz76Uxf+GbE59ZouxxNuts2k=", - "dev": true, - "requires": { - "json-stable-stringify": "1.0.1", - "through2-filter": "2.0.0" - } - }, - "vinyl": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", - "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", - "dev": true, - "requires": { - "clone": "1.0.3", - "clone-stats": "0.0.1", - "replace-ext": "0.0.1" - } - }, - "vinyl-fs": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-2.4.4.tgz", - "integrity": "sha1-vm/zJwy1Xf19MGNkDegfJddTIjk=", - "dev": true, - "requires": { - "duplexify": "3.5.3", - "glob-stream": "5.3.5", - "graceful-fs": "4.1.11", - "gulp-sourcemaps": "1.6.0", - "is-valid-glob": "0.3.0", - "lazystream": "1.0.0", - "lodash.isequal": "4.5.0", - "merge-stream": "1.0.1", - "mkdirp": "0.5.1", - "object-assign": "4.1.1", - "readable-stream": "2.3.3", - "strip-bom": "2.0.0", - "strip-bom-stream": "1.0.0", - "through2": "2.0.3", - "through2-filter": "2.0.0", - "vali-date": "1.0.0", - "vinyl": "1.2.0" - } - } - } - }, - "decompress-tar": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-3.1.0.tgz", - "integrity": "sha1-IXx4n5uURQ76rcXF5TeXj8MzxGY=", - "dev": true, - "requires": { - "is-tar": "1.0.0", - "object-assign": "2.1.1", - "strip-dirs": "1.1.1", - "tar-stream": "1.5.5", - "through2": "0.6.5", - "vinyl": "0.4.6" - }, - "dependencies": { - "clone": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz", - "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=", - "dev": true - }, - "object-assign": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz", - "integrity": "sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo=", - "dev": true - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" - } - }, - "vinyl": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz", - "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=", - "dev": true, - "requires": { - "clone": "0.2.0", - "clone-stats": "0.0.1" - } - } - } - }, - "decompress-tarbz2": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-3.1.0.tgz", - "integrity": "sha1-iyOTVoE1X58YnYclag+L3ZbZZm0=", - "dev": true, - "requires": { - "is-bzip2": "1.0.0", - "object-assign": "2.1.1", - "seek-bzip": "1.0.5", - "strip-dirs": "1.1.1", - "tar-stream": "1.5.5", - "through2": "0.6.5", - "vinyl": "0.4.6" - }, - "dependencies": { - "clone": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz", - "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=", - "dev": true - }, - "object-assign": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz", - "integrity": "sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo=", - "dev": true - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" - } - }, - "vinyl": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz", - "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=", - "dev": true, - "requires": { - "clone": "0.2.0", - "clone-stats": "0.0.1" - } - } - } - }, - "decompress-targz": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-3.1.0.tgz", - "integrity": "sha1-ssE9+YFmJomRtxXWRH9kLpaW9aA=", - "dev": true, - "requires": { - "is-gzip": "1.0.0", - "object-assign": "2.1.1", - "strip-dirs": "1.1.1", - "tar-stream": "1.5.5", - "through2": "0.6.5", - "vinyl": "0.4.6" - }, - "dependencies": { - "clone": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz", - "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=", - "dev": true - }, - "object-assign": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz", - "integrity": "sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo=", - "dev": true - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" - } - }, - "vinyl": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz", - "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=", - "dev": true, - "requires": { - "clone": "0.2.0", - "clone-stats": "0.0.1" - } - } - } - }, - "decompress-unzip": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-3.4.0.tgz", - "integrity": "sha1-YUdbQVIGa74/7hL51inRX+ZHjus=", - "dev": true, - "requires": { - "is-zip": "1.0.0", - "read-all-stream": "3.1.0", - "stat-mode": "0.2.2", - "strip-dirs": "1.1.1", - "through2": "2.0.3", - "vinyl": "1.2.0", - "yauzl": "2.9.1" - }, - "dependencies": { - "vinyl": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", - "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", - "dev": true, - "requires": { - "clone": "1.0.3", - "clone-stats": "0.0.1", - "replace-ext": "0.0.1" - } - } - } - }, - "deep-extend": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz", - "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=", - "dev": true - }, - "defaults": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", - "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", - "dev": true, - "requires": { - "clone": "1.0.3" - } - }, - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "1.0.2" - } - }, - "defined": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", - "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", - "dev": true - }, - "del": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", - "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", - "dev": true, - "requires": { - "globby": "5.0.0", - "is-path-cwd": "1.0.0", - "is-path-in-cwd": "1.0.0", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "rimraf": "2.6.2" - }, - "dependencies": { - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - } - } - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "dev": true - }, - "deprecated": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/deprecated/-/deprecated-0.0.1.tgz", - "integrity": "sha1-+cmvVGSvoeepcUWKi97yqpTVuxk=", - "dev": true - }, - "detect-file": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", - "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", - "dev": true - }, - "detect-newline": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", - "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=", - "dev": true - }, - "dom-serializer": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", - "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=", - "requires": { - "domelementtype": "1.1.3", - "entities": "1.1.1" - }, - "dependencies": { - "domelementtype": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", - "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=" - } - } - }, - "domelementtype": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz", - "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=" - }, - "domhandler": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", - "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=", - "requires": { - "domelementtype": "1.3.0" - } - }, - "domutils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.4.3.tgz", - "integrity": "sha1-CGVRN5bGswYDGFDhdVFrr4C3Km8=", - "requires": { - "domelementtype": "1.3.0" - } - }, - "download": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/download/-/download-4.4.3.tgz", - "integrity": "sha1-qlX9rTktldS2jowr4D4MKqIbqaw=", - "dev": true, - "requires": { - "caw": "1.2.0", - "concat-stream": "1.6.0", - "each-async": "1.1.1", - "filenamify": "1.2.1", - "got": "5.7.1", - "gulp-decompress": "1.2.0", - "gulp-rename": "1.2.2", - "is-url": "1.2.2", - "object-assign": "4.1.1", - "read-all-stream": "3.1.0", - "readable-stream": "2.3.3", - "stream-combiner2": "1.1.1", - "vinyl": "1.2.0", - "vinyl-fs": "2.4.4", - "ware": "1.3.0" - }, - "dependencies": { - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "1.1.0" - } - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "1.8.2", - "preserve": "0.2.0", - "repeat-element": "1.1.2" - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "0.1.1" - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "1.0.0" - } - }, - "glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", - "dev": true, - "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "glob-stream": { - "version": "5.3.5", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-5.3.5.tgz", - "integrity": "sha1-pVZlqajM3EGRWofHAeMtTgFvrSI=", - "dev": true, - "requires": { - "extend": "3.0.1", - "glob": "5.0.15", - "glob-parent": "3.1.0", - "micromatch": "2.3.11", - "ordered-read-streams": "0.3.0", - "through2": "0.6.5", - "to-absolute-glob": "0.1.1", - "unique-stream": "2.2.1" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" - } - } - } - }, - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - }, - "gulp-sourcemaps": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-1.6.0.tgz", - "integrity": "sha1-uG/zSdgBzrVuHZ59x7vLS33uYAw=", - "dev": true, - "requires": { - "convert-source-map": "1.5.1", - "graceful-fs": "4.1.11", - "strip-bom": "2.0.0", - "through2": "2.0.3", - "vinyl": "1.2.0" - } - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "2.0.0", - "array-unique": "0.2.1", - "braces": "1.8.5", - "expand-brackets": "0.1.5", - "extglob": "0.3.2", - "filename-regex": "2.0.1", - "is-extglob": "1.0.0", - "is-glob": "2.0.1", - "kind-of": "3.2.2", - "normalize-path": "2.1.1", - "object.omit": "2.0.1", - "parse-glob": "3.0.4", - "regex-cache": "0.4.4" - } - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "ordered-read-streams": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.3.0.tgz", - "integrity": "sha1-cTfmmzKYuzQiR6G77jiByA4v14s=", - "dev": true, - "requires": { - "is-stream": "1.1.0", - "readable-stream": "2.3.3" - } - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "0.2.1" - } - }, - "strip-bom-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-stream/-/strip-bom-stream-1.0.0.tgz", - "integrity": "sha1-5xRDmFd9Uaa+0PoZlPoF9D/ZiO4=", - "dev": true, - "requires": { - "first-chunk-stream": "1.0.0", - "strip-bom": "2.0.0" - } - }, - "unique-stream": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.2.1.tgz", - "integrity": "sha1-WqADz76Uxf+GbE59ZouxxNuts2k=", - "dev": true, - "requires": { - "json-stable-stringify": "1.0.1", - "through2-filter": "2.0.0" - } - }, - "vinyl": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", - "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", - "dev": true, - "requires": { - "clone": "1.0.3", - "clone-stats": "0.0.1", - "replace-ext": "0.0.1" - } - }, - "vinyl-fs": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-2.4.4.tgz", - "integrity": "sha1-vm/zJwy1Xf19MGNkDegfJddTIjk=", - "dev": true, - "requires": { - "duplexify": "3.5.3", - "glob-stream": "5.3.5", - "graceful-fs": "4.1.11", - "gulp-sourcemaps": "1.6.0", - "is-valid-glob": "0.3.0", - "lazystream": "1.0.0", - "lodash.isequal": "4.5.0", - "merge-stream": "1.0.1", - "mkdirp": "0.5.1", - "object-assign": "4.1.1", - "readable-stream": "2.3.3", - "strip-bom": "2.0.0", - "strip-bom-stream": "1.0.0", - "through2": "2.0.3", - "through2-filter": "2.0.0", - "vali-date": "1.0.0", - "vinyl": "1.2.0" - } - } - } - }, - "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" - }, - "duplexer2": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", - "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", - "requires": { - "readable-stream": "1.1.14" - } - }, - "duplexify": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.3.tgz", - "integrity": "sha512-g8ID9OroF9hKt2POf8YLayy+9594PzmM3scI00/uBXocX3TWNgoB67hjzkFe9ITAbQOne/lLdBxHXvYUM4ZgGA==", - "dev": true, - "requires": { - "end-of-stream": "1.4.1", - "inherits": "2.0.3", - "readable-stream": "2.3.3", - "stream-shift": "1.0.0" - }, - "dependencies": { - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "dev": true, - "requires": { - "once": "1.4.0" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - } - } - }, - "each-async": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/each-async/-/each-async-1.1.1.tgz", - "integrity": "sha1-3uUim98KtrogEqOV4bhpq/iBNHM=", - "dev": true, - "requires": { - "onetime": "1.1.0", - "set-immediate-shim": "1.0.1" - } - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true - }, - "electron-to-chromium": { - "version": "1.3.31", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.31.tgz", - "integrity": "sha512-XE4CLbswkZgZFn34cKFy1xaX+F5LHxeDLjY1+rsK9asDzknhbrd9g/n/01/acbU25KTsUSiLKwvlLyA+6XLUOA==", - "dev": true - }, - "end-of-stream": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-0.1.5.tgz", - "integrity": "sha1-jhdyBsPICDfYVjLouTWd/osvbq8=", - "dev": true, - "requires": { - "once": "1.3.3" - }, - "dependencies": { - "once": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz", - "integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=", - "dev": true, - "requires": { - "wrappy": "1.0.2" - } - } - } - }, - "entities": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", - "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=" - }, - "error-ex": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", - "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", - "dev": true, - "requires": { - "is-arrayish": "0.2.1" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", - "dev": true - }, - "event-stream": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", - "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", - "requires": { - "duplexer": "0.1.1", - "from": "0.1.7", - "map-stream": "0.1.0", - "pause-stream": "0.0.11", - "split": "0.3.3", - "stream-combiner": "0.0.4", - "through": "2.3.8" - } - }, - "exec-buffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/exec-buffer/-/exec-buffer-2.0.1.tgz", - "integrity": "sha1-ACijG+CxRgth0HX5avRYO54zXqA=", - "dev": true, - "optional": true, - "requires": { - "rimraf": "2.6.2", - "tempfile": "1.1.1" - } - }, - "exec-series": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/exec-series/-/exec-series-1.0.3.tgz", - "integrity": "sha1-bSV6m+rEgqhyx3g7yGFYOfx3FDo=", - "dev": true, - "optional": true, - "requires": { - "async-each-series": "1.1.0", - "object-assign": "4.1.1" - }, - "dependencies": { - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true, - "optional": true - } - } - }, - "executable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/executable/-/executable-1.1.0.tgz", - "integrity": "sha1-h3mA6REvM5EGbaNyZd562ENKtNk=", - "dev": true, - "optional": true, - "requires": { - "meow": "3.7.0" - } - }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", - "dev": true - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "2.6.9", - "define-property": "0.2.5", - "extend-shallow": "2.0.1", - "posix-character-classes": "0.1.1", - "regex-not": "1.0.0", - "snapdragon": "0.8.1", - "to-regex": "3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "0.1.6" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { - "fill-range": "2.2.3" - }, - "dependencies": { - "fill-range": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", - "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", - "dev": true, - "requires": { - "is-number": "2.1.0", - "isobject": "2.1.0", - "randomatic": "1.1.7", - "repeat-element": "1.1.2", - "repeat-string": "1.6.1" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", - "dev": true, - "requires": { - "homedir-polyfill": "1.0.1" - } - }, - "extend": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", - "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", - "dev": true - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "0.1.1" - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "0.3.2", - "define-property": "1.0.0", - "expand-brackets": "2.1.4", - "extend-shallow": "2.0.1", - "fragment-cache": "0.2.1", - "regex-not": "1.0.0", - "snapdragon": "0.8.1", - "to-regex": "3.0.1" - } - }, - "fancy-log": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.2.tgz", - "integrity": "sha1-9BEl49hPLn2JpD0G2VjI94vha+E=", - "requires": { - "ansi-gray": "0.1.1", - "color-support": "1.1.3", - "time-stamp": "1.1.0" - } - }, - "faye-websocket": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.7.3.tgz", - "integrity": "sha1-zEB0x/Sk39A69U3WXDVLE1EyzhE=", - "dev": true, - "requires": { - "websocket-driver": "0.7.0" - } - }, - "fd-slicer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", - "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", - "dev": true, - "requires": { - "pend": "1.2.0" - } - }, - "figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", - "dev": true, - "optional": true, - "requires": { - "escape-string-regexp": "1.0.5", - "object-assign": "4.1.1" - }, - "dependencies": { - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true, - "optional": true - } - } - }, - "file-type": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", - "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=", - "dev": true - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, - "filename-reserved-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-1.0.0.tgz", - "integrity": "sha1-5hz4BfDeHJhFZ9A4bcXfUO5a9+Q=", - "dev": true - }, - "filenamify": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-1.2.1.tgz", - "integrity": "sha1-qfL/0RxQO+0wABUCknI3jx8TZaU=", - "dev": true, - "requires": { - "filename-reserved-regex": "1.0.0", - "strip-outer": "1.0.0", - "trim-repeated": "1.0.0" - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "2.0.1", - "is-number": "3.0.0", - "repeat-string": "1.6.1", - "to-regex-range": "2.1.1" - } - }, - "find-index": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", - "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=", - "dev": true - }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "2.1.0", - "pinkie-promise": "2.0.1" - } - }, - "find-versions": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-1.2.1.tgz", - "integrity": "sha1-y96fEuOFdaCvG+G5osXV/Y8Ya2I=", - "dev": true, - "optional": true, - "requires": { - "array-uniq": "1.0.3", - "get-stdin": "4.0.1", - "meow": "3.7.0", - "semver-regex": "1.0.0" - } - }, - "findup-sync": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", - "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", - "dev": true, - "requires": { - "detect-file": "1.0.0", - "is-glob": "3.1.0", - "micromatch": "3.1.5", - "resolve-dir": "1.0.1" - } - }, - "fined": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fined/-/fined-1.1.0.tgz", - "integrity": "sha1-s33IRLdqL15wgeiE98CuNE8VNHY=", - "dev": true, - "requires": { - "expand-tilde": "2.0.2", - "is-plain-object": "2.0.4", - "object.defaults": "1.1.0", - "object.pick": "1.3.0", - "parse-filepath": "1.0.2" - } - }, - "first-chunk-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz", - "integrity": "sha1-Wb+1DNkF9g18OUzT2ayqtOatk04=", - "dev": true - }, - "flagged-respawn": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.0.tgz", - "integrity": "sha1-Tnmumy6zi/hrO7Vr8+ClaqX8q9c=", - "dev": true - }, - "flatten": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz", - "integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=", - "dev": true - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", - "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", - "dev": true, - "requires": { - "for-in": "1.0.2" - } - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "0.2.2" - } - }, - "from": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", - "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=" - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "gaze": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/gaze/-/gaze-0.5.2.tgz", - "integrity": "sha1-QLcJU30k0dRXZ9takIaJ3+aaxE8=", - "dev": true, - "requires": { - "globule": "0.1.0" - } - }, - "get-proxy": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/get-proxy/-/get-proxy-1.1.0.tgz", - "integrity": "sha1-iUhUSRvFkbDxR9euVw9cZ4tyVus=", - "dev": true, - "requires": { - "rc": "1.2.4" - } - }, - "get-stdin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", - "dev": true - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "gifsicle": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/gifsicle/-/gifsicle-3.0.4.tgz", - "integrity": "sha1-9Fy17RAWW2ZdySng6TKLbIId+js=", - "dev": true, - "optional": true, - "requires": { - "bin-build": "2.2.0", - "bin-wrapper": "3.0.2", - "logalot": "2.1.0" - } - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "2.0.0", - "is-glob": "2.0.1" - }, - "dependencies": { - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "2.0.1" - } - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "1.0.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "3.1.0", - "path-dirname": "1.0.2" - } - }, - "glob-stream": { - "version": "3.1.18", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-3.1.18.tgz", - "integrity": "sha1-kXCl8St5Awb9/lmPMT+PeVT9FDs=", - "dev": true, - "requires": { - "glob": "4.5.3", - "glob2base": "0.0.12", - "minimatch": "2.0.10", - "ordered-read-streams": "0.1.0", - "through2": "0.6.5", - "unique-stream": "1.0.0" - }, - "dependencies": { - "glob": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-4.5.3.tgz", - "integrity": "sha1-xstz0yJsHv7wTePFbQEvAzd+4V8=", - "dev": true, - "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "2.0.10", - "once": "1.4.0" - } - }, - "minimatch": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", - "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=", - "dev": true, - "requires": { - "brace-expansion": "1.1.8" - } - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" - } - } - } - }, - "glob-watcher": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-0.0.6.tgz", - "integrity": "sha1-uVtKjfdLOcgymLDAXJeLTZo7cQs=", - "dev": true, - "requires": { - "gaze": "0.5.2" - } - }, - "glob2base": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", - "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", - "dev": true, - "requires": { - "find-index": "0.1.1" - } - }, - "global-modules": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", - "dev": true, - "requires": { - "global-prefix": "1.0.2", - "is-windows": "1.0.1", - "resolve-dir": "1.0.1" - } - }, - "global-prefix": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", - "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", - "dev": true, - "requires": { - "expand-tilde": "2.0.2", - "homedir-polyfill": "1.0.1", - "ini": "1.3.5", - "is-windows": "1.0.1", - "which": "1.3.0" - } - }, - "globby": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", - "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", - "dev": true, - "requires": { - "array-union": "1.0.2", - "arrify": "1.0.1", - "glob": "7.1.2", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" - }, - "dependencies": { - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - } - } - }, - "globule": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/globule/-/globule-0.1.0.tgz", - "integrity": "sha1-2cjt3h2nnRJaFRt5UzuXhnY0auU=", - "dev": true, - "requires": { - "glob": "3.1.21", - "lodash": "1.0.2", - "minimatch": "0.2.14" - }, - "dependencies": { - "glob": { - "version": "3.1.21", - "resolved": "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz", - "integrity": "sha1-0p4KBV3qUTj00H7UDomC6DwgZs0=", - "dev": true, - "requires": { - "graceful-fs": "1.2.3", - "inherits": "1.0.2", - "minimatch": "0.2.14" - } - }, - "graceful-fs": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz", - "integrity": "sha1-FaSAaldUfLLS2/J/QuiajDRRs2Q=", - "dev": true - }, - "inherits": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-1.0.2.tgz", - "integrity": "sha1-ykMJ2t7mtUzAuNJH6NfHoJdb3Js=", - "dev": true - }, - "lodash": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-1.0.2.tgz", - "integrity": "sha1-j1dWDIO1n8JwvT1WG2kAQ0MOJVE=", - "dev": true - }, - "minimatch": { - "version": "0.2.14", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz", - "integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=", - "dev": true, - "requires": { - "lru-cache": "2.7.3", - "sigmund": "1.0.1" - } - } - } - }, - "glogg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.0.tgz", - "integrity": "sha1-f+DxmfV6yQbPUS/urY+Q7kooT8U=", - "requires": { - "sparkles": "1.0.0" - } - }, - "got": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/got/-/got-5.7.1.tgz", - "integrity": "sha1-X4FjWmHkplifGAVp6k44FoClHzU=", - "dev": true, - "requires": { - "create-error-class": "3.0.2", - "duplexer2": "0.1.4", - "is-redirect": "1.0.0", - "is-retry-allowed": "1.1.0", - "is-stream": "1.1.0", - "lowercase-keys": "1.0.0", - "node-status-codes": "1.0.0", - "object-assign": "4.1.1", - "parse-json": "2.2.0", - "pinkie-promise": "2.0.1", - "read-all-stream": "3.1.0", - "readable-stream": "2.3.3", - "timed-out": "3.1.3", - "unzip-response": "1.0.2", - "url-parse-lax": "1.0.0" - }, - "dependencies": { - "duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", - "dev": true, - "requires": { - "readable-stream": "2.3.3" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - } - } - }, - "graceful-fs": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.11.tgz", - "integrity": "sha1-dhPHeKGv6mLyXGMKCG1/Osu92Bg=", - "dev": true, - "requires": { - "natives": "1.1.1" - } - }, - "graceful-readlink": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", - "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", - "dev": true - }, - "growly": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", - "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", - "dev": true - }, - "gulp": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/gulp/-/gulp-3.9.1.tgz", - "integrity": "sha1-VxzkWSjdQK9lFPxAEYZgFsE4RbQ=", - "dev": true, - "requires": { - "archy": "1.0.0", - "chalk": "1.1.3", - "deprecated": "0.0.1", - "gulp-util": "3.0.8", - "interpret": "1.1.0", - "liftoff": "2.5.0", - "minimist": "1.2.0", - "orchestrator": "0.3.8", - "pretty-hrtime": "1.0.3", - "semver": "4.3.6", - "tildify": "1.2.0", - "v8flags": "2.1.1", - "vinyl-fs": "0.3.14" - } - }, - "gulp-autoprefixer": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/gulp-autoprefixer/-/gulp-autoprefixer-3.1.1.tgz", - "integrity": "sha1-dSMAUc0NFxND14O36bXREg7u+bA=", - "dev": true, - "requires": { - "autoprefixer": "6.7.7", - "gulp-util": "3.0.8", - "postcss": "5.2.18", - "through2": "2.0.3", - "vinyl-sourcemaps-apply": "0.2.1" - } - }, - "gulp-cache": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/gulp-cache/-/gulp-cache-0.4.6.tgz", - "integrity": "sha1-LQO1LbT2pVOuHVvvAeSD6Qfp95Y=", - "dev": true, - "requires": { - "bluebird": "3.5.1", - "cache-swap": "0.3.0", - "gulp-util": "3.0.8", - "object-assign": "4.1.1", - "object.omit": "2.0.1", - "object.pick": "1.3.0", - "readable-stream": "2.3.3", - "try-json-parse": "0.1.1", - "vinyl": "1.2.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - }, - "vinyl": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", - "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", - "dev": true, - "requires": { - "clone": "1.0.3", - "clone-stats": "0.0.1", - "replace-ext": "0.0.1" - } - } - } - }, - "gulp-concat": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/gulp-concat/-/gulp-concat-2.6.1.tgz", - "integrity": "sha1-Yz0WyV2IUEYorQJmVmPO5aR5M1M=", - "dev": true, - "requires": { - "concat-with-sourcemaps": "1.0.5", - "through2": "2.0.3", - "vinyl": "2.1.0" - }, - "dependencies": { - "clone": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz", - "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=", - "dev": true - }, - "clone-stats": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", - "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", - "dev": true - }, - "replace-ext": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", - "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", - "dev": true - }, - "vinyl": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.1.0.tgz", - "integrity": "sha1-Ah+cLPlR1rk5lDyJ617lrdT9kkw=", - "dev": true, - "requires": { - "clone": "2.1.1", - "clone-buffer": "1.0.0", - "clone-stats": "1.0.0", - "cloneable-readable": "1.0.0", - "remove-trailing-separator": "1.1.0", - "replace-ext": "1.0.0" - } - } - } - }, - "gulp-cssnano": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/gulp-cssnano/-/gulp-cssnano-2.1.2.tgz", - "integrity": "sha1-4IoJdx7FRUpUnxoAW90lbLjl4KM=", - "dev": true, - "requires": { - "cssnano": "3.10.0", - "gulp-util": "3.0.8", - "object-assign": "4.1.1", - "vinyl-sourcemaps-apply": "0.2.1" - }, - "dependencies": { - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - } - } - }, - "gulp-decompress": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gulp-decompress/-/gulp-decompress-1.2.0.tgz", - "integrity": "sha1-jutlpeAV+O2FMsr+KEVJYGJvDcc=", - "dev": true, - "requires": { - "archive-type": "3.2.0", - "decompress": "3.0.0", - "gulp-util": "3.0.8", - "readable-stream": "2.3.3" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - } - } - }, - "gulp-filenames": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/gulp-filenames/-/gulp-filenames-4.0.1.tgz", - "integrity": "sha1-5Wmkd3uvdYs539kSDGYMDQmzLOE=", - "dev": true, - "requires": { - "gulp-util": "2.2.20", - "through2": "2.0.0" - }, - "dependencies": { - "coffee-script": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.10.0.tgz", - "integrity": "sha1-EpOLz5vhlI+gBvkuDEyegXBRCMA=" - }, - "coveralls": { - "version": "2.11.3", - "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-2.11.3.tgz", - "integrity": "sha1-+cxKJh/pCSUhL0zNGygTlzJCa5Q=", - "requires": { - "js-yaml": "3.0.1", - "lcov-parse": "0.0.6", - "log-driver": "1.2.4", - "request": "2.40.0" - }, - "dependencies": { - "js-yaml": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.0.1.tgz", - "integrity": "sha1-dkBf6lvOMPyPQF1Ixtyn8KMsav4=", - "requires": { - "argparse": "0.1.16", - "esprima": "1.0.4" - }, - "dependencies": { - "argparse": { - "version": "0.1.16", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-0.1.16.tgz", - "integrity": "sha1-z9AeD7uj1srtBJ+9dY1A9lGW9Xw=", - "requires": { - "underscore": "1.7.0", - "underscore.string": "2.4.0" - }, - "dependencies": { - "underscore": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz", - "integrity": "sha1-a7rwh3UA02vjTsqlhODbn+8DUgk=" - }, - "underscore.string": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.4.0.tgz", - "integrity": "sha1-jN2PusTi0uoefi6Al8QvRCKA+Fs=" - } - } - }, - "esprima": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz", - "integrity": "sha1-n1V+CPw7TSbs6d00+Pv0drYlha0=" - } - } - }, - "lcov-parse": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-0.0.6.tgz", - "integrity": "sha1-gZ5dqL8HkfnT857qXtGGgYfxEXU=" - }, - "log-driver": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.4.tgz", - "integrity": "sha1-LWLX+u9F2KcTQZYaBLB2HsqZz6M=" - }, - "request": { - "version": "2.40.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.40.0.tgz", - "integrity": "sha1-TdZw9pbx5uhC5mtLXoOTAaub62c=", - "requires": { - "aws-sign2": "0.5.0", - "forever-agent": "0.5.2", - "form-data": "0.1.4", - "hawk": "1.1.1", - "http-signature": "0.10.1", - "json-stringify-safe": "5.0.1", - "mime-types": "1.0.2", - "node-uuid": "1.4.3", - "oauth-sign": "0.3.0", - "qs": "1.0.2", - "stringstream": "0.0.4", - "tough-cookie": "2.0.0", - "tunnel-agent": "0.4.1" - }, - "dependencies": { - "aws-sign2": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.5.0.tgz", - "integrity": "sha1-xXED96F/wDfwLXwuZLYC6iI/fWM=", - "optional": true - }, - "forever-agent": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.5.2.tgz", - "integrity": "sha1-bQ4JxJIflKJ/Y9O0nF/v8epMUTA=" - }, - "form-data": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-0.1.4.tgz", - "integrity": "sha1-kavXiKupcCsaq/qLwBAxoqyeOxI=", - "optional": true, - "requires": { - "async": "0.9.2", - "combined-stream": "0.0.7", - "mime": "1.2.11" - }, - "dependencies": { - "async": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", - "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=", - "optional": true - }, - "combined-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz", - "integrity": "sha1-ATfmV7qlp1QcV6w3rF/AfXO03B8=", - "optional": true, - "requires": { - "delayed-stream": "0.0.5" - }, - "dependencies": { - "delayed-stream": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz", - "integrity": "sha1-1LH0OpPoKW3+AmlPRoC8N6MTxz8=", - "optional": true - } - } - }, - "mime": { - "version": "1.2.11", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz", - "integrity": "sha1-WCA+7Ybjpe8XrtK32evUfwpg3RA=", - "optional": true - } - } - }, - "hawk": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-1.1.1.tgz", - "integrity": "sha1-h81JH5tG5OKurKM1QWdmiF0tHtk=", - "optional": true, - "requires": { - "boom": "0.4.2", - "cryptiles": "0.2.2", - "hoek": "0.9.1", - "sntp": "0.2.4" - }, - "dependencies": { - "boom": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/boom/-/boom-0.4.2.tgz", - "integrity": "sha1-emNune1O/O+xnO9JR6PGffrukRs=", - "requires": { - "hoek": "0.9.1" - } - }, - "cryptiles": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-0.2.2.tgz", - "integrity": "sha1-7ZH/HxetE9N0gohZT4pIoNJvMlw=", - "optional": true, - "requires": { - "boom": "0.4.2" - } - }, - "hoek": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz", - "integrity": "sha1-PTIkYrrfB3Fup+uFuviAec3c5QU=" - }, - "sntp": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-0.2.4.tgz", - "integrity": "sha1-+4hfGLDzqtGJ+CSGJTa87ux1CQA=", - "optional": true, - "requires": { - "hoek": "0.9.1" - } - } - } - }, - "http-signature": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-0.10.1.tgz", - "integrity": "sha1-T72sEyVZqoMjEh5UB3nAoBKyfmY=", - "optional": true, - "requires": { - "asn1": "0.1.11", - "assert-plus": "0.1.5", - "ctype": "0.5.3" - }, - "dependencies": { - "asn1": { - "version": "0.1.11", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz", - "integrity": "sha1-VZvhg3bQik7E2+gId9J4GGObLfc=", - "optional": true - }, - "assert-plus": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz", - "integrity": "sha1-7nQAlBMALYTOxyGcasgRgS5yMWA=", - "optional": true - }, - "ctype": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/ctype/-/ctype-0.5.3.tgz", - "integrity": "sha1-gsGMJGH3QRTvFsE1IkrQuRRMoS8=", - "optional": true - } - } - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "mime-types": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-1.0.2.tgz", - "integrity": "sha1-mVrhOSq4r/y/yyZB3QVOlDwNXc4=" - }, - "node-uuid": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.3.tgz", - "integrity": "sha1-MZu3pW58tj8AtcDNeFHNS03fHfk=" - }, - "oauth-sign": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.3.0.tgz", - "integrity": "sha1-y1QPk7srIqfVlBaRoojWDo6pOG4=", - "optional": true - }, - "qs": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-1.0.2.tgz", - "integrity": "sha1-UKk+K1r2aRwxvOpdrnjubqGQN2g=" - }, - "stringstream": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.4.tgz", - "integrity": "sha1-Dw40I/lClgtWkqwySlfdCTvEGpI=", - "optional": true - }, - "tough-cookie": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.0.0.tgz", - "integrity": "sha1-Qc4Icgs1z5C+sETdJgn7GekocY8=", - "optional": true - }, - "tunnel-agent": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.1.tgz", - "integrity": "sha1-u+7P9NZ5znU9uUYnYaiN/Ow8WrM=", - "optional": true - } - } - } - } - }, - "event-stream": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.1.tgz", - "integrity": "sha1-uM9sABGRgeaI8zU2Pap5Fc6JC9s=", - "requires": { - "duplexer": "0.1.1", - "from": "0.1.3", - "map-stream": "0.1.0", - "pause-stream": "0.0.11", - "split": "0.3.3", - "stream-combiner": "0.0.4", - "through": "2.3.8" - }, - "dependencies": { - "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" - }, - "from": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/from/-/from-0.1.3.tgz", - "integrity": "sha1-72OsIGKsMqz3hi4NQLRLiW8i87w=" - }, - "map-stream": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", - "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=" - }, - "pause-stream": { - "version": "0.0.11", - "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", - "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", - "requires": { - "through": "2.3.8" - } - }, - "split": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", - "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", - "requires": { - "through": "2.3.8" - } - }, - "stream-combiner": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", - "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", - "requires": { - "duplexer": "0.1.1" - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - } - } - }, - "gulp": { - "version": "3.8.11", - "resolved": "https://registry.npmjs.org/gulp/-/gulp-3.8.11.tgz", - "integrity": "sha1-1Vfgpyg+tBNkkZabBJd2eXLx0oo=", - "requires": { - "archy": "1.0.0", - "chalk": "0.5.1", - "deprecated": "0.0.1", - "gulp-util": "3.0.6", - "interpret": "0.3.10", - "liftoff": "2.1.0", - "minimist": "1.1.2", - "orchestrator": "0.3.7", - "pretty-hrtime": "0.2.2", - "semver": "4.3.6", - "tildify": "1.1.0", - "v8flags": "2.0.10", - "vinyl-fs": "0.3.13" - }, - "dependencies": { - "archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=" - }, - "chalk": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz", - "integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=", - "requires": { - "ansi-styles": "1.1.0", - "escape-string-regexp": "1.0.3", - "has-ansi": "0.1.0", - "strip-ansi": "0.3.0", - "supports-color": "0.2.0" - }, - "dependencies": { - "ansi-styles": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz", - "integrity": "sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94=" - }, - "escape-string-regexp": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.3.tgz", - "integrity": "sha1-ni2LJbwlVcMzZyN1DgPwmcJzW7U=" - }, - "has-ansi": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz", - "integrity": "sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4=", - "requires": { - "ansi-regex": "0.2.1" - }, - "dependencies": { - "ansi-regex": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", - "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=" - } - } - }, - "strip-ansi": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", - "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=", - "requires": { - "ansi-regex": "0.2.1" - }, - "dependencies": { - "ansi-regex": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", - "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=" - } - } - }, - "supports-color": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz", - "integrity": "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo=" - } - } - }, - "deprecated": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/deprecated/-/deprecated-0.0.1.tgz", - "integrity": "sha1-+cmvVGSvoeepcUWKi97yqpTVuxk=" - }, - "gulp-util": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.6.tgz", - "integrity": "sha1-oLTpntvyOchglXPkhZmd38E+Hko=", - "requires": { - "array-differ": "1.0.0", - "array-uniq": "1.0.2", - "beeper": "1.1.0", - "chalk": "1.1.0", - "dateformat": "1.0.11", - "lodash._reescape": "3.0.0", - "lodash._reevaluate": "3.0.0", - "lodash._reinterpolate": "3.0.0", - "lodash.template": "3.6.2", - "minimist": "1.1.2", - "multipipe": "0.1.2", - "object-assign": "3.0.0", - "replace-ext": "0.0.1", - "through2": "2.0.0", - "vinyl": "0.5.0" - }, - "dependencies": { - "array-differ": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", - "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=" - }, - "array-uniq": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.2.tgz", - "integrity": "sha1-X8w3OSB3VyPP1k1lxkvvU7+eum0=" - }, - "beeper": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.0.tgz", - "integrity": "sha1-nub8HOf1T+qs585zWIsFYDeGaiw=" - }, - "chalk": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.0.tgz", - "integrity": "sha1-CbRTzsSXp1Ug5KYK5IIUqHAOCSE=", - "requires": { - "ansi-styles": "2.1.0", - "escape-string-regexp": "1.0.3", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.0", - "supports-color": "2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.1.0.tgz", - "integrity": "sha1-mQ90cUaSe1Wakyv5KVkWPWDA0OI=" - }, - "escape-string-regexp": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.3.tgz", - "integrity": "sha1-ni2LJbwlVcMzZyN1DgPwmcJzW7U=" - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "requires": { - "ansi-regex": "2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz", - "integrity": "sha1-xQYbbg74qBd15Q9dZhUb9r83EQc=" - } - } - }, - "strip-ansi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.0.tgz", - "integrity": "sha1-dRC2ZVZ8qRTMtdfgcnY6yWi+NyQ=", - "requires": { - "ansi-regex": "2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz", - "integrity": "sha1-xQYbbg74qBd15Q9dZhUb9r83EQc=" - } - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" - } - } - }, - "dateformat": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.11.tgz", - "integrity": "sha1-8ny+56ASu/uC6gUVYtOXf2CT27E=", - "requires": { - "get-stdin": "4.0.1", - "meow": "3.3.0" - }, - "dependencies": { - "get-stdin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=" - }, - "meow": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-3.3.0.tgz", - "integrity": "sha1-+Hd/0Ntn9z0d4b7uCMl8hmXvxu0=", - "requires": { - "camelcase-keys": "1.0.0", - "indent-string": "1.2.2", - "minimist": "1.1.2", - "object-assign": "3.0.0" - }, - "dependencies": { - "camelcase-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-1.0.0.tgz", - "integrity": "sha1-vRoRv5sxoc5JNJOpMN4aC69K1+w=", - "requires": { - "camelcase": "1.2.1", - "map-obj": "1.0.1" - }, - "dependencies": { - "camelcase": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", - "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=" - }, - "map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=" - } - } - }, - "indent-string": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-1.2.2.tgz", - "integrity": "sha1-25m8xYPrarux5I3LsZmamGBBy2s=", - "requires": { - "get-stdin": "4.0.1", - "minimist": "1.1.2", - "repeating": "1.1.3" - }, - "dependencies": { - "repeating": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-1.1.3.tgz", - "integrity": "sha1-PUEUIYh3U3SU+X93+Xhfq4EPpKw=", - "requires": { - "is-finite": "1.0.1" - }, - "dependencies": { - "is-finite": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.1.tgz", - "integrity": "sha1-ZDhgPq6+J5OUj/SkJi7I2z1iWXs=", - "requires": { - "number-is-nan": "1.0.0" - }, - "dependencies": { - "number-is-nan": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.0.tgz", - "integrity": "sha1-wCD1KcUoKt/dIz2R1LGBw9aG3Es=" - } - } - } - } - } - } - } - } - } - } - }, - "lodash._reescape": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz", - "integrity": "sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo=" - }, - "lodash._reevaluate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz", - "integrity": "sha1-WLx0xAZklTrgsSTYBpltrKQx4u0=" - }, - "lodash._reinterpolate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" - }, - "lodash.template": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz", - "integrity": "sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8=", - "requires": { - "lodash._basecopy": "3.0.1", - "lodash._basetostring": "3.0.1", - "lodash._basevalues": "3.0.0", - "lodash._isiterateecall": "3.0.9", - "lodash._reinterpolate": "3.0.0", - "lodash.escape": "3.0.0", - "lodash.keys": "3.1.2", - "lodash.restparam": "3.6.1", - "lodash.templatesettings": "3.1.0" - }, - "dependencies": { - "lodash._basecopy": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", - "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=" - }, - "lodash._basetostring": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz", - "integrity": "sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U=" - }, - "lodash._basevalues": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz", - "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=" - }, - "lodash._isiterateecall": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", - "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=" - }, - "lodash.escape": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.0.0.tgz", - "integrity": "sha1-+ylMmae/tYYDn2bWucJ+2HTLe1E=", - "requires": { - "lodash._basetostring": "3.0.1" - } - }, - "lodash.keys": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", - "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", - "requires": { - "lodash._getnative": "3.9.1", - "lodash.isarguments": "3.0.4", - "lodash.isarray": "3.0.4" - }, - "dependencies": { - "lodash._getnative": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", - "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=" - }, - "lodash.isarguments": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.0.4.tgz", - "integrity": "sha1-67uITEjSc2akTqb+5X7XtaMqgeA=" - }, - "lodash.isarray": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", - "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=" - } - } - }, - "lodash.restparam": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", - "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=" - }, - "lodash.templatesettings": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.0.tgz", - "integrity": "sha1-U4Uv2DK5IGBaLrYZGby7+484W7Y=", - "requires": { - "lodash._reinterpolate": "3.0.0", - "lodash.escape": "3.0.0" - } - } - } - }, - "multipipe": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz", - "integrity": "sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s=", - "requires": { - "duplexer2": "0.0.2" - }, - "dependencies": { - "duplexer2": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", - "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", - "requires": { - "readable-stream": "1.1.13" - }, - "dependencies": { - "readable-stream": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.13.tgz", - "integrity": "sha1-9u73ZPUUyJ4rniMUanW6EGdW0j4=", - "requires": { - "core-util-is": "1.0.1", - "inherits": "2.0.1", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - }, - "dependencies": { - "core-util-is": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz", - "integrity": "sha1-awcIWu+aPMrG7lO/nT3wwVIaVTg=" - }, - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" - } - } - } - } - } - } - }, - "object-assign": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", - "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=" - }, - "replace-ext": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", - "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=" - }, - "vinyl": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.0.tgz", - "integrity": "sha1-rUS/xJKmqEQvVlGTCyQ30/500To=", - "requires": { - "clone": "1.0.2", - "clone-stats": "0.0.1", - "replace-ext": "0.0.1" - }, - "dependencies": { - "clone": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz", - "integrity": "sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=" - }, - "clone-stats": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", - "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=" - } - } - } - } - }, - "interpret": { - "version": "0.3.10", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-0.3.10.tgz", - "integrity": "sha1-CIwl3nMcbFsRKpDwBxz69Fnlp7s=" - }, - "liftoff": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.1.0.tgz", - "integrity": "sha1-45CAUgEhwwJhKOXrvktUnu0JVTA=", - "requires": { - "extend": "2.0.1", - "findup-sync": "0.2.1", - "flagged-respawn": "0.3.1", - "rechoir": "0.6.2", - "resolve": "1.1.6" - }, - "dependencies": { - "extend": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend/-/extend-2.0.1.tgz", - "integrity": "sha1-HugBBonnOV/5RIJByYZSvHWagmA=" - }, - "findup-sync": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.2.1.tgz", - "integrity": "sha1-4KkKRQB1xJRm7lE3MgV1FLgeh4w=", - "requires": { - "glob": "4.3.5" - }, - "dependencies": { - "glob": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-4.3.5.tgz", - "integrity": "sha1-gPuwjKVA8jiszl0R0em8QedRc9M=", - "requires": { - "inflight": "1.0.4", - "inherits": "2.0.1", - "minimatch": "2.0.10", - "once": "1.3.2" - }, - "dependencies": { - "inflight": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.4.tgz", - "integrity": "sha1-bLtFIevVHODsCpNr/XZX736bFyo=", - "requires": { - "once": "1.3.2", - "wrappy": "1.0.1" - }, - "dependencies": { - "wrappy": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz", - "integrity": "sha1-HmWWmWXMvC20VIxrhKbyxa7dRzk=" - } - } - }, - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" - }, - "minimatch": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", - "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=", - "requires": { - "brace-expansion": "1.1.0" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.0.tgz", - "integrity": "sha1-ybfQPAPze8cEvhAOUitA249s/Nk=", - "requires": { - "balanced-match": "0.2.0", - "concat-map": "0.0.1" - }, - "dependencies": { - "balanced-match": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.2.0.tgz", - "integrity": "sha1-OPZzDAOqttXtu1K9k0iF51bXFnQ=" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - } - } - } - } - }, - "once": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", - "integrity": "sha1-2P7sqTsDnsHc3ud0HJK9rF4oCBs=", - "requires": { - "wrappy": "1.0.1" - }, - "dependencies": { - "wrappy": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz", - "integrity": "sha1-HmWWmWXMvC20VIxrhKbyxa7dRzk=" - } - } - } - } - } - } - }, - "flagged-respawn": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-0.3.1.tgz", - "integrity": "sha1-OXcAkl324SRSICpx6J2JVF+7vp0=" - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "requires": { - "resolve": "1.1.6" - } - }, - "resolve": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.6.tgz", - "integrity": "sha1-00kq0FTKgA9b76YS5hvqwe7Jj48=" - } - } - }, - "minimist": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.1.2.tgz", - "integrity": "sha1-r5YLgMr3GzgjY1Kvf+8QqO/O6uM=" - }, - "orchestrator": { - "version": "0.3.7", - "resolved": "https://registry.npmjs.org/orchestrator/-/orchestrator-0.3.7.tgz", - "integrity": "sha1-xFBk4ixaKnuZc09AmpX/7cfTw98=", - "requires": { - "end-of-stream": "0.1.5", - "sequencify": "0.0.7", - "stream-consume": "0.1.0" - }, - "dependencies": { - "end-of-stream": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-0.1.5.tgz", - "integrity": "sha1-jhdyBsPICDfYVjLouTWd/osvbq8=", - "requires": { - "once": "1.3.2" - }, - "dependencies": { - "once": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", - "integrity": "sha1-2P7sqTsDnsHc3ud0HJK9rF4oCBs=", - "requires": { - "wrappy": "1.0.1" - }, - "dependencies": { - "wrappy": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz", - "integrity": "sha1-HmWWmWXMvC20VIxrhKbyxa7dRzk=" - } - } - } - } - }, - "sequencify": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/sequencify/-/sequencify-0.0.7.tgz", - "integrity": "sha1-kM/xnQLgcCf9dn9erT57ldHnOAw=" - }, - "stream-consume": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/stream-consume/-/stream-consume-0.1.0.tgz", - "integrity": "sha1-pB6tGm1ggc63n2WwYZAbbY89HQ8=" - } - } - }, - "pretty-hrtime": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-0.2.2.tgz", - "integrity": "sha1-1P2INR46R0H4Fzr31qS4RvmJXAA=" - }, - "semver": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz", - "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=" - }, - "tildify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/tildify/-/tildify-1.1.0.tgz", - "integrity": "sha1-7zLLzStupP4D6YNDxIRGURZBTTg=", - "requires": { - "os-homedir": "1.0.1" - }, - "dependencies": { - "os-homedir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.1.tgz", - "integrity": "sha1-DWK99EuRb9O73PLKsZGUj7CU8Ac=" - } - } - }, - "v8flags": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.0.10.tgz", - "integrity": "sha1-ZKFhN06XSRAJx43vL5ZJAOltnO8=", - "requires": { - "user-home": "1.1.1" - }, - "dependencies": { - "user-home": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", - "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=" - } - } - }, - "vinyl-fs": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-0.3.13.tgz", - "integrity": "sha1-PThMWzAy41bNOIAj46CFMDOCrCM=", - "requires": { - "defaults": "1.0.2", - "glob-stream": "3.1.18", - "glob-watcher": "0.0.6", - "graceful-fs": "3.0.8", - "mkdirp": "0.5.1", - "strip-bom": "1.0.0", - "through2": "0.6.5", - "vinyl": "0.4.6" - }, - "dependencies": { - "defaults": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.2.tgz", - "integrity": "sha1-aQLiWqBHZJpQHhnvnpjz6DZcEJo=", - "requires": { - "clone": "0.1.19" - }, - "dependencies": { - "clone": { - "version": "0.1.19", - "resolved": "https://registry.npmjs.org/clone/-/clone-0.1.19.tgz", - "integrity": "sha1-YT+2hjmyaklKxTJT4Vsaa9iK2oU=" - } - } - }, - "glob-stream": { - "version": "3.1.18", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-3.1.18.tgz", - "integrity": "sha1-kXCl8St5Awb9/lmPMT+PeVT9FDs=", - "requires": { - "glob": "4.5.3", - "glob2base": "0.0.12", - "minimatch": "2.0.10", - "ordered-read-streams": "0.1.0", - "through2": "0.6.5", - "unique-stream": "1.0.0" - }, - "dependencies": { - "glob": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-4.5.3.tgz", - "integrity": "sha1-xstz0yJsHv7wTePFbQEvAzd+4V8=", - "requires": { - "inflight": "1.0.4", - "inherits": "2.0.1", - "minimatch": "2.0.10", - "once": "1.3.2" - }, - "dependencies": { - "inflight": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.4.tgz", - "integrity": "sha1-bLtFIevVHODsCpNr/XZX736bFyo=", - "requires": { - "once": "1.3.2", - "wrappy": "1.0.1" - }, - "dependencies": { - "wrappy": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz", - "integrity": "sha1-HmWWmWXMvC20VIxrhKbyxa7dRzk=" - } - } - }, - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" - }, - "once": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", - "integrity": "sha1-2P7sqTsDnsHc3ud0HJK9rF4oCBs=", - "requires": { - "wrappy": "1.0.1" - }, - "dependencies": { - "wrappy": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz", - "integrity": "sha1-HmWWmWXMvC20VIxrhKbyxa7dRzk=" - } - } - } - } - }, - "glob2base": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", - "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", - "requires": { - "find-index": "0.1.1" - }, - "dependencies": { - "find-index": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", - "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=" - } - } - }, - "minimatch": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", - "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=", - "requires": { - "brace-expansion": "1.1.0" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.0.tgz", - "integrity": "sha1-ybfQPAPze8cEvhAOUitA249s/Nk=", - "requires": { - "balanced-match": "0.2.0", - "concat-map": "0.0.1" - }, - "dependencies": { - "balanced-match": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.2.0.tgz", - "integrity": "sha1-OPZzDAOqttXtu1K9k0iF51bXFnQ=" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - } - } - } - } - }, - "ordered-read-streams": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.1.0.tgz", - "integrity": "sha1-/VZamvjrRHO6abbtijQ1LLVS8SY=" - }, - "unique-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-1.0.0.tgz", - "integrity": "sha1-1ZpKdUJ0R9mqbJHnAmP40mpLEEs=" - } - } - }, - "glob-watcher": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-0.0.6.tgz", - "integrity": "sha1-uVtKjfdLOcgymLDAXJeLTZo7cQs=", - "requires": { - "gaze": "0.5.1" - }, - "dependencies": { - "gaze": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/gaze/-/gaze-0.5.1.tgz", - "integrity": "sha1-IucxB47z5J0cSrERWsCRGSBRgkw=", - "requires": { - "globule": "0.1.0" - }, - "dependencies": { - "globule": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/globule/-/globule-0.1.0.tgz", - "integrity": "sha1-2cjt3h2nnRJaFRt5UzuXhnY0auU=", - "requires": { - "glob": "3.1.21", - "lodash": "1.0.2", - "minimatch": "0.2.14" - }, - "dependencies": { - "glob": { - "version": "3.1.21", - "resolved": "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz", - "integrity": "sha1-0p4KBV3qUTj00H7UDomC6DwgZs0=", - "requires": { - "graceful-fs": "1.2.3", - "inherits": "1.0.0", - "minimatch": "0.2.14" - }, - "dependencies": { - "graceful-fs": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz", - "integrity": "sha1-FaSAaldUfLLS2/J/QuiajDRRs2Q=" - }, - "inherits": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-1.0.0.tgz", - "integrity": "sha1-OOGXUoW/H3upyE2hArsSdxMirEg=" - } - } - }, - "lodash": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-1.0.2.tgz", - "integrity": "sha1-j1dWDIO1n8JwvT1WG2kAQ0MOJVE=" - }, - "minimatch": { - "version": "0.2.14", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz", - "integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=", - "requires": { - "lru-cache": "2.6.5", - "sigmund": "1.0.1" - }, - "dependencies": { - "lru-cache": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.6.5.tgz", - "integrity": "sha1-5W1jVBSO3o13B7WNFDIg/QjfD9U=" - }, - "sigmund": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", - "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=" - } - } - } - } - } - } - } - } - }, - "graceful-fs": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.8.tgz", - "integrity": "sha1-zoE+cl+oL35hR9UcmlymgnBVHCI=" - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" - } - } - }, - "strip-bom": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-1.0.0.tgz", - "integrity": "sha1-hbiGLzhEtabV7IRnqTWYFzo295Q=", - "requires": { - "first-chunk-stream": "1.0.0", - "is-utf8": "0.2.0" - }, - "dependencies": { - "first-chunk-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz", - "integrity": "sha1-Wb+1DNkF9g18OUzT2ayqtOatk04=" - }, - "is-utf8": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.0.tgz", - "integrity": "sha1-uKpUElrmJr/k4765ZfFqicWKETc=" - } - } - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "requires": { - "readable-stream": "1.0.33", - "xtend": "4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "1.0.33", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.33.tgz", - "integrity": "sha1-OjYN1mwbHX/UcFOJhg7aHQ9hEmw=", - "requires": { - "core-util-is": "1.0.1", - "inherits": "2.0.1", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - }, - "dependencies": { - "core-util-is": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz", - "integrity": "sha1-awcIWu+aPMrG7lO/nT3wwVIaVTg=" - }, - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" - } - } - }, - "xtend": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.0.tgz", - "integrity": "sha1-i8Nv+Hrtvnzp6vC8o2sjVKdDhA8=" - } - } - }, - "vinyl": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz", - "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=", - "requires": { - "clone": "0.2.0", - "clone-stats": "0.0.1" - }, - "dependencies": { - "clone": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz", - "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=" - }, - "clone-stats": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", - "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=" - } - } - } - } - } - } - }, - "gulp-util": { - "version": "2.2.20", - "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-2.2.20.tgz", - "integrity": "sha1-1xRuVyiRC9jwR6awseVJvCLb1kw=", - "dev": true, - "requires": { - "chalk": "0.5.1", - "dateformat": "1.0.11", - "lodash._reinterpolate": "2.4.1", - "lodash.template": "2.4.1", - "minimist": "0.2.0", - "multipipe": "0.1.2", - "through2": "0.5.1", - "vinyl": "0.2.3" - }, - "dependencies": { - "chalk": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz", - "integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=", - "dev": true, - "requires": { - "ansi-styles": "1.1.0", - "escape-string-regexp": "1.0.3", - "has-ansi": "0.1.0", - "strip-ansi": "0.3.0", - "supports-color": "0.2.0" - }, - "dependencies": { - "ansi-styles": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz", - "integrity": "sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94=", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.3.tgz", - "integrity": "sha1-ni2LJbwlVcMzZyN1DgPwmcJzW7U=", - "dev": true - }, - "has-ansi": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz", - "integrity": "sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4=", - "dev": true, - "requires": { - "ansi-regex": "0.2.1" - }, - "dependencies": { - "ansi-regex": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", - "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=", - "dev": true - } - } - }, - "strip-ansi": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", - "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=", - "dev": true, - "requires": { - "ansi-regex": "0.2.1" - }, - "dependencies": { - "ansi-regex": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", - "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=", - "dev": true - } - } - }, - "supports-color": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz", - "integrity": "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo=", - "dev": true - } - } - }, - "dateformat": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.11.tgz", - "integrity": "sha1-8ny+56ASu/uC6gUVYtOXf2CT27E=", - "dev": true, - "requires": { - "get-stdin": "4.0.1", - "meow": "3.3.0" - }, - "dependencies": { - "get-stdin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", - "dev": true - }, - "meow": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-3.3.0.tgz", - "integrity": "sha1-+Hd/0Ntn9z0d4b7uCMl8hmXvxu0=", - "dev": true, - "requires": { - "camelcase-keys": "1.0.0", - "indent-string": "1.2.2", - "minimist": "1.1.2", - "object-assign": "3.0.0" - }, - "dependencies": { - "camelcase-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-1.0.0.tgz", - "integrity": "sha1-vRoRv5sxoc5JNJOpMN4aC69K1+w=", - "dev": true, - "requires": { - "camelcase": "1.2.1", - "map-obj": "1.0.1" - }, - "dependencies": { - "camelcase": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", - "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", - "dev": true - }, - "map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", - "dev": true - } - } - }, - "indent-string": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-1.2.2.tgz", - "integrity": "sha1-25m8xYPrarux5I3LsZmamGBBy2s=", - "dev": true, - "requires": { - "get-stdin": "4.0.1", - "minimist": "1.1.2", - "repeating": "1.1.3" - }, - "dependencies": { - "repeating": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-1.1.3.tgz", - "integrity": "sha1-PUEUIYh3U3SU+X93+Xhfq4EPpKw=", - "dev": true, - "requires": { - "is-finite": "1.0.1" - }, - "dependencies": { - "is-finite": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.1.tgz", - "integrity": "sha1-ZDhgPq6+J5OUj/SkJi7I2z1iWXs=", - "dev": true, - "requires": { - "number-is-nan": "1.0.0" - }, - "dependencies": { - "number-is-nan": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.0.tgz", - "integrity": "sha1-wCD1KcUoKt/dIz2R1LGBw9aG3Es=", - "dev": true - } - } - } - } - } - } - }, - "minimist": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.1.2.tgz", - "integrity": "sha1-r5YLgMr3GzgjY1Kvf+8QqO/O6uM=", - "dev": true - }, - "object-assign": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", - "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=", - "dev": true - } - } - } - } - }, - "lodash._reinterpolate": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-2.4.1.tgz", - "integrity": "sha1-TxInqlqHEfxjL1sHofRgequLMiI=", - "dev": true - }, - "lodash.template": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-2.4.1.tgz", - "integrity": "sha1-nmEQB+32KRKal0qzxIuBez4c8g0=", - "dev": true, - "requires": { - "lodash._escapestringchar": "2.4.1", - "lodash._reinterpolate": "2.4.1", - "lodash.defaults": "2.4.1", - "lodash.escape": "2.4.1", - "lodash.keys": "2.4.1", - "lodash.templatesettings": "2.4.1", - "lodash.values": "2.4.1" - }, - "dependencies": { - "lodash._escapestringchar": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._escapestringchar/-/lodash._escapestringchar-2.4.1.tgz", - "integrity": "sha1-7P4iYYoq3lC/7qQ5N+Ud9m8O23I=", - "dev": true - }, - "lodash.defaults": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-2.4.1.tgz", - "integrity": "sha1-p+iIXwXmiFEUS24SqPNngCa8TFQ=", - "dev": true, - "requires": { - "lodash._objecttypes": "2.4.1", - "lodash.keys": "2.4.1" - }, - "dependencies": { - "lodash._objecttypes": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz", - "integrity": "sha1-fAt/admKH3ZSn4kLDNsbTf7BHBE=", - "dev": true - } - } - }, - "lodash.escape": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-2.4.1.tgz", - "integrity": "sha1-LOEsXghNsKV92l5dHu659dF1o7Q=", - "dev": true, - "requires": { - "lodash._escapehtmlchar": "2.4.1", - "lodash._reunescapedhtml": "2.4.1", - "lodash.keys": "2.4.1" - }, - "dependencies": { - "lodash._escapehtmlchar": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._escapehtmlchar/-/lodash._escapehtmlchar-2.4.1.tgz", - "integrity": "sha1-32fDu2t+jh6DGrSL+geVuSr+iZ0=", - "dev": true, - "requires": { - "lodash._htmlescapes": "2.4.1" - }, - "dependencies": { - "lodash._htmlescapes": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._htmlescapes/-/lodash._htmlescapes-2.4.1.tgz", - "integrity": "sha1-MtFL8IRLbeb4tioFG09nwii2JMs=", - "dev": true - } - } - }, - "lodash._reunescapedhtml": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._reunescapedhtml/-/lodash._reunescapedhtml-2.4.1.tgz", - "integrity": "sha1-dHxPxAED6zu4oJduVx96JlnpO6c=", - "dev": true, - "requires": { - "lodash._htmlescapes": "2.4.1", - "lodash.keys": "2.4.1" - }, - "dependencies": { - "lodash._htmlescapes": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._htmlescapes/-/lodash._htmlescapes-2.4.1.tgz", - "integrity": "sha1-MtFL8IRLbeb4tioFG09nwii2JMs=", - "dev": true - } - } - } - } - }, - "lodash.keys": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz", - "integrity": "sha1-SN6kbfj/djKxDXBrissmWR4rNyc=", - "dev": true, - "requires": { - "lodash._isnative": "2.4.1", - "lodash._shimkeys": "2.4.1", - "lodash.isobject": "2.4.1" - }, - "dependencies": { - "lodash._isnative": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._isnative/-/lodash._isnative-2.4.1.tgz", - "integrity": "sha1-PqZAS3hKe+g2x7V1gOHN95sUgyw=", - "dev": true - }, - "lodash._shimkeys": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._shimkeys/-/lodash._shimkeys-2.4.1.tgz", - "integrity": "sha1-bpzJZm/wgfC1psl4uD4kLmlJ0gM=", - "dev": true, - "requires": { - "lodash._objecttypes": "2.4.1" - }, - "dependencies": { - "lodash._objecttypes": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz", - "integrity": "sha1-fAt/admKH3ZSn4kLDNsbTf7BHBE=", - "dev": true - } - } - }, - "lodash.isobject": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-2.4.1.tgz", - "integrity": "sha1-Wi5H/mmVPx7mMafrof5k0tBlWPU=", - "dev": true, - "requires": { - "lodash._objecttypes": "2.4.1" - }, - "dependencies": { - "lodash._objecttypes": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz", - "integrity": "sha1-fAt/admKH3ZSn4kLDNsbTf7BHBE=", - "dev": true - } - } - } - } - }, - "lodash.templatesettings": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-2.4.1.tgz", - "integrity": "sha1-6nbHXRHrhtTb6JqDiTu4YZKaxpk=", - "dev": true, - "requires": { - "lodash._reinterpolate": "2.4.1", - "lodash.escape": "2.4.1" - } - }, - "lodash.values": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.values/-/lodash.values-2.4.1.tgz", - "integrity": "sha1-q/UUQ2s8twUAFieXjLzzCxKA7qQ=", - "dev": true, - "requires": { - "lodash.keys": "2.4.1" - } - } - } - }, - "minimist": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.2.0.tgz", - "integrity": "sha1-Tf/lJdriuGTGbC4jxicdev3s784=", - "dev": true - }, - "multipipe": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz", - "integrity": "sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s=", - "dev": true, - "requires": { - "duplexer2": "0.0.2" - }, - "dependencies": { - "duplexer2": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", - "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", - "dev": true, - "requires": { - "readable-stream": "1.1.13" - }, - "dependencies": { - "readable-stream": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.13.tgz", - "integrity": "sha1-9u73ZPUUyJ4rniMUanW6EGdW0j4=", - "dev": true, - "requires": { - "core-util-is": "1.0.1", - "inherits": "2.0.1", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - }, - "dependencies": { - "core-util-is": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz", - "integrity": "sha1-awcIWu+aPMrG7lO/nT3wwVIaVTg=", - "dev": true - }, - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - } - } - } - } - } - } - }, - "through2": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.5.1.tgz", - "integrity": "sha1-390BLrnHAOIyP9M084rGIqs3Lac=", - "dev": true, - "requires": { - "readable-stream": "1.0.33", - "xtend": "3.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "1.0.33", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.33.tgz", - "integrity": "sha1-OjYN1mwbHX/UcFOJhg7aHQ9hEmw=", - "dev": true, - "requires": { - "core-util-is": "1.0.1", - "inherits": "2.0.1", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - }, - "dependencies": { - "core-util-is": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz", - "integrity": "sha1-awcIWu+aPMrG7lO/nT3wwVIaVTg=", - "dev": true - }, - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - } - } - }, - "xtend": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz", - "integrity": "sha1-XM50B7r2Qsunvs2laBEcST9ZZlo=", - "dev": true - } - } - }, - "vinyl": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.2.3.tgz", - "integrity": "sha1-vKk4IJWC7FpJrVOKAPofEl5RMlI=", - "dev": true, - "requires": { - "clone-stats": "0.0.1" - }, - "dependencies": { - "clone-stats": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", - "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", - "dev": true - } - } - } - } - }, - "mocha": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-2.2.5.tgz", - "integrity": "sha1-07cqT+SeyUOTU/GsiT28Qw2ZMUA=", - "requires": { - "commander": "2.3.0", - "debug": "2.0.0", - "diff": "1.4.0", - "escape-string-regexp": "1.0.2", - "glob": "3.2.3", - "growl": "1.8.1", - "jade": "0.26.3", - "mkdirp": "0.5.0", - "supports-color": "1.2.1" - }, - "dependencies": { - "commander": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.3.0.tgz", - "integrity": "sha1-/UMOiJgy7DU7ms0d4hfBHLPu+HM=" - }, - "debug": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.0.0.tgz", - "integrity": "sha1-ib2d9nMrUSVrxnBTQrugLtEhMe8=", - "requires": { - "ms": "0.6.2" - }, - "dependencies": { - "ms": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.6.2.tgz", - "integrity": "sha1-2JwhJMb9wTU9Zai3e/GqxLGTcIw=" - } - } - }, - "diff": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz", - "integrity": "sha1-fyjS657nsVqX79ic5j3P2qPMur8=" - }, - "escape-string-regexp": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz", - "integrity": "sha1-Tbwv5nTnGUnK8/smlc5/LcHZqNE=" - }, - "glob": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.3.tgz", - "integrity": "sha1-4xPusknHr/qlxHUoaw4RW1mDlGc=", - "requires": { - "graceful-fs": "2.0.3", - "inherits": "2.0.1", - "minimatch": "0.2.14" - }, - "dependencies": { - "graceful-fs": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-2.0.3.tgz", - "integrity": "sha1-fNLNsiiko/Nule+mzBQt59GhNtA=" - }, - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" - }, - "minimatch": { - "version": "0.2.14", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz", - "integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=", - "requires": { - "lru-cache": "2.6.5", - "sigmund": "1.0.1" - }, - "dependencies": { - "lru-cache": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.6.5.tgz", - "integrity": "sha1-5W1jVBSO3o13B7WNFDIg/QjfD9U=" - }, - "sigmund": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", - "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=" - } - } - } - } - }, - "growl": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.8.1.tgz", - "integrity": "sha1-Sy3sjZB+k9szZiTc7AGDUC+MlCg=" - }, - "jade": { - "version": "0.26.3", - "resolved": "https://registry.npmjs.org/jade/-/jade-0.26.3.tgz", - "integrity": "sha1-jxDXl32NefL2/4YqgbBRPMslaGw=", - "requires": { - "commander": "0.6.1", - "mkdirp": "0.3.0" - }, - "dependencies": { - "commander": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-0.6.1.tgz", - "integrity": "sha1-+mihT2qUXVTbvlDYzbMyDp47GgY=" - }, - "mkdirp": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz", - "integrity": "sha1-G79asbqCevI1dRQ0kEJkVfSB/h4=" - } - } - }, - "mkdirp": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz", - "integrity": "sha1-HXMHam35hs2TROFecfzAWkyavxI=", - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" - } - } - }, - "supports-color": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-1.2.1.tgz", - "integrity": "sha1-Eu4hUHCGzZjBBY2ewPSsR2t687I=" - } - } - }, - "should": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/should/-/should-2.1.1.tgz", - "integrity": "sha1-xkixOotGRGXC+DjqDJPxLkrgbGs=" - }, - "through2": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.0.tgz", - "integrity": "sha1-9BocMd9eEp5DFERvZuygXNajBIA=", - "requires": { - "readable-stream": "2.0.2", - "xtend": "4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.2.tgz", - "integrity": "sha1-vsgb6ujPRVFovC5bKzH1vPrtmxs=", - "requires": { - "core-util-is": "1.0.1", - "inherits": "2.0.1", - "isarray": "0.0.1", - "process-nextick-args": "1.0.2", - "string_decoder": "0.10.31", - "util-deprecate": "1.0.1" - }, - "dependencies": { - "core-util-is": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz", - "integrity": "sha1-awcIWu+aPMrG7lO/nT3wwVIaVTg=" - }, - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - }, - "process-nextick-args": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.2.tgz", - "integrity": "sha1-i00/xYZmi9W2Vz5zLt8rccHB2Ko=" - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" - }, - "util-deprecate": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.1.tgz", - "integrity": "sha1-NVaj0TxMaqeYPX4kJUeBlxmbeIE=" - } - } - }, - "xtend": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.0.tgz", - "integrity": "sha1-i8Nv+Hrtvnzp6vC8o2sjVKdDhA8=" - } - } - } - } - }, - "gulp-foreach": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/gulp-foreach/-/gulp-foreach-0.1.0.tgz", - "integrity": "sha1-JUer/RobdfVptUGUGQ7xwLAolTg=", - "dev": true, - "requires": { - "gulp-util": "2.2.20", - "through2": "0.6.5" - }, - "dependencies": { - "ansi-regex": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", - "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=", - "dev": true - }, - "ansi-styles": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz", - "integrity": "sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94=", - "dev": true - }, - "chalk": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz", - "integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=", - "dev": true, - "requires": { - "ansi-styles": "1.1.0", - "escape-string-regexp": "1.0.5", - "has-ansi": "0.1.0", - "strip-ansi": "0.3.0", - "supports-color": "0.2.0" - } - }, - "dateformat": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz", - "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=", - "dev": true, - "requires": { - "get-stdin": "4.0.1", - "meow": "3.7.0" - } - }, - "gulp-util": { - "version": "2.2.20", - "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-2.2.20.tgz", - "integrity": "sha1-1xRuVyiRC9jwR6awseVJvCLb1kw=", - "dev": true, - "requires": { - "chalk": "0.5.1", - "dateformat": "1.0.12", - "lodash._reinterpolate": "2.4.1", - "lodash.template": "2.4.1", - "minimist": "0.2.0", - "multipipe": "0.1.2", - "through2": "0.5.1", - "vinyl": "0.2.3" - }, - "dependencies": { - "through2": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.5.1.tgz", - "integrity": "sha1-390BLrnHAOIyP9M084rGIqs3Lac=", - "dev": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "3.0.0" - } - } - } - }, - "has-ansi": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz", - "integrity": "sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4=", - "dev": true, - "requires": { - "ansi-regex": "0.2.1" - } - }, - "lodash._reinterpolate": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-2.4.1.tgz", - "integrity": "sha1-TxInqlqHEfxjL1sHofRgequLMiI=", - "dev": true - }, - "lodash.escape": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-2.4.1.tgz", - "integrity": "sha1-LOEsXghNsKV92l5dHu659dF1o7Q=", - "dev": true, - "requires": { - "lodash._escapehtmlchar": "2.4.1", - "lodash._reunescapedhtml": "2.4.1", - "lodash.keys": "2.4.1" - } - }, - "lodash.keys": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz", - "integrity": "sha1-SN6kbfj/djKxDXBrissmWR4rNyc=", - "dev": true, - "requires": { - "lodash._isnative": "2.4.1", - "lodash._shimkeys": "2.4.1", - "lodash.isobject": "2.4.1" - } - }, - "lodash.template": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-2.4.1.tgz", - "integrity": "sha1-nmEQB+32KRKal0qzxIuBez4c8g0=", - "dev": true, - "requires": { - "lodash._escapestringchar": "2.4.1", - "lodash._reinterpolate": "2.4.1", - "lodash.defaults": "2.4.1", - "lodash.escape": "2.4.1", - "lodash.keys": "2.4.1", - "lodash.templatesettings": "2.4.1", - "lodash.values": "2.4.1" - } - }, - "lodash.templatesettings": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-2.4.1.tgz", - "integrity": "sha1-6nbHXRHrhtTb6JqDiTu4YZKaxpk=", - "dev": true, - "requires": { - "lodash._reinterpolate": "2.4.1", - "lodash.escape": "2.4.1" - } - }, - "minimist": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.2.0.tgz", - "integrity": "sha1-Tf/lJdriuGTGbC4jxicdev3s784=", - "dev": true - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "strip-ansi": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", - "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=", - "dev": true, - "requires": { - "ansi-regex": "0.2.1" - } - }, - "supports-color": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz", - "integrity": "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo=", - "dev": true - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" - }, - "dependencies": { - "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", - "dev": true - } - } - }, - "vinyl": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.2.3.tgz", - "integrity": "sha1-vKk4IJWC7FpJrVOKAPofEl5RMlI=", - "dev": true, - "requires": { - "clone-stats": "0.0.1" - } - }, - "xtend": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz", - "integrity": "sha1-XM50B7r2Qsunvs2laBEcST9ZZlo=", - "dev": true - } - } - }, - "gulp-git": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/gulp-git/-/gulp-git-2.5.1.tgz", - "integrity": "sha512-8gGfQVKx9KjGpGpQEI7CInniwUnybZSVQNuixhRlT+giwn/DTgOI1XUqdw4lD/7Groh/V9mY1S5nsB7bLixS6A==", - "dev": true, - "requires": { - "any-shell-escape": "0.1.1", - "fancy-log": "1.3.2", - "lodash.template": "4.4.0", - "plugin-error": "0.1.2", - "require-dir": "0.3.2", - "strip-bom-stream": "3.0.0", - "through2": "2.0.3", - "vinyl": "2.1.0" - }, - "dependencies": { - "clone": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz", - "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=", - "dev": true - }, - "clone-stats": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", - "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", - "dev": true - }, - "lodash.template": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz", - "integrity": "sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A=", - "dev": true, - "requires": { - "lodash._reinterpolate": "3.0.0", - "lodash.templatesettings": "4.1.0" - } - }, - "lodash.templatesettings": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz", - "integrity": "sha1-K01OlbpEDZFf8IvImeRVNmZxMxY=", - "dev": true, - "requires": { - "lodash._reinterpolate": "3.0.0" - } - }, - "replace-ext": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", - "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", - "dev": true - }, - "vinyl": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.1.0.tgz", - "integrity": "sha1-Ah+cLPlR1rk5lDyJ617lrdT9kkw=", - "dev": true, - "requires": { - "clone": "2.1.1", - "clone-buffer": "1.0.0", - "clone-stats": "1.0.0", - "cloneable-readable": "1.0.0", - "remove-trailing-separator": "1.1.0", - "replace-ext": "1.0.0" - } - } - } - }, - "gulp-imagemin": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/gulp-imagemin/-/gulp-imagemin-2.4.0.tgz", - "integrity": "sha1-+FlIp3r1MrQRXcn7+sBK+GOnWLo=", - "dev": true, - "requires": { - "chalk": "1.1.3", - "gulp-util": "3.0.8", - "imagemin": "4.0.0", - "object-assign": "4.1.1", - "plur": "2.1.2", - "pretty-bytes": "2.0.1", - "through2-concurrent": "1.1.1" - }, - "dependencies": { - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - } - } - }, - "gulp-inject-element": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/gulp-inject-element/-/gulp-inject-element-2.0.2.tgz", - "integrity": "sha1-GX5+ILFVV38S2XilOj1W+xH2ysU=", - "requires": { - "cheerio": "0.19.0", - "event-stream": "3.3.4", - "gulp-util": "3.0.8" - } - }, - "gulp-inject-string": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/gulp-inject-string/-/gulp-inject-string-1.1.1.tgz", - "integrity": "sha512-Q25r/25DMxCEknj4nqHhpDWFGvQQNcZwnheiDIOWhOqcSUtagbidEGe3HANUdokiiIjqkTVIyIg9hP64LKh5Tw==", - "dev": true, - "requires": { - "event-stream": "3.3.4", - "plugin-error": "0.1.2" - } - }, - "gulp-jshint": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/gulp-jshint/-/gulp-jshint-2.1.0.tgz", - "integrity": "sha512-sP3NK8Y/1e58O0PH9t6s7DAr/lKDSUbIY207oWSeufM6/VclB7jJrIBcPCsyhrFTCDUl9DauePbt6VqP2vPM5w==", - "dev": true, - "requires": { - "lodash": "4.17.4", - "minimatch": "3.0.4", - "plugin-error": "0.1.2", - "rcloader": "0.2.2", - "through2": "2.0.3" - }, - "dependencies": { - "lodash": { - "version": "4.17.4", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", - "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", - "dev": true - } - } - }, - "gulp-livereload": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/gulp-livereload/-/gulp-livereload-3.8.1.tgz", - "integrity": "sha1-APdEstdJ0+njdGWJyKRKysd5tQ8=", - "dev": true, - "requires": { - "chalk": "0.5.1", - "debug": "2.6.9", - "event-stream": "3.3.4", - "gulp-util": "3.0.8", - "lodash.assign": "3.2.0", - "mini-lr": "0.1.9" - }, - "dependencies": { - "ansi-regex": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", - "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=", - "dev": true - }, - "ansi-styles": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz", - "integrity": "sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94=", - "dev": true - }, - "chalk": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz", - "integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=", - "dev": true, - "requires": { - "ansi-styles": "1.1.0", - "escape-string-regexp": "1.0.5", - "has-ansi": "0.1.0", - "strip-ansi": "0.3.0", - "supports-color": "0.2.0" - } - }, - "has-ansi": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz", - "integrity": "sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4=", - "dev": true, - "requires": { - "ansi-regex": "0.2.1" - } - }, - "lodash.assign": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-3.2.0.tgz", - "integrity": "sha1-POnwI0tLIiPilrj6CsH+6OvKZPo=", - "dev": true, - "requires": { - "lodash._baseassign": "3.2.0", - "lodash._createassigner": "3.1.1", - "lodash.keys": "3.1.2" - } - }, - "strip-ansi": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", - "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=", - "dev": true, - "requires": { - "ansi-regex": "0.2.1" - } - }, - "supports-color": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz", - "integrity": "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo=", - "dev": true - } - } - }, - "gulp-minify-css": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/gulp-minify-css/-/gulp-minify-css-1.2.4.tgz", - "integrity": "sha1-thZJV2Auon+eWtiCJ2ld0gV3jAY=", - "dev": true, - "requires": { - "clean-css": "3.4.28", - "gulp-util": "3.0.8", - "object-assign": "4.1.1", - "readable-stream": "2.3.3", - "vinyl-bufferstream": "1.0.1", - "vinyl-sourcemaps-apply": "0.2.1" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - } - } - }, - "gulp-notify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/gulp-notify/-/gulp-notify-2.2.0.tgz", - "integrity": "sha1-BGyChcKS6X7tThWgCcJsu+XO8TU=", - "dev": true, - "requires": { - "gulp-util": "3.0.8", - "lodash.template": "3.6.2", - "node-notifier": "4.6.1", - "node.extend": "1.1.6", - "through2": "0.6.5" - }, - "dependencies": { - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" - } - } - } - }, - "gulp-plumber": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gulp-plumber/-/gulp-plumber-1.2.0.tgz", - "integrity": "sha512-L/LJftsbKoHbVj6dN5pvMsyJn9jYI0wT0nMg3G6VZhDac4NesezecYTi8/48rHi+yEic3sUpw6jlSc7qNWh32A==", - "dev": true, - "requires": { - "chalk": "1.1.3", - "fancy-log": "1.3.2", - "plugin-error": "0.1.2", - "through2": "2.0.3" - } - }, - "gulp-regex-replace": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/gulp-regex-replace/-/gulp-regex-replace-0.2.3.tgz", - "integrity": "sha1-tgP/1TkbR8/ahhJqbW7vlbL/gZU=", - "dev": true, - "requires": { - "gulp-util": "2.2.20", - "through2": "0.4.2" - }, - "dependencies": { - "ansi-regex": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", - "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=", - "dev": true - }, - "ansi-styles": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz", - "integrity": "sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94=", - "dev": true - }, - "chalk": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz", - "integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=", - "dev": true, - "requires": { - "ansi-styles": "1.1.0", - "escape-string-regexp": "1.0.5", - "has-ansi": "0.1.0", - "strip-ansi": "0.3.0", - "supports-color": "0.2.0" - } - }, - "dateformat": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz", - "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=", - "dev": true, - "requires": { - "get-stdin": "4.0.1", - "meow": "3.7.0" - } - }, - "gulp-util": { - "version": "2.2.20", - "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-2.2.20.tgz", - "integrity": "sha1-1xRuVyiRC9jwR6awseVJvCLb1kw=", - "dev": true, - "requires": { - "chalk": "0.5.1", - "dateformat": "1.0.12", - "lodash._reinterpolate": "2.4.1", - "lodash.template": "2.4.1", - "minimist": "0.2.0", - "multipipe": "0.1.2", - "through2": "0.5.1", - "vinyl": "0.2.3" - }, - "dependencies": { - "through2": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.5.1.tgz", - "integrity": "sha1-390BLrnHAOIyP9M084rGIqs3Lac=", - "dev": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "3.0.0" - } - } - } - }, - "has-ansi": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz", - "integrity": "sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4=", - "dev": true, - "requires": { - "ansi-regex": "0.2.1" - } - }, - "lodash._reinterpolate": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-2.4.1.tgz", - "integrity": "sha1-TxInqlqHEfxjL1sHofRgequLMiI=", - "dev": true - }, - "lodash.escape": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-2.4.1.tgz", - "integrity": "sha1-LOEsXghNsKV92l5dHu659dF1o7Q=", - "dev": true, - "requires": { - "lodash._escapehtmlchar": "2.4.1", - "lodash._reunescapedhtml": "2.4.1", - "lodash.keys": "2.4.1" - } - }, - "lodash.keys": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz", - "integrity": "sha1-SN6kbfj/djKxDXBrissmWR4rNyc=", - "dev": true, - "requires": { - "lodash._isnative": "2.4.1", - "lodash._shimkeys": "2.4.1", - "lodash.isobject": "2.4.1" - } - }, - "lodash.template": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-2.4.1.tgz", - "integrity": "sha1-nmEQB+32KRKal0qzxIuBez4c8g0=", - "dev": true, - "requires": { - "lodash._escapestringchar": "2.4.1", - "lodash._reinterpolate": "2.4.1", - "lodash.defaults": "2.4.1", - "lodash.escape": "2.4.1", - "lodash.keys": "2.4.1", - "lodash.templatesettings": "2.4.1", - "lodash.values": "2.4.1" - } - }, - "lodash.templatesettings": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-2.4.1.tgz", - "integrity": "sha1-6nbHXRHrhtTb6JqDiTu4YZKaxpk=", - "dev": true, - "requires": { - "lodash._reinterpolate": "2.4.1", - "lodash.escape": "2.4.1" - } - }, - "minimist": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.2.0.tgz", - "integrity": "sha1-Tf/lJdriuGTGbC4jxicdev3s784=", - "dev": true - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "strip-ansi": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", - "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=", - "dev": true, - "requires": { - "ansi-regex": "0.2.1" - } - }, - "supports-color": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz", - "integrity": "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo=", - "dev": true - }, - "through2": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.4.2.tgz", - "integrity": "sha1-2/WGYDEVHsg1K7bE22SiKSqEC5s=", - "dev": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "2.1.2" - }, - "dependencies": { - "xtend": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", - "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", - "dev": true, - "requires": { - "object-keys": "0.4.0" - } - } - } - }, - "vinyl": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.2.3.tgz", - "integrity": "sha1-vKk4IJWC7FpJrVOKAPofEl5RMlI=", - "dev": true, - "requires": { - "clone-stats": "0.0.1" - } - }, - "xtend": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz", - "integrity": "sha1-XM50B7r2Qsunvs2laBEcST9ZZlo=", - "dev": true - } - } - }, - "gulp-rename": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/gulp-rename/-/gulp-rename-1.2.2.tgz", - "integrity": "sha1-OtRCh2PwXidk3sHGfYaNsnVoeBc=", - "dev": true - }, - "gulp-replace": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/gulp-replace/-/gulp-replace-0.5.4.tgz", - "integrity": "sha1-aaZ5FLvRPFYr/xT1BKQDeWqg2qk=", - "dev": true, - "requires": { - "istextorbinary": "1.0.2", - "readable-stream": "2.3.3", - "replacestream": "4.0.3" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - } - } - }, - "gulp-ruby-sass": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/gulp-ruby-sass/-/gulp-ruby-sass-2.1.1.tgz", - "integrity": "sha1-6A9lCSEI7kr8tJNgiNxyUzaa3Kw=", - "dev": true, - "requires": { - "convert-source-map": "1.5.1", - "cross-spawn": "5.1.0", - "dargs": "2.1.0", - "each-async": "1.1.1", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "glob2base": "0.0.12", - "gulp-util": "3.0.8", - "md5-hex": "1.3.0", - "object-assign": "4.1.1", - "os-tmpdir": "1.0.2", - "path-exists": "2.1.0", - "rimraf": "2.6.2" - }, - "dependencies": { - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - } - } - }, - "gulp-sourcemaps": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-1.12.0.tgz", - "integrity": "sha1-eG+XyUoPloSSRl1wVY4EJCxnlZg=", - "dev": true, - "requires": { - "@gulp-sourcemaps/map-sources": "1.0.0", - "acorn": "4.0.13", - "convert-source-map": "1.5.1", - "css": "2.2.1", - "debug-fabulous": "0.0.4", - "detect-newline": "2.1.0", - "graceful-fs": "4.1.11", - "source-map": "0.5.7", - "strip-bom": "2.0.0", - "through2": "2.0.3", - "vinyl": "1.2.0" - }, - "dependencies": { - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "0.2.1" - } - }, - "vinyl": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", - "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", - "dev": true, - "requires": { - "clone": "1.0.3", - "clone-stats": "0.0.1", - "replace-ext": "0.0.1" - } - } - } - }, - "gulp-string-replace": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/gulp-string-replace/-/gulp-string-replace-0.4.0.tgz", - "integrity": "sha1-4K+LN+LUxQ+RXW021tly/vZE9xY=", - "dev": true, - "requires": { - "extend": "3.0.1", - "gulp-util": "3.0.8", - "replacestream": "4.0.3", - "through2": "2.0.3" - } - }, - "gulp-tap": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gulp-tap/-/gulp-tap-1.0.1.tgz", - "integrity": "sha1-5nESThJZtM6iGe0cqXt/WFwzRpA=", - "dev": true, - "requires": { - "through2": "2.0.3" - } - }, - "gulp-track-filenames": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/gulp-track-filenames/-/gulp-track-filenames-0.1.0.tgz", - "integrity": "sha1-gsu6rIXTs/N/Nb+Rtyq09Z6swXw=", - "dev": true, - "requires": { - "minimatch": "0.4.0", - "through2": "0.5.1" - }, - "dependencies": { - "minimatch": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.4.0.tgz", - "integrity": "sha1-vSx9Bg0sjI/Xzefx8u0tWycP2xs=", - "dev": true, - "requires": { - "lru-cache": "2.7.3", - "sigmund": "1.0.1" - } - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "through2": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.5.1.tgz", - "integrity": "sha1-390BLrnHAOIyP9M084rGIqs3Lac=", - "dev": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "3.0.0" - } - }, - "xtend": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz", - "integrity": "sha1-XM50B7r2Qsunvs2laBEcST9ZZlo=", - "dev": true - } - } - }, - "gulp-uglify": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/gulp-uglify/-/gulp-uglify-1.5.4.tgz", - "integrity": "sha1-UkeI2HZm0J+dDCH7IXf5ADmmWMk=", - "dev": true, - "requires": { - "deap": "1.0.0", - "fancy-log": "1.3.2", - "gulp-util": "3.0.8", - "isobject": "2.1.0", - "through2": "2.0.3", - "uglify-js": "2.6.4", - "uglify-save-license": "0.4.1", - "vinyl-sourcemaps-apply": "0.2.1" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "gulp-util": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.8.tgz", - "integrity": "sha1-AFTh50RQLifATBh8PsxQXdVLu08=", - "requires": { - "array-differ": "1.0.0", - "array-uniq": "1.0.3", - "beeper": "1.1.1", - "chalk": "1.1.3", - "dateformat": "2.2.0", - "fancy-log": "1.3.2", - "gulplog": "1.0.0", - "has-gulplog": "0.1.0", - "lodash._reescape": "3.0.0", - "lodash._reevaluate": "3.0.0", - "lodash._reinterpolate": "3.0.0", - "lodash.template": "3.6.2", - "minimist": "1.2.0", - "multipipe": "0.1.2", - "object-assign": "3.0.0", - "replace-ext": "0.0.1", - "through2": "2.0.3", - "vinyl": "0.5.3" - } - }, - "gulplog": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", - "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", - "requires": { - "glogg": "1.0.0" - } - }, - "has": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", - "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", - "dev": true, - "requires": { - "function-bind": "1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "requires": { - "ansi-regex": "2.1.1" - } - }, - "has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", - "dev": true - }, - "has-gulplog": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz", - "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=", - "requires": { - "sparkles": "1.0.0" - } - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "2.0.6", - "has-values": "1.0.0", - "isobject": "3.0.1" - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "3.0.0", - "kind-of": "4.0.0" - }, - "dependencies": { - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "homedir-polyfill": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz", - "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=", - "dev": true, - "requires": { - "parse-passwd": "1.0.0" - } - }, - "hosted-git-info": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", - "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==", - "dev": true - }, - "html-comment-regex": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.1.tgz", - "integrity": "sha1-ZouTd26q5V696POtRkswekljYl4=", - "dev": true - }, - "htmlparser2": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", - "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=", - "requires": { - "domelementtype": "1.3.0", - "domhandler": "2.3.0", - "domutils": "1.5.1", - "entities": "1.0.0", - "readable-stream": "1.1.14" - }, - "dependencies": { - "domutils": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", - "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", - "requires": { - "dom-serializer": "0.1.0", - "domelementtype": "1.3.0" - } - }, - "entities": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", - "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=" - } - } - }, - "http-errors": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.3.1.tgz", - "integrity": "sha1-GX4izevUGYWF6GlO9nhhl7ke2UI=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "statuses": "1.4.0" - } - }, - "http-parser-js": { - "version": "0.4.9", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.9.tgz", - "integrity": "sha1-6hoE+2St/wJC6ZdPKX3Uw8rSceE=", - "dev": true - }, - "iconv-lite": { - "version": "0.4.13", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz", - "integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI=", - "dev": true - }, - "imagemin": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/imagemin/-/imagemin-4.0.0.tgz", - "integrity": "sha1-6Q5/CTaDZZXxj6Ff6Qb0+iWeqEc=", - "dev": true, - "requires": { - "buffer-to-vinyl": "1.1.0", - "concat-stream": "1.6.0", - "imagemin-gifsicle": "4.2.0", - "imagemin-jpegtran": "4.3.2", - "imagemin-optipng": "4.3.0", - "imagemin-svgo": "4.2.1", - "optional": "0.1.4", - "readable-stream": "2.3.3", - "stream-combiner2": "1.1.1", - "vinyl-fs": "2.4.4" - }, - "dependencies": { - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "1.1.0" - } - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "1.8.2", - "preserve": "0.2.0", - "repeat-element": "1.1.2" - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "0.1.1" - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "1.0.0" - } - }, - "glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", - "dev": true, - "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "glob-stream": { - "version": "5.3.5", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-5.3.5.tgz", - "integrity": "sha1-pVZlqajM3EGRWofHAeMtTgFvrSI=", - "dev": true, - "requires": { - "extend": "3.0.1", - "glob": "5.0.15", - "glob-parent": "3.1.0", - "micromatch": "2.3.11", - "ordered-read-streams": "0.3.0", - "through2": "0.6.5", - "to-absolute-glob": "0.1.1", - "unique-stream": "2.2.1" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" - } - } - } - }, - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - }, - "gulp-sourcemaps": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-1.6.0.tgz", - "integrity": "sha1-uG/zSdgBzrVuHZ59x7vLS33uYAw=", - "dev": true, - "requires": { - "convert-source-map": "1.5.1", - "graceful-fs": "4.1.11", - "strip-bom": "2.0.0", - "through2": "2.0.3", - "vinyl": "1.2.0" - } - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "2.0.0", - "array-unique": "0.2.1", - "braces": "1.8.5", - "expand-brackets": "0.1.5", - "extglob": "0.3.2", - "filename-regex": "2.0.1", - "is-extglob": "1.0.0", - "is-glob": "2.0.1", - "kind-of": "3.2.2", - "normalize-path": "2.1.1", - "object.omit": "2.0.1", - "parse-glob": "3.0.4", - "regex-cache": "0.4.4" - } - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "ordered-read-streams": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.3.0.tgz", - "integrity": "sha1-cTfmmzKYuzQiR6G77jiByA4v14s=", - "dev": true, - "requires": { - "is-stream": "1.1.0", - "readable-stream": "2.3.3" - } - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "0.2.1" - } - }, - "strip-bom-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-stream/-/strip-bom-stream-1.0.0.tgz", - "integrity": "sha1-5xRDmFd9Uaa+0PoZlPoF9D/ZiO4=", - "dev": true, - "requires": { - "first-chunk-stream": "1.0.0", - "strip-bom": "2.0.0" - } - }, - "unique-stream": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.2.1.tgz", - "integrity": "sha1-WqADz76Uxf+GbE59ZouxxNuts2k=", - "dev": true, - "requires": { - "json-stable-stringify": "1.0.1", - "through2-filter": "2.0.0" - } - }, - "vinyl": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", - "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", - "dev": true, - "requires": { - "clone": "1.0.3", - "clone-stats": "0.0.1", - "replace-ext": "0.0.1" - } - }, - "vinyl-fs": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-2.4.4.tgz", - "integrity": "sha1-vm/zJwy1Xf19MGNkDegfJddTIjk=", - "dev": true, - "requires": { - "duplexify": "3.5.3", - "glob-stream": "5.3.5", - "graceful-fs": "4.1.11", - "gulp-sourcemaps": "1.6.0", - "is-valid-glob": "0.3.0", - "lazystream": "1.0.0", - "lodash.isequal": "4.5.0", - "merge-stream": "1.0.1", - "mkdirp": "0.5.1", - "object-assign": "4.1.1", - "readable-stream": "2.3.3", - "strip-bom": "2.0.0", - "strip-bom-stream": "1.0.0", - "through2": "2.0.3", - "through2-filter": "2.0.0", - "vali-date": "1.0.0", - "vinyl": "1.2.0" - } - } - } - }, - "imagemin-gifsicle": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/imagemin-gifsicle/-/imagemin-gifsicle-4.2.0.tgz", - "integrity": "sha1-D++butNHbmt2iFc2zFsLh6CHV8o=", - "dev": true, - "optional": true, - "requires": { - "gifsicle": "3.0.4", - "is-gif": "1.0.0", - "through2": "0.6.5" - }, - "dependencies": { - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "optional": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true, - "optional": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" - } - } - } - }, - "imagemin-jpegtran": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/imagemin-jpegtran/-/imagemin-jpegtran-4.3.2.tgz", - "integrity": "sha1-G8bR4r0T/bZNJFUm1jWn5d/rEvw=", - "dev": true, - "optional": true, - "requires": { - "is-jpg": "1.0.0", - "jpegtran-bin": "3.2.0", - "through2": "2.0.3" - } - }, - "imagemin-optipng": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/imagemin-optipng/-/imagemin-optipng-4.3.0.tgz", - "integrity": "sha1-dgRmOrLuMVczJ0cm/Rw3TStErbY=", - "dev": true, - "optional": true, - "requires": { - "exec-buffer": "2.0.1", - "is-png": "1.1.0", - "optipng-bin": "3.1.4", - "through2": "0.6.5" - }, - "dependencies": { - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "optional": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true, - "optional": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" - } - } - } - }, - "imagemin-svgo": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/imagemin-svgo/-/imagemin-svgo-4.2.1.tgz", - "integrity": "sha1-VPB9xW9HJgRi32phxUvvtEtXvlU=", - "dev": true, - "optional": true, - "requires": { - "is-svg": "1.1.1", - "svgo": "0.6.6", - "through2": "2.0.3" - }, - "dependencies": { - "csso": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/csso/-/csso-2.0.0.tgz", - "integrity": "sha1-F4tDpEYhIhwndWCG9THgL0KQDug=", - "dev": true, - "optional": true, - "requires": { - "clap": "1.2.3", - "source-map": "0.5.7" - } - }, - "is-svg": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-1.1.1.tgz", - "integrity": "sha1-rA76r7ZTrFhHNwix+HNjbKEQ4xs=", - "dev": true, - "optional": true - }, - "js-yaml": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.6.1.tgz", - "integrity": "sha1-bl/mfYsgXOTSL60Ft3geja3MSzA=", - "dev": true, - "optional": true, - "requires": { - "argparse": "1.0.9", - "esprima": "2.7.3" - } - }, - "svgo": { - "version": "0.6.6", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-0.6.6.tgz", - "integrity": "sha1-s0CIkDbyD5tEdUMHfQ9Vc+0ETAg=", - "dev": true, - "optional": true, - "requires": { - "coa": "1.0.4", - "colors": "1.1.2", - "csso": "2.0.0", - "js-yaml": "3.6.1", - "mkdirp": "0.5.1", - "sax": "1.2.4", - "whet.extend": "0.9.9" - } - } - } - }, - "indent-string": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", - "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", - "dev": true, - "requires": { - "repeating": "2.0.1" - } - }, - "indexes-of": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", - "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", - "dev": true - }, - "interpret": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", - "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", - "dev": true - }, - "ip-regex": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-1.0.3.tgz", - "integrity": "sha1-3FiQdvZZ9BnCIgOaMzFvHHOH7/0=", - "dev": true, - "optional": true - }, - "irregular-plurals": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-1.4.0.tgz", - "integrity": "sha1-LKmwM2UREYVUEvFr5dd8YqRYp2Y=", - "dev": true - }, - "is": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/is/-/is-3.2.1.tgz", - "integrity": "sha1-0Kwq1V63sL7JJqUmb2xmKqqD3KU=", - "dev": true - }, - "is-absolute": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", - "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", - "dev": true, - "requires": { - "is-relative": "1.0.0", - "is-windows": "1.0.1" - } - }, - "is-absolute-url": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", - "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=", - "dev": true - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "6.0.2" - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "is-builtin-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", - "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", - "dev": true, - "requires": { - "builtin-modules": "1.1.1" - } - }, - "is-bzip2": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-bzip2/-/is-bzip2-1.0.0.tgz", - "integrity": "sha1-XuWOqlounIDiFAe+3yOuWsCRs/w=", - "dev": true - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "6.0.2" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" - } - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-finite": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", - "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", - "dev": true, - "requires": { - "number-is-nan": "1.0.1" - } - }, - "is-gif": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-gif/-/is-gif-1.0.0.tgz", - "integrity": "sha1-ptKumIkwB7/6l6HYwB1jIFgyCX4=", - "dev": true, - "optional": true - }, - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "2.1.1" - } - }, - "is-gzip": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-gzip/-/is-gzip-1.0.0.tgz", - "integrity": "sha1-bKiwe5nHeZgCWQDlVc7Y7YCHmoM=", - "dev": true - }, - "is-jpg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-jpg/-/is-jpg-1.0.0.tgz", - "integrity": "sha1-KVnBfnNDDbOCZNp1uQ3VTy2G2hw=", - "dev": true, - "optional": true - }, - "is-natural-number": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-2.1.1.tgz", - "integrity": "sha1-fUxXKDd+84bD4ZSpkRv1fG3DNec=", - "dev": true - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", - "dev": true - }, - "is-odd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-1.0.0.tgz", - "integrity": "sha1-O4qTLrAos3dcObsJ6RdnrM22kIg=", - "dev": true, - "requires": { - "is-number": "3.0.0" - } - }, - "is-path-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", - "dev": true - }, - "is-path-in-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", - "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", - "dev": true, - "requires": { - "is-path-inside": "1.0.1" - } - }, - "is-path-inside": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", - "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", - "dev": true, - "requires": { - "path-is-inside": "1.0.2" - } - }, - "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", - "dev": true - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "3.0.1" - } - }, - "is-png": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-png/-/is-png-1.1.0.tgz", - "integrity": "sha1-1XSxK/J1wDUEVVcLDltXqwYgd84=", - "dev": true, - "optional": true - }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, - "is-redirect": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", - "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=", - "dev": true - }, - "is-relative": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", - "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", - "dev": true, - "requires": { - "is-unc-path": "1.0.0" - } - }, - "is-retry-allowed": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", - "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=", - "dev": true - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, - "is-svg": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-2.1.0.tgz", - "integrity": "sha1-z2EJDaDZ77yrhyLeum8DIgjbsOk=", - "dev": true, - "requires": { - "html-comment-regex": "1.1.1" - } - }, - "is-tar": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-tar/-/is-tar-1.0.0.tgz", - "integrity": "sha1-L2suF5LB9bs2UZrKqdZcDSb+hT0=", - "dev": true - }, - "is-unc-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", - "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", - "dev": true, - "requires": { - "unc-path-regex": "0.1.2" - } - }, - "is-url": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.2.tgz", - "integrity": "sha1-SYkFpZO/R8wtnn9zg3K792lsfyY=", - "dev": true - }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", - "dev": true - }, - "is-valid-glob": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-0.3.0.tgz", - "integrity": "sha1-1LVcafUYhvm2XHDWwmItN+KfSP4=", - "dev": true - }, - "is-windows": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.1.tgz", - "integrity": "sha1-MQ23D3QtJZoWo2kgK1GvhCMzENk=", - "dev": true - }, - "is-zip": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-zip/-/is-zip-1.0.0.tgz", - "integrity": "sha1-R7Co/004p2QxzP2ZqOFaTIa6IyU=", - "dev": true - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, - "istextorbinary": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/istextorbinary/-/istextorbinary-1.0.2.tgz", - "integrity": "sha1-rOGTVNGpoBc+/rEITOD4ewrX3s8=", - "dev": true, - "requires": { - "binaryextensions": "1.0.1", - "textextensions": "1.0.2" - } - }, - "jpegtran-bin": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jpegtran-bin/-/jpegtran-bin-3.2.0.tgz", - "integrity": "sha1-9g7PSumZwL2tLp+83ytvCYHnops=", - "dev": true, - "optional": true, - "requires": { - "bin-build": "2.2.0", - "bin-wrapper": "3.0.2", - "logalot": "2.1.0" - } - }, - "js-base64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.1.tgz", - "integrity": "sha512-2h586r2I/CqU7z1aa1kBgWaVAXWAZK+zHnceGi/jFgn7+7VSluxYer/i3xOZVearCxxXvyDkLtTBo+OeJCA3kA==", - "dev": true - }, - "js-yaml": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.7.0.tgz", - "integrity": "sha1-XJZ93YN6m/3KXy3oQlOr6KHAO4A=", - "dev": true, - "requires": { - "argparse": "1.0.9", - "esprima": "2.7.3" - } - }, - "jshint": { - "version": "2.9.5", - "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.9.5.tgz", - "integrity": "sha1-HnJSkVzmgbQIJ+4UJIxG006apiw=", - "dev": true, - "requires": { - "cli": "1.0.1", - "console-browserify": "1.1.0", - "exit": "0.1.2", - "htmlparser2": "3.8.3", - "lodash": "3.7.0", - "minimatch": "3.0.4", - "shelljs": "0.3.0", - "strip-json-comments": "1.0.4" - }, - "dependencies": { - "lodash": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.7.0.tgz", - "integrity": "sha1-Nni9irmVBXwHreg27S7wh9qBHUU=", - "dev": true - }, - "strip-json-comments": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", - "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=", - "dev": true - } - } - }, - "json-stable-stringify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", - "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", - "dev": true, - "requires": { - "jsonify": "0.0.0" - } - }, - "jsonify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - }, - "lazy-cache": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-2.0.2.tgz", - "integrity": "sha1-uRkKT5EzVGlIQIWfio9whNiCImQ=", - "dev": true, - "requires": { - "set-getter": "0.1.0" - } - }, - "lazy-debug-legacy": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/lazy-debug-legacy/-/lazy-debug-legacy-0.0.1.tgz", - "integrity": "sha1-U3cWwHduTPeePtG2IfdljCkRsbE=", - "dev": true - }, - "lazy-req": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/lazy-req/-/lazy-req-1.1.0.tgz", - "integrity": "sha1-va6+rTD42CQDnODOFJ1Nqge6H6w=", - "dev": true, - "optional": true - }, - "lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", - "dev": true, - "requires": { - "readable-stream": "2.3.3" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - } - } - }, - "liftoff": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.5.0.tgz", - "integrity": "sha1-IAkpG7Mc6oYbvxCnwVooyvdcMew=", - "dev": true, - "requires": { - "extend": "3.0.1", - "findup-sync": "2.0.0", - "fined": "1.1.0", - "flagged-respawn": "1.0.0", - "is-plain-object": "2.0.4", - "object.map": "1.0.1", - "rechoir": "0.6.2", - "resolve": "1.5.0" - } - }, - "livereload-js": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-2.3.0.tgz", - "integrity": "sha512-j1R0/FeGa64Y+NmqfZhyoVRzcFlOZ8sNlKzHjh4VvLULFACZhn68XrX5DFg2FhMvSMJmROuFxRSa560ECWKBMg==", - "dev": true - }, - "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "parse-json": "2.2.0", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "strip-bom": "2.0.0" - }, - "dependencies": { - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "0.2.1" - } - } - } - }, - "lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" - }, - "lodash._arraycopy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._arraycopy/-/lodash._arraycopy-3.0.0.tgz", - "integrity": "sha1-due3wfH7klRzdIeKVi7Qaj5Q9uE=", - "dev": true - }, - "lodash._arrayeach": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._arrayeach/-/lodash._arrayeach-3.0.0.tgz", - "integrity": "sha1-urFWsqkNPxu9XGU0AzSeXlkz754=", - "dev": true - }, - "lodash._baseassign": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz", - "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=", - "dev": true, - "requires": { - "lodash._basecopy": "3.0.1", - "lodash.keys": "3.1.2" - } - }, - "lodash._baseclone": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/lodash._baseclone/-/lodash._baseclone-3.3.0.tgz", - "integrity": "sha1-MDUZv2OT/n5C802LYw73eU41Qrc=", - "dev": true, - "requires": { - "lodash._arraycopy": "3.0.0", - "lodash._arrayeach": "3.0.0", - "lodash._baseassign": "3.2.0", - "lodash._basefor": "3.0.3", - "lodash.isarray": "3.0.4", - "lodash.keys": "3.1.2" - } - }, - "lodash._basecopy": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", - "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=" - }, - "lodash._basefor": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash._basefor/-/lodash._basefor-3.0.3.tgz", - "integrity": "sha1-dVC06SGO8J+tJDQ7YSAhx5tMIMI=", - "dev": true - }, - "lodash._basetostring": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz", - "integrity": "sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U=" - }, - "lodash._basevalues": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz", - "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=" - }, - "lodash._bindcallback": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz", - "integrity": "sha1-5THCdkTPi1epnhftlbNcdIeJOS4=", - "dev": true - }, - "lodash._createassigner": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/lodash._createassigner/-/lodash._createassigner-3.1.1.tgz", - "integrity": "sha1-g4pbri/aymOsIt7o4Z+k5taXCxE=", - "dev": true, - "requires": { - "lodash._bindcallback": "3.0.1", - "lodash._isiterateecall": "3.0.9", - "lodash.restparam": "3.6.1" - } - }, - "lodash._escapehtmlchar": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._escapehtmlchar/-/lodash._escapehtmlchar-2.4.1.tgz", - "integrity": "sha1-32fDu2t+jh6DGrSL+geVuSr+iZ0=", - "dev": true, - "requires": { - "lodash._htmlescapes": "2.4.1" - } - }, - "lodash._escapestringchar": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._escapestringchar/-/lodash._escapestringchar-2.4.1.tgz", - "integrity": "sha1-7P4iYYoq3lC/7qQ5N+Ud9m8O23I=", - "dev": true - }, - "lodash._getnative": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", - "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=" - }, - "lodash._htmlescapes": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._htmlescapes/-/lodash._htmlescapes-2.4.1.tgz", - "integrity": "sha1-MtFL8IRLbeb4tioFG09nwii2JMs=", - "dev": true - }, - "lodash._isiterateecall": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", - "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=" - }, - "lodash._isnative": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._isnative/-/lodash._isnative-2.4.1.tgz", - "integrity": "sha1-PqZAS3hKe+g2x7V1gOHN95sUgyw=", - "dev": true - }, - "lodash._objecttypes": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz", - "integrity": "sha1-fAt/admKH3ZSn4kLDNsbTf7BHBE=", - "dev": true - }, - "lodash._reescape": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz", - "integrity": "sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo=" - }, - "lodash._reevaluate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz", - "integrity": "sha1-WLx0xAZklTrgsSTYBpltrKQx4u0=" - }, - "lodash._reinterpolate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" - }, - "lodash._reunescapedhtml": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._reunescapedhtml/-/lodash._reunescapedhtml-2.4.1.tgz", - "integrity": "sha1-dHxPxAED6zu4oJduVx96JlnpO6c=", - "dev": true, - "requires": { - "lodash._htmlescapes": "2.4.1", - "lodash.keys": "2.4.1" - }, - "dependencies": { - "lodash.keys": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz", - "integrity": "sha1-SN6kbfj/djKxDXBrissmWR4rNyc=", - "dev": true, - "requires": { - "lodash._isnative": "2.4.1", - "lodash._shimkeys": "2.4.1", - "lodash.isobject": "2.4.1" - } - } - } - }, - "lodash._root": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz", - "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=" - }, - "lodash._shimkeys": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash._shimkeys/-/lodash._shimkeys-2.4.1.tgz", - "integrity": "sha1-bpzJZm/wgfC1psl4uD4kLmlJ0gM=", - "dev": true, - "requires": { - "lodash._objecttypes": "2.4.1" - } - }, - "lodash.assign": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", - "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=", - "dev": true - }, - "lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", - "dev": true - }, - "lodash.defaults": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-2.4.1.tgz", - "integrity": "sha1-p+iIXwXmiFEUS24SqPNngCa8TFQ=", - "dev": true, - "requires": { - "lodash._objecttypes": "2.4.1", - "lodash.keys": "2.4.1" - }, - "dependencies": { - "lodash.keys": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz", - "integrity": "sha1-SN6kbfj/djKxDXBrissmWR4rNyc=", - "dev": true, - "requires": { - "lodash._isnative": "2.4.1", - "lodash._shimkeys": "2.4.1", - "lodash.isobject": "2.4.1" - } - } - } - }, - "lodash.escape": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz", - "integrity": "sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg=", - "requires": { - "lodash._root": "3.0.1" - } - }, - "lodash.isarguments": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", - "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=" - }, - "lodash.isarray": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", - "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=" - }, - "lodash.isequal": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", - "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=", - "dev": true - }, - "lodash.isobject": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-2.4.1.tgz", - "integrity": "sha1-Wi5H/mmVPx7mMafrof5k0tBlWPU=", - "dev": true, - "requires": { - "lodash._objecttypes": "2.4.1" - } - }, - "lodash.keys": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", - "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", - "requires": { - "lodash._getnative": "3.9.1", - "lodash.isarguments": "3.1.0", - "lodash.isarray": "3.0.4" - } - }, - "lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", - "dev": true - }, - "lodash.merge": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.0.tgz", - "integrity": "sha1-aYhLoUSsM/5plzemCG3v+t0PicU=", - "dev": true - }, - "lodash.restparam": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", - "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=" - }, - "lodash.template": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz", - "integrity": "sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8=", - "requires": { - "lodash._basecopy": "3.0.1", - "lodash._basetostring": "3.0.1", - "lodash._basevalues": "3.0.0", - "lodash._isiterateecall": "3.0.9", - "lodash._reinterpolate": "3.0.0", - "lodash.escape": "3.2.0", - "lodash.keys": "3.1.2", - "lodash.restparam": "3.6.1", - "lodash.templatesettings": "3.1.1" - } - }, - "lodash.templatesettings": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz", - "integrity": "sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU=", - "requires": { - "lodash._reinterpolate": "3.0.0", - "lodash.escape": "3.2.0" - } - }, - "lodash.toarray": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz", - "integrity": "sha1-JMS/zWsvuji/0FlNsRedjptlZWE=", - "dev": true - }, - "lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", - "dev": true - }, - "lodash.values": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.values/-/lodash.values-2.4.1.tgz", - "integrity": "sha1-q/UUQ2s8twUAFieXjLzzCxKA7qQ=", - "dev": true, - "requires": { - "lodash.keys": "2.4.1" - }, - "dependencies": { - "lodash.keys": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz", - "integrity": "sha1-SN6kbfj/djKxDXBrissmWR4rNyc=", - "dev": true, - "requires": { - "lodash._isnative": "2.4.1", - "lodash._shimkeys": "2.4.1", - "lodash.isobject": "2.4.1" - } - } - } - }, - "logalot": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/logalot/-/logalot-2.1.0.tgz", - "integrity": "sha1-X46MkNME7fElMJUaVVSruMXj9VI=", - "dev": true, - "optional": true, - "requires": { - "figures": "1.7.0", - "squeak": "1.3.0" - } - }, - "longest": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", - "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", - "dev": true - }, - "loud-rejection": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", - "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", - "dev": true, - "requires": { - "currently-unhandled": "0.4.1", - "signal-exit": "3.0.2" - } - }, - "lowercase-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", - "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=", - "dev": true - }, - "lpad-align": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/lpad-align/-/lpad-align-1.1.2.tgz", - "integrity": "sha1-IfYArBwwlcPG5JfuZyce4ISB/p4=", - "dev": true, - "optional": true, - "requires": { - "get-stdin": "4.0.1", - "indent-string": "2.1.0", - "longest": "1.0.1", - "meow": "3.7.0" - } - }, - "lru-cache": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", - "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=", - "dev": true - }, - "macaddress": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/macaddress/-/macaddress-0.2.8.tgz", - "integrity": "sha1-WQTcU3w57G2+/q6QIycTX6hRHxI=", - "dev": true - }, - "make-iterator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.0.tgz", - "integrity": "sha1-V7713IXSOSO6I3ZzJNjo+PPZaUs=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", - "dev": true - }, - "map-stream": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", - "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=" - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "1.0.1" - } - }, - "marked": { - "version": "0.3.12", - "resolved": "https://registry.npmjs.org/marked/-/marked-0.3.12.tgz", - "integrity": "sha512-k4NaW+vS7ytQn6MgJn3fYpQt20/mOgYM5Ft9BYMfQJDz2QT6yEeS9XJ8k2Nw8JTeWK/znPPW2n3UJGzyYEiMoA==", - "dev": true - }, - "marked-terminal": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-2.0.0.tgz", - "integrity": "sha1-Xq9Wi+ZvaGVBr6UqVYKAMQox3i0=", - "dev": true, - "requires": { - "cardinal": "1.0.0", - "chalk": "1.1.3", - "cli-table": "0.3.1", - "lodash.assign": "4.2.0", - "node-emoji": "1.8.1" - } - }, - "math-expression-evaluator": { - "version": "1.2.17", - "resolved": "https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz", - "integrity": "sha1-3oGf282E3M2PrlnGrreWFbnSZqw=", - "dev": true - }, - "md5-hex": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-1.3.0.tgz", - "integrity": "sha1-0sSv6YPENwZiF5uMrRRSGRNQRsQ=", - "dev": true, - "requires": { - "md5-o-matic": "0.1.1" - } - }, - "md5-o-matic": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/md5-o-matic/-/md5-o-matic-0.1.1.tgz", - "integrity": "sha1-givM1l4RfFFPqxdrJZRdVBAKA8M=", - "dev": true - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", - "dev": true - }, - "meow": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", - "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", - "dev": true, - "requires": { - "camelcase-keys": "2.1.0", - "decamelize": "1.2.0", - "loud-rejection": "1.6.0", - "map-obj": "1.0.1", - "minimist": "1.2.0", - "normalize-package-data": "2.4.0", - "object-assign": "4.1.1", - "read-pkg-up": "1.0.1", - "redent": "1.0.0", - "trim-newlines": "1.0.0" - }, - "dependencies": { - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - } - } - }, - "merge-stream": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", - "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=", - "dev": true, - "requires": { - "readable-stream": "2.3.3" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - } - } - }, - "micromatch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.5.tgz", - "integrity": "sha512-ykttrLPQrz1PUJcXjwsTUjGoPJ64StIGNE2lGVD1c9CuguJ+L7/navsE8IcDNndOoCMvYV0qc/exfVbMHkUhvA==", - "dev": true, - "requires": { - "arr-diff": "4.0.0", - "array-unique": "0.3.2", - "braces": "2.3.0", - "define-property": "1.0.0", - "extend-shallow": "2.0.1", - "extglob": "2.0.4", - "fragment-cache": "0.2.1", - "kind-of": "6.0.2", - "nanomatch": "1.2.7", - "object.pick": "1.3.0", - "regex-not": "1.0.0", - "snapdragon": "0.8.1", - "to-regex": "3.0.1" - } - }, - "mime-db": { - "version": "1.30.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz", - "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=", - "dev": true - }, - "mime-types": { - "version": "2.1.17", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz", - "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=", - "dev": true, - "requires": { - "mime-db": "1.30.0" - } - }, - "mini-lr": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/mini-lr/-/mini-lr-0.1.9.tgz", - "integrity": "sha1-AhmdJzR5U9H9HW297UJh8Yey0PY=", - "dev": true, - "requires": { - "body-parser": "1.14.2", - "debug": "2.6.9", - "faye-websocket": "0.7.3", - "livereload-js": "2.3.0", - "parseurl": "1.3.2", - "qs": "2.2.5" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "1.1.8" - } - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" - }, - "mixin-deep": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.0.tgz", - "integrity": "sha512-dgaCvoh6i1nosAUBKb0l0pfJ78K8+S9fluyIR2YvAeUD/QuMahnFnF3xYty5eYXMjhGSsB0DsW6A0uAZyetoAg==", - "dev": true, - "requires": { - "for-in": "1.0.2", - "is-extendable": "1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "multipipe": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz", - "integrity": "sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s=", - "requires": { - "duplexer2": "0.0.2" - } - }, - "nanomatch": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.7.tgz", - "integrity": "sha512-/5ldsnyurvEw7wNpxLFgjVvBLMta43niEYOy0CJ4ntcYSbx6bugRUTQeFb4BR/WanEL1o3aQgHuVLHQaB6tOqg==", - "dev": true, - "requires": { - "arr-diff": "4.0.0", - "array-unique": "0.3.2", - "define-property": "1.0.0", - "extend-shallow": "2.0.1", - "fragment-cache": "0.2.1", - "is-odd": "1.0.0", - "kind-of": "5.1.0", - "object.pick": "1.3.0", - "regex-not": "1.0.0", - "snapdragon": "0.8.1", - "to-regex": "3.0.1" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "natives": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/natives/-/natives-1.1.1.tgz", - "integrity": "sha512-8eRaxn8u/4wN8tGkhlc2cgwwvOLMLUMUn4IYTexMgWd+LyUDfeXVkk2ygQR0hvIHbJQXgHujia3ieUUDwNGkEA==", - "dev": true - }, - "node-emoji": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.8.1.tgz", - "integrity": "sha512-+ktMAh1Jwas+TnGodfCfjUbJKoANqPaJFN0z0iqh41eqD8dvguNzcitVSBSVK1pidz0AqGbLKcoVuVLRVZ/aVg==", - "dev": true, - "requires": { - "lodash.toarray": "4.4.0" - } - }, - "node-notifier": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-4.6.1.tgz", - "integrity": "sha1-BW0UJE89zBzq3+aK+c/wxUc6M/M=", - "dev": true, - "requires": { - "cli-usage": "0.1.7", - "growly": "1.3.0", - "lodash.clonedeep": "3.0.2", - "minimist": "1.2.0", - "semver": "5.5.0", - "shellwords": "0.1.1", - "which": "1.3.0" - }, - "dependencies": { - "lodash.clonedeep": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-3.0.2.tgz", - "integrity": "sha1-oKHkDYKl6on/WxR7hETtY9koJ9s=", - "dev": true, - "requires": { - "lodash._baseclone": "3.3.0", - "lodash._bindcallback": "3.0.1" - } - }, - "semver": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", - "dev": true - } - } - }, - "node-status-codes": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-status-codes/-/node-status-codes-1.0.0.tgz", - "integrity": "sha1-WuVUHQJGRdMqWPzdyc7s6nrjrC8=", - "dev": true - }, - "node.extend": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/node.extend/-/node.extend-1.1.6.tgz", - "integrity": "sha1-p7iCyC1sk6SGOlUEvV3o7IYli5Y=", - "dev": true, - "requires": { - "is": "3.2.1" - } - }, - "normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", - "dev": true, - "requires": { - "hosted-git-info": "2.5.0", - "is-builtin-module": "1.0.0", - "semver": "4.3.6", - "validate-npm-package-license": "3.0.1" - } - }, - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "1.1.0" - } - }, - "normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", - "dev": true - }, - "normalize-url": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", - "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", - "dev": true, - "requires": { - "object-assign": "4.1.1", - "prepend-http": "1.0.4", - "query-string": "4.3.4", - "sort-keys": "1.1.2" - }, - "dependencies": { - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - } - } - }, - "nth-check": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz", - "integrity": "sha1-mSms32KPwsQQmN6rgqxYDPFJquQ=", - "requires": { - "boolbase": "1.0.0" - } - }, - "num2fraction": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", - "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=", - "dev": true - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, - "object-assign": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", - "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=" - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "0.1.1", - "define-property": "0.2.5", - "kind-of": "3.2.2" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "0.1.6" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "object-keys": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", - "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "3.0.1" - } - }, - "object.defaults": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", - "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", - "dev": true, - "requires": { - "array-each": "1.0.1", - "array-slice": "1.1.0", - "for-own": "1.0.0", - "isobject": "3.0.1" - } - }, - "object.map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", - "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", - "dev": true, - "requires": { - "for-own": "1.0.0", - "make-iterator": "1.0.0" - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "0.1.5", - "is-extendable": "0.1.1" - }, - "dependencies": { - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "1.0.2" - } - } - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "3.0.1" - } - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dev": true, - "requires": { - "ee-first": "1.1.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1.0.2" - } - }, - "onetime": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", - "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", - "dev": true - }, - "optional": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/optional/-/optional-0.1.4.tgz", - "integrity": "sha512-gtvrrCfkE08wKcgXaVwQVgwEQ8vel2dc5DDBn9RLQZ3YtmtkBss6A2HY6BnJH4N/4Ku97Ri/SF8sNWE2225WJw==", - "dev": true - }, - "optipng-bin": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/optipng-bin/-/optipng-bin-3.1.4.tgz", - "integrity": "sha1-ldNPLEiHBPb9cGBr/qDGWfHZXYQ=", - "dev": true, - "optional": true, - "requires": { - "bin-build": "2.2.0", - "bin-wrapper": "3.0.2", - "logalot": "2.1.0" - } - }, - "orchestrator": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/orchestrator/-/orchestrator-0.3.8.tgz", - "integrity": "sha1-FOfp4nZPcxX7rBhOUGx6pt+UrX4=", - "dev": true, - "requires": { - "end-of-stream": "0.1.5", - "sequencify": "0.0.7", - "stream-consume": "0.1.0" - } - }, - "ordered-read-streams": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.1.0.tgz", - "integrity": "sha1-/VZamvjrRHO6abbtijQ1LLVS8SY=", - "dev": true - }, - "os-filter-obj": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/os-filter-obj/-/os-filter-obj-1.0.3.tgz", - "integrity": "sha1-WRUzDZDs7VV9LZOKMcbdIU2cY60=", - "dev": true, - "optional": true - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, - "parse-filepath": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", - "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", - "dev": true, - "requires": { - "is-absolute": "1.0.0", - "map-cache": "0.2.2", - "path-root": "0.1.1" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "0.3.0", - "is-dotfile": "1.0.3", - "is-extglob": "1.0.0", - "is-glob": "2.0.1" - }, - "dependencies": { - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "1.0.0" - } - } - } - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "1.3.1" - } - }, - "parse-passwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", - "dev": true - }, - "parseurl": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", - "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=", - "dev": true - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "2.0.1" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-parse": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", - "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", - "dev": true - }, - "path-root": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", - "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", - "dev": true, - "requires": { - "path-root-regex": "0.1.2" - } - }, - "path-root-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", - "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", - "dev": true - }, - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" - }, - "dependencies": { - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - } - } - }, - "pause-stream": { - "version": "0.0.11", - "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", - "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", - "requires": { - "through": "2.3.8" - } - }, - "pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", - "dev": true - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "2.0.4" - } - }, - "plugin-error": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-0.1.2.tgz", - "integrity": "sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4=", - "dev": true, - "requires": { - "ansi-cyan": "0.1.1", - "ansi-red": "0.1.1", - "arr-diff": "1.1.0", - "arr-union": "2.1.0", - "extend-shallow": "1.1.4" - }, - "dependencies": { - "arr-diff": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-1.1.0.tgz", - "integrity": "sha1-aHwydYFjWI/vfeezb6vklesaOZo=", - "dev": true, - "requires": { - "arr-flatten": "1.1.0", - "array-slice": "0.2.3" - } - }, - "arr-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-2.1.0.tgz", - "integrity": "sha1-IPnqtexw9cfSFbEHexw5Fh0pLH0=", - "dev": true - }, - "array-slice": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz", - "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=", - "dev": true - }, - "extend-shallow": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-1.1.4.tgz", - "integrity": "sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE=", - "dev": true, - "requires": { - "kind-of": "1.1.0" - } - }, - "kind-of": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz", - "integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=", - "dev": true - } - } - }, - "plur": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/plur/-/plur-2.1.2.tgz", - "integrity": "sha1-dIJFLBoPUI4+NE6uwxLJHCncZVo=", - "dev": true, - "requires": { - "irregular-plurals": "1.4.0" - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "postcss": { - "version": "5.2.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", - "dev": true, - "requires": { - "chalk": "1.1.3", - "js-base64": "2.4.1", - "source-map": "0.5.7", - "supports-color": "3.2.3" - }, - "dependencies": { - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "1.0.0" - } - } - } - }, - "postcss-calc": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-5.3.1.tgz", - "integrity": "sha1-d7rnypKK2FcW4v2kLyYb98HWW14=", - "dev": true, - "requires": { - "postcss": "5.2.18", - "postcss-message-helpers": "2.0.0", - "reduce-css-calc": "1.3.0" - } - }, - "postcss-colormin": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-2.2.2.tgz", - "integrity": "sha1-ZjFBfV8OkJo9fsJrJMio0eT5bks=", - "dev": true, - "requires": { - "colormin": "1.1.2", - "postcss": "5.2.18", - "postcss-value-parser": "3.3.0" - } - }, - "postcss-convert-values": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-2.6.1.tgz", - "integrity": "sha1-u9hZPFwf0uPRwyK7kl3K6Nrk1i0=", - "dev": true, - "requires": { - "postcss": "5.2.18", - "postcss-value-parser": "3.3.0" - } - }, - "postcss-discard-comments": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz", - "integrity": "sha1-vv6J+v1bPazlzM5Rt2uBUUvgDj0=", - "dev": true, - "requires": { - "postcss": "5.2.18" - } - }, - "postcss-discard-duplicates": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-2.1.0.tgz", - "integrity": "sha1-uavye4isGIFYpesSq8riAmO5GTI=", - "dev": true, - "requires": { - "postcss": "5.2.18" - } - }, - "postcss-discard-empty": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz", - "integrity": "sha1-0rS9nVztXr2Nyt52QMfXzX9PkrU=", - "dev": true, - "requires": { - "postcss": "5.2.18" - } - }, - "postcss-discard-overridden": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz", - "integrity": "sha1-ix6vVU9ob7KIzYdMVWZ7CqNmjVg=", - "dev": true, - "requires": { - "postcss": "5.2.18" - } - }, - "postcss-discard-unused": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz", - "integrity": "sha1-vOMLLMWR/8Y0Mitfs0ZLbZNPRDM=", - "dev": true, - "requires": { - "postcss": "5.2.18", - "uniqs": "2.0.0" - } - }, - "postcss-filter-plugins": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/postcss-filter-plugins/-/postcss-filter-plugins-2.0.2.tgz", - "integrity": "sha1-bYWGJTTXNaxCDkqFgG4fXUKG2Ew=", - "dev": true, - "requires": { - "postcss": "5.2.18", - "uniqid": "4.1.1" - } - }, - "postcss-merge-idents": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz", - "integrity": "sha1-TFUwMTwI4dWzu/PSu8dH4njuonA=", - "dev": true, - "requires": { - "has": "1.0.1", - "postcss": "5.2.18", - "postcss-value-parser": "3.3.0" - } - }, - "postcss-merge-longhand": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-2.0.2.tgz", - "integrity": "sha1-I9kM0Sewp3mUkVMyc5A0oaTz1lg=", - "dev": true, - "requires": { - "postcss": "5.2.18" - } - }, - "postcss-merge-rules": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-2.1.2.tgz", - "integrity": "sha1-0d9d+qexrMO+VT8OnhDofGG19yE=", - "dev": true, - "requires": { - "browserslist": "1.7.7", - "caniuse-api": "1.6.1", - "postcss": "5.2.18", - "postcss-selector-parser": "2.2.3", - "vendors": "1.0.1" - } - }, - "postcss-message-helpers": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-message-helpers/-/postcss-message-helpers-2.0.0.tgz", - "integrity": "sha1-pPL0+rbk/gAvCu0ABHjN9S+bpg4=", - "dev": true - }, - "postcss-minify-font-values": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz", - "integrity": "sha1-S1jttWZB66fIR0qzUmyv17vey2k=", - "dev": true, - "requires": { - "object-assign": "4.1.1", - "postcss": "5.2.18", - "postcss-value-parser": "3.3.0" - }, - "dependencies": { - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - } - } - }, - "postcss-minify-gradients": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz", - "integrity": "sha1-Xb2hE3NwP4PPtKPqOIHY11/15uE=", - "dev": true, - "requires": { - "postcss": "5.2.18", - "postcss-value-parser": "3.3.0" - } - }, - "postcss-minify-params": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz", - "integrity": "sha1-rSzgcTc7lDs9kwo/pZo1jCjW8fM=", - "dev": true, - "requires": { - "alphanum-sort": "1.0.2", - "postcss": "5.2.18", - "postcss-value-parser": "3.3.0", - "uniqs": "2.0.0" - } - }, - "postcss-minify-selectors": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz", - "integrity": "sha1-ssapjAByz5G5MtGkllCBFDEXNb8=", - "dev": true, - "requires": { - "alphanum-sort": "1.0.2", - "has": "1.0.1", - "postcss": "5.2.18", - "postcss-selector-parser": "2.2.3" - } - }, - "postcss-normalize-charset": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz", - "integrity": "sha1-757nEhLX/nWceO0WL2HtYrXLk/E=", - "dev": true, - "requires": { - "postcss": "5.2.18" - } - }, - "postcss-normalize-url": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz", - "integrity": "sha1-EI90s/L82viRov+j6kWSJ5/HgiI=", - "dev": true, - "requires": { - "is-absolute-url": "2.1.0", - "normalize-url": "1.9.1", - "postcss": "5.2.18", - "postcss-value-parser": "3.3.0" - } - }, - "postcss-ordered-values": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-2.2.3.tgz", - "integrity": "sha1-7sbCpntsQSqNsgQud/6NpD+VwR0=", - "dev": true, - "requires": { - "postcss": "5.2.18", - "postcss-value-parser": "3.3.0" - } - }, - "postcss-reduce-idents": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz", - "integrity": "sha1-wsbSDMlYKE9qv75j92Cb9AkFmtM=", - "dev": true, - "requires": { - "postcss": "5.2.18", - "postcss-value-parser": "3.3.0" - } - }, - "postcss-reduce-initial": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz", - "integrity": "sha1-aPgGlfBF0IJjqHmtJA343WT2ROo=", - "dev": true, - "requires": { - "postcss": "5.2.18" - } - }, - "postcss-reduce-transforms": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz", - "integrity": "sha1-/3b02CEkN7McKYpC0uFEQCV3GuE=", - "dev": true, - "requires": { - "has": "1.0.1", - "postcss": "5.2.18", - "postcss-value-parser": "3.3.0" - } - }, - "postcss-selector-parser": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz", - "integrity": "sha1-+UN3iGBsPJrO4W/+jYsWKX8nu5A=", - "dev": true, - "requires": { - "flatten": "1.0.2", - "indexes-of": "1.0.1", - "uniq": "1.0.1" - } - }, - "postcss-svgo": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-2.1.6.tgz", - "integrity": "sha1-tt8YqmE7Zm4TPwittSGcJoSsEI0=", - "dev": true, - "requires": { - "is-svg": "2.1.0", - "postcss": "5.2.18", - "postcss-value-parser": "3.3.0", - "svgo": "0.7.2" - } - }, - "postcss-unique-selectors": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz", - "integrity": "sha1-mB1X0p3csz57Hf4f1DuGSfkzyh0=", - "dev": true, - "requires": { - "alphanum-sort": "1.0.2", - "postcss": "5.2.18", - "uniqs": "2.0.0" - } - }, - "postcss-value-parser": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz", - "integrity": "sha1-h/OPnxj3dKSrTIojL1xc6IcqnRU=", - "dev": true - }, - "postcss-zindex": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-2.2.0.tgz", - "integrity": "sha1-0hCd3AVbka9n/EyzsCWUZjnSryI=", - "dev": true, - "requires": { - "has": "1.0.1", - "postcss": "5.2.18", - "uniqs": "2.0.0" - } - }, - "prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "pretty-bytes": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-2.0.1.tgz", - "integrity": "sha1-FV7E0ANvQTkecEXW2+SWPVJdJk8=", - "dev": true, - "requires": { - "get-stdin": "4.0.1", - "meow": "3.7.0", - "number-is-nan": "1.0.1" - } - }, - "pretty-hrtime": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", - "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=", - "dev": true - }, - "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", - "dev": true - }, - "qs": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/qs/-/qs-2.2.5.tgz", - "integrity": "sha1-EIirr53MCuWuRbcJ5sa1iIsjkjw=", - "dev": true - }, - "query-string": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", - "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", - "dev": true, - "requires": { - "object-assign": "4.1.1", - "strict-uri-encode": "1.1.0" - }, - "dependencies": { - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - } - } - }, - "randomatic": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", - "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", - "dev": true, - "requires": { - "is-number": "3.0.0", - "kind-of": "4.0.0" - }, - "dependencies": { - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "raw-body": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.1.7.tgz", - "integrity": "sha1-rf6s4uT7MJgFgBTQjActzFl1h3Q=", - "dev": true, - "requires": { - "bytes": "2.4.0", - "iconv-lite": "0.4.13", - "unpipe": "1.0.0" - }, - "dependencies": { - "bytes": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz", - "integrity": "sha1-fZcZb51br39pNeJZhVSe3SpsIzk=", - "dev": true - } - } - }, - "rc": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.4.tgz", - "integrity": "sha1-oPYGyq4qO4YrvQ74VILAElsxX6M=", - "dev": true, - "requires": { - "deep-extend": "0.4.2", - "ini": "1.3.5", - "minimist": "1.2.0", - "strip-json-comments": "2.0.1" - } - }, - "rcfinder": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/rcfinder/-/rcfinder-0.1.9.tgz", - "integrity": "sha1-8+gPOH3fmugK4wpBADKWQuroERU=", - "dev": true, - "requires": { - "lodash.clonedeep": "4.5.0" - } - }, - "rcloader": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/rcloader/-/rcloader-0.2.2.tgz", - "integrity": "sha1-WNIpi0YtC5v9ITPSoex0+9cFxxc=", - "dev": true, - "requires": { - "lodash.assign": "4.2.0", - "lodash.isobject": "3.0.2", - "lodash.merge": "4.6.0", - "rcfinder": "0.1.9" - }, - "dependencies": { - "lodash.isobject": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-3.0.2.tgz", - "integrity": "sha1-PI+41bW/S/kK4G4U8qUwpO2TXh0=", - "dev": true - } - } - }, - "read-all-stream": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/read-all-stream/-/read-all-stream-3.1.0.tgz", - "integrity": "sha1-NcPhd/IHjveJ7kv6+kNzB06u9Po=", - "dev": true, - "requires": { - "pinkie-promise": "2.0.1", - "readable-stream": "2.3.3" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - } - } - }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "dev": true, - "requires": { - "load-json-file": "1.1.0", - "normalize-package-data": "2.4.0", - "path-type": "1.1.0" - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "dev": true, - "requires": { - "find-up": "1.1.2", - "read-pkg": "1.1.0" - } - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "dev": true, - "requires": { - "resolve": "1.5.0" - } - }, - "redent": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", - "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", - "dev": true, - "requires": { - "indent-string": "2.1.0", - "strip-indent": "1.0.1" - } - }, - "redeyed": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-1.0.1.tgz", - "integrity": "sha1-6WwZO0DAgWsArshCaY5hGF5VSYo=", - "dev": true, - "requires": { - "esprima": "3.0.0" - }, - "dependencies": { - "esprima": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.0.0.tgz", - "integrity": "sha1-U88kes2ncxPlUcOqLnM0LT+099k=", - "dev": true - } - } - }, - "reduce-css-calc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz", - "integrity": "sha1-dHyRTgSWFKTJz7umKYca0dKSdxY=", - "dev": true, - "requires": { - "balanced-match": "0.4.2", - "math-expression-evaluator": "1.2.17", - "reduce-function-call": "1.0.2" - }, - "dependencies": { - "balanced-match": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", - "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", - "dev": true - } - } - }, - "reduce-function-call": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/reduce-function-call/-/reduce-function-call-1.0.2.tgz", - "integrity": "sha1-WiAL+S4ON3UXUv5FsKszD9S2vpk=", - "dev": true, - "requires": { - "balanced-match": "0.4.2" - }, - "dependencies": { - "balanced-match": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", - "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", - "dev": true - } - } - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "requires": { - "is-equal-shallow": "0.1.3" - } - }, - "regex-not": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.0.tgz", - "integrity": "sha1-Qvg+OXcWIt+CawKvF2Ul1qXxV/k=", - "dev": true, - "requires": { - "extend-shallow": "2.0.1" - } - }, - "remove-markdown": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/remove-markdown/-/remove-markdown-0.1.0.tgz", - "integrity": "sha1-z4tm6eb8tKzJchBIre7no1dpi6k=", - "dev": true - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", - "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "dev": true, - "requires": { - "is-finite": "1.0.2" - } - }, - "replace-ext": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", - "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=" - }, - "replacestream": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/replacestream/-/replacestream-4.0.3.tgz", - "integrity": "sha512-AC0FiLS352pBBiZhd4VXB1Ab/lh0lEgpP+GGvZqbQh8a5cmXVoTe5EX/YeTFArnp4SRGTHh1qCHu9lGs1qG8sA==", - "dev": true, - "requires": { - "escape-string-regexp": "1.0.5", - "object-assign": "4.1.1", - "readable-stream": "2.3.3" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - } - } - }, - "require-dir": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/require-dir/-/require-dir-0.3.2.tgz", - "integrity": "sha1-wdXHXp+//eny5rM+OD209ZS1pqk=", - "dev": true - }, - "resolve": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", - "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==", - "dev": true, - "requires": { - "path-parse": "1.0.5" - } - }, - "resolve-dir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", - "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", - "dev": true, - "requires": { - "expand-tilde": "2.0.2", - "global-modules": "1.0.0" - } - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "right-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", - "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", - "dev": true, - "requires": { - "align-text": "0.1.4" - } - }, - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", - "dev": true, - "requires": { - "glob": "7.1.2" - } - }, - "run-sequence": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/run-sequence/-/run-sequence-1.2.2.tgz", - "integrity": "sha1-UJWgvr6YczsBQL0I3YDsAw3azes=", - "dev": true, - "requires": { - "chalk": "1.1.3", - "gulp-util": "3.0.8" - } - }, - "safe-buffer": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" - }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true - }, - "seek-bzip": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.5.tgz", - "integrity": "sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w=", - "dev": true, - "requires": { - "commander": "2.8.1" - } - }, - "semver": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz", - "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=", - "dev": true - }, - "semver-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-1.0.0.tgz", - "integrity": "sha1-kqSWkGX5xwxpR1PVUkj8aPj2Usk=", - "dev": true, - "optional": true - }, - "semver-truncate": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/semver-truncate/-/semver-truncate-1.1.2.tgz", - "integrity": "sha1-V/Qd5pcHpicJp+AQS6IRcQnqR+g=", - "dev": true, - "optional": true, - "requires": { - "semver": "5.5.0" - }, - "dependencies": { - "semver": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", - "dev": true, - "optional": true - } - } - }, - "sequencify": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/sequencify/-/sequencify-0.0.7.tgz", - "integrity": "sha1-kM/xnQLgcCf9dn9erT57ldHnOAw=", - "dev": true - }, - "set-getter": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/set-getter/-/set-getter-0.1.0.tgz", - "integrity": "sha1-12nBgsnVpR9AkUXy+6guXoboA3Y=", - "dev": true, - "requires": { - "to-object-path": "0.3.0" - } - }, - "set-immediate-shim": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", - "dev": true - }, - "set-value": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", - "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", - "dev": true, - "requires": { - "extend-shallow": "2.0.1", - "is-extendable": "0.1.1", - "is-plain-object": "2.0.4", - "split-string": "3.1.0" - } - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "shelljs": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", - "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=", - "dev": true - }, - "shellwords": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", - "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", - "dev": true - }, - "sigmund": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", - "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", - "dev": true - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true - }, - "snapdragon": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.1.tgz", - "integrity": "sha1-4StUh/re0+PeoKyR6UAL91tAE3A=", - "dev": true, - "requires": { - "base": "0.11.2", - "debug": "2.6.9", - "define-property": "0.2.5", - "extend-shallow": "2.0.1", - "map-cache": "0.2.2", - "source-map": "0.5.7", - "source-map-resolve": "0.5.1", - "use": "2.0.2" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "0.1.6" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "1.0.0", - "isobject": "3.0.1", - "snapdragon-util": "3.0.1" - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "sort-keys": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", - "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", - "dev": true, - "requires": { - "is-plain-obj": "1.1.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.1.tgz", - "integrity": "sha512-0KW2wvzfxm8NCTb30z0LMNyPqWCdDGE2viwzUaucqJdkTRXtZiSY3I+2A6nVAjmdOy0I4gU8DwnVVGsk9jvP2A==", - "dev": true, - "requires": { - "atob": "2.0.3", - "decode-uri-component": "0.2.0", - "resolve-url": "0.2.1", - "source-map-url": "0.4.0", - "urix": "0.1.0" - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "sparkles": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.0.tgz", - "integrity": "sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM=" - }, - "spdx-correct": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", - "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", - "dev": true, - "requires": { - "spdx-license-ids": "1.2.2" - } - }, - "spdx-expression-parse": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", - "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=", - "dev": true - }, - "spdx-license-ids": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", - "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", - "dev": true - }, - "split": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", - "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", - "requires": { - "through": "2.3.8" - } - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "3.0.2" - }, - "dependencies": { - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "1.0.0", - "is-extendable": "1.0.1" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "2.0.4" - } - } - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "squeak": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/squeak/-/squeak-1.3.0.tgz", - "integrity": "sha1-MwRQN7ZDiLVnZ0uEMiplIQc5FsM=", - "dev": true, - "optional": true, - "requires": { - "chalk": "1.1.3", - "console-stream": "0.1.1", - "lpad-align": "1.1.2" - } - }, - "stat-mode": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-0.2.2.tgz", - "integrity": "sha1-5sgLYjEj19gM8TLOU480YokHJQI=", - "dev": true - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "0.2.5", - "object-copy": "0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "0.1.6" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "statuses": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", - "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", - "dev": true - }, - "stream-combiner": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", - "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", - "requires": { - "duplexer": "0.1.1" - } - }, - "stream-combiner2": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", - "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=", - "dev": true, - "requires": { - "duplexer2": "0.1.4", - "readable-stream": "2.3.3" - }, - "dependencies": { - "duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", - "dev": true, - "requires": { - "readable-stream": "2.3.3" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - } - } - }, - "stream-consume": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/stream-consume/-/stream-consume-0.1.0.tgz", - "integrity": "sha1-pB6tGm1ggc63n2WwYZAbbY89HQ8=", - "dev": true - }, - "stream-shift": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", - "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", - "dev": true - }, - "streamqueue": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/streamqueue/-/streamqueue-1.1.2.tgz", - "integrity": "sha512-CHUpqa+1BM99z7clQz9W6L9ZW4eXRRQCR0H+utVAGGvNo2ePlJAFjhdK0IjunaBbY/gWKJawk5kpJeyz0EXxRA==", - "dev": true, - "requires": { - "isstream": "0.1.2", - "readable-stream": "2.3.3" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - } - } - }, - "strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", - "dev": true - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "2.1.1" - } - }, - "strip-bom": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-1.0.0.tgz", - "integrity": "sha1-hbiGLzhEtabV7IRnqTWYFzo295Q=", - "dev": true, - "requires": { - "first-chunk-stream": "1.0.0", - "is-utf8": "0.2.1" - } - }, - "strip-bom-buf": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-buf/-/strip-bom-buf-1.0.0.tgz", - "integrity": "sha1-HLRar1dTD0yvhsf3UXnSyaUd1XI=", - "dev": true, - "requires": { - "is-utf8": "0.2.1" - } - }, - "strip-bom-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-stream/-/strip-bom-stream-3.0.0.tgz", - "integrity": "sha1-lWvMXYRDD2klapDtgjdlzYWOFZw=", - "dev": true, - "requires": { - "first-chunk-stream": "2.0.0", - "strip-bom-buf": "1.0.0" - }, - "dependencies": { - "first-chunk-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-2.0.0.tgz", - "integrity": "sha1-G97NuOCDwGZLkZRVgVd6Q6nzHXA=", - "dev": true, - "requires": { - "readable-stream": "2.3.3" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - } - } - }, - "strip-dirs": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-1.1.1.tgz", - "integrity": "sha1-lgu9EoeETzl1pFWKoQOoJV4kVqA=", - "dev": true, - "requires": { - "chalk": "1.1.3", - "get-stdin": "4.0.1", - "is-absolute": "0.1.7", - "is-natural-number": "2.1.1", - "minimist": "1.2.0", - "sum-up": "1.0.3" - }, - "dependencies": { - "is-absolute": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-0.1.7.tgz", - "integrity": "sha1-hHSREZ/MtftDYhfMc39/qtUPYD8=", - "dev": true, - "requires": { - "is-relative": "0.1.3" - } - }, - "is-relative": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-0.1.3.tgz", - "integrity": "sha1-kF/uiuhvRbPsYUvDwVyGnfCHboI=", - "dev": true - } - } - }, - "strip-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", - "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", - "dev": true, - "requires": { - "get-stdin": "4.0.1" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "strip-outer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.0.tgz", - "integrity": "sha1-qsC6YNLpDF1PJ1/Yhp/ZotMQ/7g=", - "dev": true, - "requires": { - "escape-string-regexp": "1.0.5" - } - }, - "sum-up": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sum-up/-/sum-up-1.0.3.tgz", - "integrity": "sha1-HGYfZnBX9jvLeHWqFDi8FiUlFW4=", - "dev": true, - "requires": { - "chalk": "1.1.3" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" - }, - "svgo": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-0.7.2.tgz", - "integrity": "sha1-n1dyQTlSE1xv779Ar+ak+qiLS7U=", - "dev": true, - "requires": { - "coa": "1.0.4", - "colors": "1.1.2", - "csso": "2.3.2", - "js-yaml": "3.7.0", - "mkdirp": "0.5.1", - "sax": "1.2.4", - "whet.extend": "0.9.9" - } - }, - "tar-stream": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.5.tgz", - "integrity": "sha512-mQdgLPc/Vjfr3VWqWbfxW8yQNiJCbAZ+Gf6GDu1Cy0bdb33ofyiNGBtAY96jHFhDuivCwgW1H9DgTON+INiXgg==", - "dev": true, - "requires": { - "bl": "1.2.1", - "end-of-stream": "1.4.1", - "readable-stream": "2.3.3", - "xtend": "4.0.1" - }, - "dependencies": { - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "dev": true, - "requires": { - "once": "1.4.0" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - } - } - }, - "tempfile": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/tempfile/-/tempfile-1.1.1.tgz", - "integrity": "sha1-W8xOrsxKsscH2LwR2ZzMmiyyh/I=", - "dev": true, - "requires": { - "os-tmpdir": "1.0.2", - "uuid": "2.0.3" - } - }, - "textextensions": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/textextensions/-/textextensions-1.0.2.tgz", - "integrity": "sha1-ZUhjk+4fK7A5pgy7oFsLaL2VAdI=", - "dev": true - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "through2": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", - "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", - "requires": { - "readable-stream": "2.3.3", - "xtend": "4.0.1" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "requires": { - "safe-buffer": "5.1.1" - } - } - } - }, - "through2-concurrent": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/through2-concurrent/-/through2-concurrent-1.1.1.tgz", - "integrity": "sha1-EctOpMnjG8puTB5tukjRxyjDUks=", - "dev": true, - "requires": { - "through2": "2.0.3" - } - }, - "through2-filter": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-2.0.0.tgz", - "integrity": "sha1-YLxVoNrLdghdsfna6Zq0P4PWIuw=", - "dev": true, - "requires": { - "through2": "2.0.3", - "xtend": "4.0.1" - } - }, - "tildify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/tildify/-/tildify-1.2.0.tgz", - "integrity": "sha1-3OwD9V3Km3qj5bBPIYF+tW5jWIo=", - "dev": true, - "requires": { - "os-homedir": "1.0.2" - } - }, - "time-stamp": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", - "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=" - }, - "timed-out": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-3.1.3.tgz", - "integrity": "sha1-lYYL/MXHbCd/j4Mm/Q9bLiDrohc=", - "dev": true - }, - "to-absolute-glob": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-0.1.1.tgz", - "integrity": "sha1-HN+kcqnvUMI57maZm2YsoOs5k38=", - "dev": true, - "requires": { - "extend-shallow": "2.0.1" - } - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "to-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.1.tgz", - "integrity": "sha1-FTWL7kosg712N3uh3ASdDxiDeq4=", - "dev": true, - "requires": { - "define-property": "0.2.5", - "extend-shallow": "2.0.1", - "regex-not": "1.0.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "0.1.6" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "3.0.0", - "repeat-string": "1.6.1" - } - }, - "trim-newlines": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", - "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", - "dev": true - }, - "trim-repeated": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", - "integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=", - "dev": true, - "requires": { - "escape-string-regexp": "1.0.5" - } - }, - "try-json-parse": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/try-json-parse/-/try-json-parse-0.1.1.tgz", - "integrity": "sha1-jbAWIuh35RuDFAyu58gIZK05DII=", - "dev": true - }, - "tunnel-agent": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", - "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=", - "dev": true - }, - "type-is": { - "version": "1.6.15", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz", - "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=", - "dev": true, - "requires": { - "media-typer": "0.3.0", - "mime-types": "2.1.17" - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "uglify-js": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.6.4.tgz", - "integrity": "sha1-ZeovswWck5RpLxX+2HwrNsFrmt8=", - "dev": true, - "requires": { - "async": "0.2.10", - "source-map": "0.5.7", - "uglify-to-browserify": "1.0.2", - "yargs": "3.10.0" - } - }, - "uglify-save-license": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/uglify-save-license/-/uglify-save-license-0.4.1.tgz", - "integrity": "sha1-lXJsF8xv0XHDYX479NjYKqjEzOE=", - "dev": true - }, - "uglify-to-browserify": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", - "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", - "dev": true - }, - "unc-path-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", - "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", - "dev": true - }, - "union-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", - "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", - "dev": true, - "requires": { - "arr-union": "3.1.0", - "get-value": "2.0.6", - "is-extendable": "0.1.1", - "set-value": "0.4.3" - }, - "dependencies": { - "set-value": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", - "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", - "dev": true, - "requires": { - "extend-shallow": "2.0.1", - "is-extendable": "0.1.1", - "is-plain-object": "2.0.4", - "to-object-path": "0.3.0" - } - } - } - }, - "uniq": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", - "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", - "dev": true - }, - "uniqid": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/uniqid/-/uniqid-4.1.1.tgz", - "integrity": "sha1-iSIN32t1GuUrX3JISGNShZa7hME=", - "dev": true, - "requires": { - "macaddress": "0.2.8" - } - }, - "uniqs": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", - "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=", - "dev": true - }, - "unique-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-1.0.0.tgz", - "integrity": "sha1-1ZpKdUJ0R9mqbJHnAmP40mpLEEs=", - "dev": true - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "dev": true - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "0.3.1", - "isobject": "3.0.1" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "2.0.6", - "has-values": "0.1.4", - "isobject": "2.1.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - } - } - }, - "unzip-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-1.0.2.tgz", - "integrity": "sha1-uYTwh3/AqJwsdzzB73tbIytbBv4=", - "dev": true - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url-parse-lax": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", - "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", - "dev": true, - "requires": { - "prepend-http": "1.0.4" - } - }, - "url-regex": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/url-regex/-/url-regex-3.2.0.tgz", - "integrity": "sha1-260eDJ4p4QXdCx8J9oYvf9tIJyQ=", - "dev": true, - "optional": true, - "requires": { - "ip-regex": "1.0.3" - } - }, - "use": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/use/-/use-2.0.2.tgz", - "integrity": "sha1-riig1y+TvyJCKhii43mZMRLeyOg=", - "dev": true, - "requires": { - "define-property": "0.2.5", - "isobject": "3.0.1", - "lazy-cache": "2.0.2" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "0.1.6" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "user-home": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", - "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=", - "dev": true - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "uuid": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", - "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=", - "dev": true - }, - "v8flags": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz", - "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=", - "dev": true, - "requires": { - "user-home": "1.1.1" - } - }, - "vali-date": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/vali-date/-/vali-date-1.0.0.tgz", - "integrity": "sha1-G5BKWWCfsyjvB4E4Qgk09rhnCaY=", - "dev": true - }, - "validate-npm-package-license": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", - "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", - "dev": true, - "requires": { - "spdx-correct": "1.0.2", - "spdx-expression-parse": "1.0.4" - } - }, - "vendors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.1.tgz", - "integrity": "sha1-N61zyO5Bf7PVgOeFMSMH0nSEfyI=", - "dev": true - }, - "vinyl": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz", - "integrity": "sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4=", - "requires": { - "clone": "1.0.3", - "clone-stats": "0.0.1", - "replace-ext": "0.0.1" - } - }, - "vinyl-assign": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/vinyl-assign/-/vinyl-assign-1.2.1.tgz", - "integrity": "sha1-TRmIkbVRWRHXcajNnFSApGoHSkU=", - "dev": true, - "requires": { - "object-assign": "4.1.1", - "readable-stream": "2.3.3" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - } - } - }, - "vinyl-bufferstream": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/vinyl-bufferstream/-/vinyl-bufferstream-1.0.1.tgz", - "integrity": "sha1-BTeGn1gO/6TKRay0dXnkuf5jCBo=", - "dev": true, - "requires": { - "bufferstreams": "1.0.1" - } - }, - "vinyl-fs": { - "version": "0.3.14", - "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-0.3.14.tgz", - "integrity": "sha1-mmhRzhysHBzqX+hsCTHWIMLPqeY=", - "dev": true, - "requires": { - "defaults": "1.0.3", - "glob-stream": "3.1.18", - "glob-watcher": "0.0.6", - "graceful-fs": "3.0.11", - "mkdirp": "0.5.1", - "strip-bom": "1.0.0", - "through2": "0.6.5", - "vinyl": "0.4.6" - }, - "dependencies": { - "clone": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz", - "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=", - "dev": true - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" - } - }, - "vinyl": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz", - "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=", - "dev": true, - "requires": { - "clone": "0.2.0", - "clone-stats": "0.0.1" - } - } - } - }, - "vinyl-sourcemaps-apply": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz", - "integrity": "sha1-q2VJ1h0XLCsbh75cUI0jnI74dwU=", - "dev": true, - "requires": { - "source-map": "0.5.7" - } - }, - "ware": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ware/-/ware-1.3.0.tgz", - "integrity": "sha1-0bFPOdLiy0q4xAmPdW/ksWTkc9Q=", - "dev": true, - "requires": { - "wrap-fn": "0.1.5" - } - }, - "websocket-driver": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz", - "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=", - "dev": true, - "requires": { - "http-parser-js": "0.4.9", - "websocket-extensions": "0.1.3" - } - }, - "websocket-extensions": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", - "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==", - "dev": true - }, - "whet.extend": { - "version": "0.9.9", - "resolved": "https://registry.npmjs.org/whet.extend/-/whet.extend-0.9.9.tgz", - "integrity": "sha1-+HfVv2SMl+WqVC+twW1qJZucEaE=", - "dev": true - }, - "which": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", - "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", - "dev": true, - "requires": { - "isexe": "2.0.0" - } - }, - "window-size": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", - "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", - "dev": true - }, - "wordwrap": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", - "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", - "dev": true - }, - "wrap-fn": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/wrap-fn/-/wrap-fn-0.1.5.tgz", - "integrity": "sha1-8htuQQFv9KfjFyDbxjoJAWvfmEU=", - "dev": true, - "requires": { - "co": "3.1.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - }, - "yargs": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", - "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", - "dev": true, - "requires": { - "camelcase": "1.2.1", - "cliui": "2.1.0", - "decamelize": "1.2.0", - "window-size": "0.1.0" - }, - "dependencies": { - "camelcase": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", - "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", - "dev": true - } - } - }, - "yauzl": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.9.1.tgz", - "integrity": "sha1-qBmB6nCleUYTOIPwKcWCGok1mn8=", - "dev": true, - "requires": { - "buffer-crc32": "0.2.13", - "fd-slicer": "1.0.1" - } - } - } -} diff --git a/docs.helm.sh/package.json b/docs.helm.sh/package.json deleted file mode 100644 index 5c699a4ef9..0000000000 --- a/docs.helm.sh/package.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "name": "helm-docs", - "version": "0.0.1", - "description": "Helm Docs", - "main": "gulpfile.js/index.js", - "author": "Ronan Flynn-Curran", - "license": "MIT", - "repository": { - "type": "git", - "url": "git+https://github.com/helm/helm-www" - }, - "devDependencies": { - "bower": "^1.7.1", - "del": "^2.2.0", - "gulp": "^3.9.0", - "gulp-autoprefixer": "^3.1.0", - "gulp-cache": "^0.4.1", - "gulp-concat": "^2.6.0", - "gulp-cssnano": "^2.1.0", - "gulp-filenames": "^4.0.1", - "gulp-foreach": "^0.1.0", - "gulp-git": "^2.4.0", - "gulp-imagemin": "^2.4.0", - "gulp-inject-string": "^1.1.0", - "gulp-jshint": "^2.0.4", - "gulp-livereload": "^3.8.1", - "gulp-minify-css": "^1.2.2", - "gulp-notify": "^2.2.0", - "gulp-plumber": "^1.1.0", - "gulp-regex-replace": "^0.2.3", - "gulp-rename": "^1.2.2", - "gulp-replace": "^0.5.4", - "gulp-ruby-sass": "^2.0.6", - "gulp-sourcemaps": "^1.6.0", - "gulp-string-replace": "^0.4.0", - "gulp-tap": "^1.0.1", - "gulp-track-filenames": "^0.1.0", - "gulp-uglify": "^1.5.1", - "gulp-util": "^3.0.8", - "jshint": "^2.9.4", - "remove-markdown": "0.1.0", - "run-sequence": "^1.2.2", - "streamqueue": "^1.1.1" - }, - "dependencies": { - "gulp-inject-element": "^2.0.2" - } -} diff --git a/docs.helm.sh/rootfs/.dockerignore b/docs.helm.sh/rootfs/.dockerignore deleted file mode 100644 index 1d1fe94df4..0000000000 --- a/docs.helm.sh/rootfs/.dockerignore +++ /dev/null @@ -1 +0,0 @@ -Dockerfile \ No newline at end of file diff --git a/docs.helm.sh/rootfs/Dockerfile b/docs.helm.sh/rootfs/Dockerfile deleted file mode 100644 index d86bc2bab5..0000000000 --- a/docs.helm.sh/rootfs/Dockerfile +++ /dev/null @@ -1,29 +0,0 @@ -FROM alpine:3.5 - -ARG plugins=http.cors,http.ipfilter,http.minify -ARG BUILD_DATE - -RUN apk upgrade --no-cache --available \ - && apk add --no-cache \ - bash \ - ca-certificates \ - curl \ - libressl \ - openssh-client \ - tar \ - && adduser -D -u 1000 caddy - -RUN curl --silent --show-error --fail --location \ - --header "Accept: application/tar+gzip, application/x-gzip, application/octet-stream" -o - \ - "https://caddyserver.com/download/linux/amd64?plugins=${plugins}" \ - | tar --no-same-owner -C /usr/bin/ -xz caddy \ - && chmod 0755 /usr/bin/caddy \ - && /usr/bin/caddy -version - -COPY . / - -EXPOSE 2015 - -USER caddy -ENTRYPOINT ["/usr/bin/caddy"] -CMD ["--conf", "/etc/caddy/Caddyfile", "--log", "stdout"] \ No newline at end of file diff --git a/docs.helm.sh/rootfs/etc/caddy/Caddyfile b/docs.helm.sh/rootfs/etc/caddy/Caddyfile deleted file mode 100644 index 732114cdfc..0000000000 --- a/docs.helm.sh/rootfs/etc/caddy/Caddyfile +++ /dev/null @@ -1,5 +0,0 @@ -:2015 { - root /public - tls off - status 200 /healthz -} \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/architecture/index.html b/docs.helm.sh/rootfs/public/architecture/index.html deleted file mode 100644 index cb686a3723..0000000000 --- a/docs.helm.sh/rootfs/public/architecture/index.html +++ /dev/null @@ -1,1398 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

The Kubernetes Helm Architecture

- -

This document describes the Helm architecture at a high level.

- -

The Purpose of Helm

- -

Helm is a tool for managing Kubernetes packages called charts. Helm -can do the following:

- -
    -
  • Create new charts from scratch
  • -
  • Package charts into chart archive (tgz) files
  • -
  • Interact with chart repositories where charts are stored
  • -
  • Install and uninstall charts into an existing Kubernetes cluster
  • -
  • Manage the release cycle of charts that have been installed with Helm
  • -
- -

For Helm, there are three important concepts:

- -
    -
  1. The chart is a bundle of information necessary to create an -instance of a Kubernetes application.
  2. -
  3. The config contains configuration information that can be merged -into a packaged chart to create a releasable object.
  4. -
  5. A release is a running instance of a chart, combined with a -specific config.
  6. -
- -

Components

- -

Helm has two major components:

- -

The Helm Client is a command-line client for end users. The client -is responsible for the following domains:

- -
    -
  • Local chart development
  • -
  • Managing repositories
  • -
  • Interacting with the Tiller server - -
      -
    • Sending charts to be installed
    • -
    • Asking for information about releases
    • -
    • Requesting upgrading or uninstalling of existing releases
    • -
  • -
- -

The Tiller Server is an in-cluster server that interacts with the -Helm client, and interfaces with the Kubernetes API server. The server -is responsible for the following:

- -
    -
  • Listening for incoming requests from the Helm client
  • -
  • Combining a chart and configuration to build a release
  • -
  • Installing charts into Kubernetes, and then tracking the subsequent -release
  • -
  • Upgrading and uninstalling charts by interacting with Kubernetes
  • -
- -

In a nutshell, the client is responsible for managing charts, and the -server is responsible for managing releases.

- -

Implementation

- -

The Helm client is written in the Go programming language, and uses the -gRPC protocol suite to interact with the Tiller server.

- -

The Tiller server is also written in Go. It provides a gRPC server to -connect with the client, and it uses the Kubernetes client library to -communicate with Kubernetes. Currently, that library uses REST+JSON.

- -

The Tiller server stores information in ConfigMaps located inside of -Kubernetes. It does not need its own database.

- -

Configuration files are, when possible, written in YAML.

- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/categories/index.xml b/docs.helm.sh/rootfs/public/categories/index.xml deleted file mode 100644 index 71d570e102..0000000000 --- a/docs.helm.sh/rootfs/public/categories/index.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - Categories - https://docs.helm.sh/categories/ - en-us - Mon, 01 Jan 0001 00:00:00 UTC - - - diff --git a/docs.helm.sh/rootfs/public/chart_best_practices/conventions/index.html b/docs.helm.sh/rootfs/public/chart_best_practices/conventions/index.html deleted file mode 100644 index 05db7d902d..0000000000 --- a/docs.helm.sh/rootfs/public/chart_best_practices/conventions/index.html +++ /dev/null @@ -1,1382 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

General Conventions

- -

This part of the Best Practices Guide explains general conventions.

- -

Chart Names

- -

Chart names should be lower case letters and numbers. Words may be separated with dashes (-):

- -

Examples:

- -
drupal
-nginx-lego
-aws-cluster-autoscaler
-
- -

Neither uppercase letters nor underscores should be used in chart names. Dots should not be used in chart names.

- -

The directory that contains a chart MUST have the same name as the chart. Thus, the chart nginx-lego MUST be created in a directory called nginx-lego/. This is not merely a stylistic detail, but a requirement of the Helm Chart format.

- -

Version Numbers

- -

Wherever possible, Helm uses SemVer 2 to represent version numbers. (Note that Docker image tags do not necessarily follow SemVer, and are thus considered an unfortunate exception to the rule.)

- -

When SemVer versions are stored in Kubernetes labels, we conventionally alter the + character to an _ character, as labels do not allow the + sign as a value.

- -

Formatting YAML

- -

YAML files should be indented using two spaces (and never tabs).

- -

Usage of the Words Helm, Tiller, and Chart

- -

There are a few small conventions followed for using the words Helm, helm, Tiller, and tiller.

- -
    -
  • Helm refers to the project, and is often used as an umbrella term
  • -
  • helm refers to the client-side command
  • -
  • Tiller is the proper name of the backend
  • -
  • tiller is the name of the binary run on the backend
  • -
  • The term ‘chart’ does not need to be capitalized, as it is not a proper noun.
  • -
- -

When in doubt, use Helm (with an uppercase ‘H’).

- -

Restricting Tiller by Version

- -

A Chart.yaml file can specify a tillerVersion SemVer constraint:

- -
name: mychart
-version: 0.2.0
-tillerVersion: ">=2.4.0"
-
- -

This constraint should be set when templates use a new feature that was not -supported in older versions of Helm. While this parameter will accept sophisticated -SemVer rules, the best practice is to default to the form >=2.4.0, where 2.4.0 -is the version that introduced the new feature used in the chart.

- -

This feature was introduced in Helm 2.4.0, so any version of Tiller older than -2.4.0 will simply ignore this field.

- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/chart_best_practices/index.html b/docs.helm.sh/rootfs/public/chart_best_practices/index.html deleted file mode 100644 index eec4daf214..0000000000 --- a/docs.helm.sh/rootfs/public/chart_best_practices/index.html +++ /dev/null @@ -1,2081 +0,0 @@ - - - - - - - - - Chart Best Practices - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
- -
-
- -

The Chart Best Practices Guide

- -

This guide covers the Helm Team’s considered best practices for creating charts. -It focuses on how charts should be structured.

- -

We focus primarily on best practices for charts that may be publicly deployed. -We know that many charts are for internal-use only, and authors of such charts -may find that their internal interests override our suggestions here.

- -

Table of Contents

- - -
-
- -
-
- -

General Conventions

- -

This part of the Best Practices Guide explains general conventions.

- -

Chart Names

- -

Chart names should be lower case letters and numbers. Words may be separated with dashes (-):

- -

Examples:

- -
drupal
-nginx-lego
-aws-cluster-autoscaler
-
- -

Neither uppercase letters nor underscores should be used in chart names. Dots should not be used in chart names.

- -

The directory that contains a chart MUST have the same name as the chart. Thus, the chart nginx-lego MUST be created in a directory called nginx-lego/. This is not merely a stylistic detail, but a requirement of the Helm Chart format.

- -

Version Numbers

- -

Wherever possible, Helm uses SemVer 2 to represent version numbers. (Note that Docker image tags do not necessarily follow SemVer, and are thus considered an unfortunate exception to the rule.)

- -

When SemVer versions are stored in Kubernetes labels, we conventionally alter the + character to an _ character, as labels do not allow the + sign as a value.

- -

Formatting YAML

- -

YAML files should be indented using two spaces (and never tabs).

- -

Usage of the Words Helm, Tiller, and Chart

- -

There are a few small conventions followed for using the words Helm, helm, Tiller, and tiller.

- -
    -
  • Helm refers to the project, and is often used as an umbrella term
  • -
  • helm refers to the client-side command
  • -
  • Tiller is the proper name of the backend
  • -
  • tiller is the name of the binary run on the backend
  • -
  • The term ‘chart’ does not need to be capitalized, as it is not a proper noun.
  • -
- -

When in doubt, use Helm (with an uppercase ‘H’).

- -

Restricting Tiller by Version

- -

A Chart.yaml file can specify a tillerVersion SemVer constraint:

- -
name: mychart
-version: 0.2.0
-tillerVersion: ">=2.4.0"
-
- -

This constraint should be set when templates use a new feature that was not -supported in older versions of Helm. While this parameter will accept sophisticated -SemVer rules, the best practice is to default to the form >=2.4.0, where 2.4.0 -is the version that introduced the new feature used in the chart.

- -

This feature was introduced in Helm 2.4.0, so any version of Tiller older than -2.4.0 will simply ignore this field.

-
-
- -
-
- -

Labels and Annotations

- -

This part of the Best Practices Guide discusses the best practices for using -labels and annotations in your chart.

- -

Is it a Label or an Annotation?

- -

An item of metadata should be a label under the following conditions:

- -
    -
  • It is used by Kubernetes to identify this resource
  • -
  • It is useful to expose to operators for the purpose of querying the system.
  • -
- -

For example, we suggest using chart: NAME-VERSION as a label so that operators -can conveniently find all of the instances of a particular chart to use.

- -

If an item of metadata is not used for querying, it should be set as an annotation -instead.

- -

Helm hooks are always annotations.

- -

Standard Labels

- -

The following table defines common labels that Helm charts use. Helm itself never requires that a particular label be present. Labels that are marked REC -are recommended, and should be placed onto a chart for global consistency. Those marked OPT are optional. These are idiomatic or commonly in use, but are not relied upon frequently for operational purposes.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameStatusDescription
heritageRECThis should always be set to {{ .Release.Service }}. It is for finding all things managed by Tiller.
releaseRECThis should be the {{ .Release.Name }}.
chartRECThis should be the chart name and version: {{ .Chart.Name }}-{{ .Chart.Version \| replace "+" "_" }}.
appRECThis should be the app name, reflecting the entire app. Usually {{ template "name" . }} is used for this. This is used by many Kubernetes manifests, and is not Helm-specific.
componentOPTThis is a common label for marking the different roles that pieces may play in an application. For example, component: frontend.
-
-
- -
-
- -

Pods and PodTemplates

- -

This part of the Best Practices Guide discusses formatting the Pod and PodTemplate -portions in chart manifests.

- -

The following (non-exhaustive) list of resources use PodTemplates:

- -
    -
  • Deployment
  • -
  • ReplicationController
  • -
  • ReplicaSet
  • -
  • DaemonSet
  • -
  • StatefulSet
  • -
- -

Images

- -

A container image should use a fixed tag or the SHA of the image. It should not use the tags latest, head, canary, or other tags that are designed to be “floating”.

- -

Images may be defined in the values.yaml file to make it easy to swap out images.

- -
image: {{ .Values.redisImage | quote }}
-
- -

An image and a tag may be defined in values.yaml as two separate fields:

- -
image: "{{ .Values.redisImage }}:{{ .Values.redisTag }}"
-
- -

ImagePullPolicy

- -

helm create sets the imagePullPolicy to IfNotPresent by default by doing the following in your deployment.yaml:

- -
imagePullPolicy: {{ .Values.image.pullPolicy }}
-
- -

And values.yaml:

- -
pullPolicy: IfNotPresent
-
- -

Similarly, Kubernetes defaults the imagePullPolicy to IfNotPresent if it is not defined at all. If you want a value other than IfNotPresent, simply update the value in values.yaml to your desired value.

- -

PodTemplates Should Declare Selectors

- -

All PodTemplate sections should specify a selector. For example:

- -
selector:
-  matchLabels:
-      app: MyName
-template:
-  metadata:
-    labels:
-      app: MyName
-
- -

This is a good practice because it makes the relationship between the set and -the pod.

- -

But this is even more important for sets like Deployment. -Without this, the entire set of labels is used to select matching pods, and -this will break if you use labels that change, like version or release date.

-
-
- -
-
- -

Role-Based Access Control

- -

This part of the Best Practices Guide discusses the creation and formatting of RBAC resources in chart manifests.

- -

RBAC resources are:

- -
    -
  • ServiceAccount (namespaced)
  • -
  • Role (namespaced)
  • -
  • ClusterRole
  • -
  • RoleBinding (namespaced)
  • -
  • ClusterRoleBinding
  • -
- -

YAML Configuration

- -

RBAC and ServiceAccount configuration should happen under separate keys. They are separate things. Splitting these two concepts out in the YAML disambiguates them and make this clearer.

- -
rbac:
-  # Specifies whether RBAC resources should be created
-  create: true
-
-serviceAccount:
-  # Specifies whether a ServiceAccount should be created
-  create: true
-  # The name of the ServiceAccount to use.
-  # If not set and create is true, a name is generated using the fullname template
-  name:
-
- -

This structure can be extended for more complex charts that require multiple ServiceAccounts.

- -
serviceAccounts:
-  client:
-    create: true
-    name:
-  server: 
-    create: true
-    name:
-
- -

RBAC Resources Should be Created by Default

- -

rbac.create should be a boolean value controlling whether RBAC resources are created. The default should be true. Users who wish to manage RBAC access controls themselves can set this value to false (in which case see below).

- -

Using RBAC Resources

- -

serviceAccount.name should set to the name of the ServiceAccount to be used by access-controlled resources created by the chart. If serviceAccount.create is true, then a ServiceAccount with this name should be created. If the name is not set, then a name is generated using the fullname template, If serviceAccount.create is false, then it should not be created, but it should still be associated with the same resources so that manually-created RBAC resources created later that reference it will function correctly. If serviceAccount.create is false and the name is not specified, then the default ServiceAccount is used.

- -

The following helper template should be used for the ServiceAccount.

- -
{{/*
-Create the name of the service account to use
-*/}}
-{{- define "mychart.serviceAccountName" -}}
-{{- if .Values.serviceAccount.create -}}
-    {{ default (include "mychart.fullname" .) .Values.serviceAccount.name }}
-{{- else -}}
-    {{ default "default" .Values.serviceAccount.name }}
-{{- end -}}
-{{- end -}}
-
-
-
- -
-
- -

Requirements Files

- -

This section of the guide covers best practices for requirements.yaml files.

- -

Versions

- -

Where possible, use version ranges instead of pinning to an exact version. The suggested default is to use a patch-level version match:

- -
version: ~1.2.3
-
- -

This will match version 1.2.3 and any patches to that release. In other words, ~1.2.3 is equivalent to >= 1.2.3, < 1.3.0

- -

For the complete version matching syntax, please see the semver documentation

- -

Repository URLs

- -

Where possible, use https:// repository URLs, followed by http:// URLs.

- -

If the repository has been added to the repository index file, the repository name can be used as an alias of URL. Use alias: or @ followed by repository names.

- -

File URLs (file://...) are considered a “special case” for charts that are assembled by a fixed deployment pipeline. Charts that use file:// in a requirements.yaml file are not allowed in the official Helm repository.

- -

Conditions and Tags

- -

Conditions or tags should be added to any dependencies that are optional.

- -

The preferred form of a condition is:

- -
condition: somechart.enabled
-
- -

Where somechart is the chart name of the dependency.

- -

When multiple subcharts (dependencies) together provide an optional or swappable feature, those charts should share the same tags.

- -

For example, if both nginx and memcached together provided performance optimizations for the main app in the chart, and were required to both be present when that feature is enabled, then they might both have a -tags section like this:

- -
tags:
-  - webaccelerator
-
- -

This allows a user to turn that feature on and off with one tag.

-
-
- -
-
- -

Templates

- -

This part of the Best Practices Guide focuses on templates.

- -

Structure of templates/

- -

The templates directory should be structured as follows:

- -
    -
  • Template files should have the extension .yaml if they produce YAML output. The -extension .tpl may be used for template files that produce no formatted content.
  • -
  • Template file names should use dashed notation (my-example-configmap.yaml), not camelcase.
  • -
  • Each resource definition should be in its own template file.
  • -
  • Template file names should reflect the resource kind in the name. e.g. foo-pod.yaml, -bar-svc.yaml
  • -
- -

Names of Defined Templates

- -

Defined templates (templates created inside a {{ define }} directive) are -globally accessible. That means that a chart and all of its subcharts will have -access to all of the templates created with {{ define }}.

- -

For that reason, all defined template names should be namespaced.

- -

Correct:

- -
{{- define "nginx.fullname" }}
-{{/* ... */}}
-{{ end -}}
-
- -

Incorrect:

- -
{{- define "fullname" -}}
-{{/* ... */}}
-{{ end -}}
-
- -

It is highly recommended that new charts are created via helm create command as the template names are automatically defined as per this best practice.

- -

Formatting Templates

- -

Templates should be indented using two spaces (never tabs).

- -

Template directives should have whitespace after the opening braces and before the -closing braces:

- -

Correct:

- -
{{ .foo }}
-{{ print "foo" }}
-{{- print "bar" -}}
-
- -

Incorrect:

- -
{{.foo}}
-{{print "foo"}}
-{{-print "bar"-}}
-
- -

Templates should chomp whitespace where possible:

- -
foo:
-  {{- range .Values.items }}
-  {{ . }}
-  {{ end -}}
-
- -

Blocks (such as control structures) may be indented to indicate flow of the template code.

- -
{{ if $foo -}}
-  {{- with .Bar }}Hello{{ end -}}
-{{- end -}} 
-
- -

However, since YAML is a whitespace-oriented language, it is often not possible for code indentation to follow that convention.

- -

Whitespace in Generated Templates

- -

It is preferable to keep the amount of whitespace in generated templates to -a minimum. In particular, numerous blank lines should not appear adjacent to each -other. But occasional empty lines (particularly between logical sections) is -fine.

- -

This is best:

- -
apiVersion: batch/v1
-kind: Job
-metadata:
-  name: example
-  labels:
-    first: first
-    second: second
-
- -

This is okay:

- -
apiVersion: batch/v1
-kind: Job
-
-metadata:
-  name: example
-
-  labels:
-    first: first
-    second: second
-
-
- -

But this should be avoided:

- -
apiVersion: batch/v1
-kind: Job
-
-metadata:
-  name: example
-
-
-
-
-
-  labels:
-    first: first
-
-    second: second
-
-
- -

Comments (YAML Comments vs. Template Comments)

- -

Both YAML and Helm Templates have comment markers.

- -

YAML comments:

- -
# This is a comment
-type: sprocket
-
- -

Template Comments:

- -
{{- /*
-This is a comment.
-*/ -}}
-type: frobnitz
-
- -

Template comments should be used when documenting features of a template, such as explaining a defined template:

- -
{{- /*
-mychart.shortname provides a 6 char truncated version of the release name.
-*/ }}
-{{ define "mychart.shortname" -}}
-{{ .Release.Name | trunc 6 }}
-{{- end -}}
-
-
- -

Inside of templates, YAML comments may be used when it is useful for Helm users to (possibly) see the comments during debugging.

- -
# This may cause problems if the value is more than 100Gi
-memory: {{ .Values.maxMem | quote }}
-
- -

The comment above is visible when the user runs helm install --debug, while -comments specified in {{- /* */ -}} sections are not.

- -

Use of JSON in Templates and Template Output

- -

YAML is a superset of JSON. In some cases, using a JSON syntax can be more -readable than other YAML representations.

- -

For example, this YAML is closer to the normal YAML method of expressing lists:

- -
arguments: 
-  - "--dirname"
-  - "/foo"
-
- -

But it is easier to read when collapsed into a JSON list style:

- -
arguments: ["--dirname", "/foo"]
-
- -

Using JSON for increased legibility is good. However, JSON syntax should not -be used for representing more complex constructs.

- -

When dealing with pure JSON embedded inside of YAML (such as init container -configuration), it is of course appropriate to use the JSON format.

-
-
- -
-
- -

Third Party Resources

- -

This section of the Best Practices Guide deals with creating and using Third Party Resource -objects.

- -

When working with Third Party Resources (TPRs), it is important to distinguish -two different pieces:

- -
    -
  • There is a declaration of a TPR. This is the YAML file that has the kind ThirdPartyResource
  • -
  • Then there are resources that use the TPR. Say a TPR defines foo.example.com/v1. Any resource -that has apiVersion: example.com/v1 and kind Foo is a resource that uses the -TPR.
  • -
- -

Install a TPR Declaration Before Using the Resource

- -

Helm is optimized to load as many resources into Kubernetes as fast as possible. -By design, Kubernetes can take an entire set of manifests and bring them all -online (this is called the reconciliation loop).

- -

But there’s a difference with TPRs.

- -

For a TPR, the declaration must be registered before any resources of that TPRs -kind(s) can be used. And the registration process sometimes takes a few seconds.

- -

Method 1: Separate Charts

- -

One way to do this is to put the TPR definition in one chart, and then put any -resources that use that TPR in another chart.

- -

In this method, each chart must be installed separately.

- -

Method 2: Pre-install Hooks

- -

To package the two together, add a pre-install hook to the TPR definition so -that it is fully installed before the rest of the chart is executed.

- -

Note that if you create the TPR with a pre-install hook, that TPR definition -will not be deleted when helm delete is run.

-
-
- -
-
- -

Values

- -

This part of the best practices guide covers using values. In this part of the -guide, we provide recommendations on how you should structure and use your -values, with focus on designing a chart’s values.yaml file.

- -

Naming Conventions

- -

Variables names should begin with a lowercase letter, and words should be -separated with camelcase:

- -

Correct:

- -
chicken: true
-chickenNoodleSoup: true
-
- -

Incorrect:

- -
Chicken: true  # initial caps may conflict with built-ins
-chicken-noodle-soup: true # do not use hyphens in the name
-
- -

Note that all of Helm’s built-in variables begin with an uppercase letter to -easily distinguish them from user-defined values: .Release.Name, -.Capabilities.KubeVersion.

- -

Flat or Nested Values

- -

YAML is a flexible format, and values may be nested deeply or flattened.

- -

Nested:

- -
server:
-  name: nginx
-  port: 80
-
- -

Flat:

- -
serverName: nginx
-serverPort: 80
-
- -

In most cases, flat should be favored over nested. The reason for this is that -it is simpler for template developers and users.

- -

For optimal safety, a nested value must be checked at every level:

- -
{{ if .Values.server }}
-  {{ default "none" .Values.server.name }}
-{{ end }}
-
- -

For every layer of nesting, an existence check must be done. But for flat -configuration, such checks can be skipped, making the template easier to read -and use.

- -
{{ default "none" .Values.serverName }}
-
- -

When there are a large number of related variables, and at least one of them -is non-optional, nested values may be used to improve readability.

- -

Make Types Clear

- -

YAML’s type coercion rules are sometimes counterintuitive. For example, -foo: false is not the same as foo: "false". Large integers like foo: 12345678 -will get converted to scientific notation in some cases.

- -

The easiest way to avoid type conversion errors is to be explicit about strings, -and implicit about everything else. Or, in short, quote all strings.

- -

Often, to avoid the integer casting issues, it is advantageous to store your -integers as strings as well, and use {{ int $value }} in the template to convert -from a string back to an integer.

- -

In most cases, explicit type tags are respected, so foo: !!string 1234 should -treat 1234 as a string. However, the YAML parser consumes tags, so the type -data is lost after one parse.

- -

Consider How Users Will Use Your Values

- -

There are three potential sources of values:

- -
    -
  • A chart’s values.yaml file
  • -
  • A values file supplied by helm install -f or helm upgrade -f
  • -
  • The values passed to a --set flag on helm install or helm upgrade
  • -
- -

When designing the structure of your values, keep in mind that users of your -chart may want to override them via either the -f flag or with the --set -option.

- -

Since --set is more limited in expressiveness, the first guidelines for writing -your values.yaml file is make it easy to override from --set.

- -

For this reason, it’s often better to structure your values file using maps.

- -

Difficult to use with --set:

- -
servers:
-  - name: foo
-    port: 80
-  - name: bar
-    port: 81
-
- -

The above cannot be expressed with --set in Helm <=2.4. In Helm 2.5, the -accessing the port on foo is --set servers[0].port=80. Not only is it harder -for the user to figure out, but it is prone to errors if at some later time the -order of the servers is changed.

- -

Easy to use:

- -
servers:
-  foo:
-    port: 80
-  bar:
-    port: 81
-
- -

Accessing foo’s port is much more obvious: --set servers.foo.port=80.

- -

Document ‘values.yaml’

- -

Every defined property in ‘values.yaml’ should be documented. The documentation string should begin with the name of the property that it describes, and then give at least a one-sentence description.

- -

Incorrect:

- -
# the host name for the webserver
-serverHost = example
-serverPort = 9191
-
- -

Correct:

- -
# serverHost is the host name for the webserver
-serverHost = example
-# serverPort is the HTTP listener port for the webserver
-serverPort = 9191
-
-
- -

Beginning each comment with the name of the parameter it documents makes it easy to grep out documentation, and will enable documentation tools to reliably correlate doc strings with the parameters they describe.

-
-
- -
-
 
-
- -
-
-

- Helm is supported by and built with a community of over 250 developers. -

-

- helm.sh and docs.helm.sh are maintained by Microsoft -

-
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/chart_best_practices/index.xml b/docs.helm.sh/rootfs/public/chart_best_practices/index.xml deleted file mode 100644 index 6ccf90e889..0000000000 --- a/docs.helm.sh/rootfs/public/chart_best_practices/index.xml +++ /dev/null @@ -1,796 +0,0 @@ - - - - Chart_best_practices - https://docs.helm.sh/chart_best_practices/ - en-us - Mon, 01 Jan 0001 00:00:00 UTC - - - - https://docs.helm.sh/chart_best_practices/readme/ - Mon, 01 Jan 0001 00:00:00 UTC - https://docs.helm.sh/chart_best_practices/readme/ - - -<h1 id="the-chart-best-practices-guide">The Chart Best Practices Guide</h1> - -<p>This guide covers the Helm Team&rsquo;s considered best practices for creating charts. -It focuses on how charts should be structured.</p> - -<p>We focus primarily on best practices for charts that may be publicly deployed. -We know that many charts are for internal-use only, and authors of such charts -may find that their internal interests override our suggestions here.</p> - -<h2 id="table-of-contents">Table of Contents</h2> - -<ul> -<li><a href="./#conventions">General Conventions</a>: Learn about general chart conventions.</li> -<li><a href="./#values">Values Files</a>: See the best practices for structuring <code>values.yaml</code>.</li> -<li><a href="./#templates">Templates</a>: Learn some of the best techniques for writing templates.</li> -<li><a href="./#requirements">Requirements</a>: Follow best practices for <code>requirements.yaml</code> files.</li> -<li><a href="./#labels">Labels and Annotations</a>: Helm has a <em>heritage</em> of labeling and annotating.</li> -<li>Kubernetes Resources: - -<ul> -<li><a href="./#pods">Pods and Pod Specs</a>: See the best practices for working with pod specifications.</li> -<li><a href="./#rbac">Role-Based Access Control</a>: Guidance on creating and using service accounts, roles, and role bindings.</li> -<li><a href="./#third_party_resources">Third Party Resources</a>: Third Party Resources (TPRs) have their own associated best practices.</li> -</ul></li> -</ul> - - - - - - https://docs.helm.sh/chart_best_practices/conventions/ - Mon, 01 Jan 0001 00:00:00 UTC - https://docs.helm.sh/chart_best_practices/conventions/ - - -<h1 id="general-conventions">General Conventions</h1> - -<p>This part of the Best Practices Guide explains general conventions.</p> - -<h2 id="chart-names">Chart Names</h2> - -<p>Chart names should be lower case letters and numbers. Words <em>may</em> be separated with dashes (-):</p> - -<p>Examples:</p> - -<pre><code>drupal -nginx-lego -aws-cluster-autoscaler -</code></pre> - -<p>Neither uppercase letters nor underscores should be used in chart names. Dots should not be used in chart names.</p> - -<p>The directory that contains a chart MUST have the same name as the chart. Thus, the chart <code>nginx-lego</code> MUST be created in a directory called <code>nginx-lego/</code>. This is not merely a stylistic detail, but a requirement of the Helm Chart format.</p> - -<h2 id="version-numbers">Version Numbers</h2> - -<p>Wherever possible, Helm uses <a href="http://semver.org">SemVer 2</a> to represent version numbers. (Note that Docker image tags do not necessarily follow SemVer, and are thus considered an unfortunate exception to the rule.)</p> - -<p>When SemVer versions are stored in Kubernetes labels, we conventionally alter the <code>+</code> character to an <code>_</code> character, as labels do not allow the <code>+</code> sign as a value.</p> - -<h2 id="formatting-yaml">Formatting YAML</h2> - -<p>YAML files should be indented using <em>two spaces</em> (and never tabs).</p> - -<h2 id="usage-of-the-words-helm-tiller-and-chart">Usage of the Words Helm, Tiller, and Chart</h2> - -<p>There are a few small conventions followed for using the words Helm, helm, Tiller, and tiller.</p> - -<ul> -<li>Helm refers to the project, and is often used as an umbrella term</li> -<li><code>helm</code> refers to the client-side command</li> -<li>Tiller is the proper name of the backend</li> -<li><code>tiller</code> is the name of the binary run on the backend</li> -<li>The term &lsquo;chart&rsquo; does not need to be capitalized, as it is not a proper noun.</li> -</ul> - -<p>When in doubt, use <em>Helm</em> (with an uppercase &lsquo;H&rsquo;).</p> - -<h2 id="restricting-tiller-by-version">Restricting Tiller by Version</h2> - -<p>A <code>Chart.yaml</code> file can specify a <code>tillerVersion</code> SemVer constraint:</p> - -<pre><code class="language-yaml">name: mychart -version: 0.2.0 -tillerVersion: &quot;&gt;=2.4.0&quot; -</code></pre> - -<p>This constraint should be set when templates use a new feature that was not -supported in older versions of Helm. While this parameter will accept sophisticated -SemVer rules, the best practice is to default to the form <code>&gt;=2.4.0</code>, where <code>2.4.0</code> -is the version that introduced the new feature used in the chart.</p> - -<p>This feature was introduced in Helm 2.4.0, so any version of Tiller older than -2.4.0 will simply ignore this field.</p> - - - - - - https://docs.helm.sh/chart_best_practices/labels/ - Mon, 01 Jan 0001 00:00:00 UTC - https://docs.helm.sh/chart_best_practices/labels/ - - -<h1 id="labels-and-annotations">Labels and Annotations</h1> - -<p>This part of the Best Practices Guide discusses the best practices for using -labels and annotations in your chart.</p> - -<h2 id="is-it-a-label-or-an-annotation">Is it a Label or an Annotation?</h2> - -<p>An item of metadata should be a label under the following conditions:</p> - -<ul> -<li>It is used by Kubernetes to identify this resource</li> -<li>It is useful to expose to operators for the purpose of querying the system.</li> -</ul> - -<p>For example, we suggest using <code>chart: NAME-VERSION</code> as a label so that operators -can conveniently find all of the instances of a particular chart to use.</p> - -<p>If an item of metadata is not used for querying, it should be set as an annotation -instead.</p> - -<p>Helm hooks are always annotations.</p> - -<h2 id="standard-labels">Standard Labels</h2> - -<p>The following table defines common labels that Helm charts use. Helm itself never requires that a particular label be present. Labels that are marked REC -are recommended, and <em>should</em> be placed onto a chart for global consistency. Those marked OPT are optional. These are idiomatic or commonly in use, but are not relied upon frequently for operational purposes.</p> - -<table> -<thead> -<tr> -<th>Name</th> -<th>Status</th> -<th>Description</th> -</tr> -</thead> - -<tbody> -<tr> -<td>heritage</td> -<td>REC</td> -<td>This should always be set to <code>{{ .Release.Service }}</code>. It is for finding all things managed by Tiller.</td> -</tr> - -<tr> -<td>release</td> -<td>REC</td> -<td>This should be the <code>{{ .Release.Name }}</code>.</td> -</tr> - -<tr> -<td>chart</td> -<td>REC</td> -<td>This should be the chart name and version: <code>{{ .Chart.Name }}-{{ .Chart.Version \| replace &quot;+&quot; &quot;_&quot; }}</code>.</td> -</tr> - -<tr> -<td>app</td> -<td>REC</td> -<td>This should be the app name, reflecting the entire app. Usually <code>{{ template &quot;name&quot; . }}</code> is used for this. This is used by many Kubernetes manifests, and is not Helm-specific.</td> -</tr> - -<tr> -<td>component</td> -<td>OPT</td> -<td>This is a common label for marking the different roles that pieces may play in an application. For example, <code>component: frontend</code>.</td> -</tr> -</tbody> -</table> - - - - - - https://docs.helm.sh/chart_best_practices/pods/ - Mon, 01 Jan 0001 00:00:00 UTC - https://docs.helm.sh/chart_best_practices/pods/ - - -<h1 id="pods-and-podtemplates">Pods and PodTemplates</h1> - -<p>This part of the Best Practices Guide discusses formatting the Pod and PodTemplate -portions in chart manifests.</p> - -<p>The following (non-exhaustive) list of resources use PodTemplates:</p> - -<ul> -<li>Deployment</li> -<li>ReplicationController</li> -<li>ReplicaSet</li> -<li>DaemonSet</li> -<li>StatefulSet</li> -</ul> - -<h2 id="images">Images</h2> - -<p>A container image should use a fixed tag or the SHA of the image. It should not use the tags <code>latest</code>, <code>head</code>, <code>canary</code>, or other tags that are designed to be &ldquo;floating&rdquo;.</p> - -<p>Images <em>may</em> be defined in the <code>values.yaml</code> file to make it easy to swap out images.</p> - -<pre><code>image: {{ .Values.redisImage | quote }} -</code></pre> - -<p>An image and a tag <em>may</em> be defined in <code>values.yaml</code> as two separate fields:</p> - -<pre><code>image: &quot;{{ .Values.redisImage }}:{{ .Values.redisTag }}&quot; -</code></pre> - -<h2 id="imagepullpolicy">ImagePullPolicy</h2> - -<p><code>helm create</code> sets the <code>imagePullPolicy</code> to <code>IfNotPresent</code> by default by doing the following in your <code>deployment.yaml</code>:</p> - -<pre><code class="language-yaml">imagePullPolicy: {{ .Values.image.pullPolicy }} -</code></pre> - -<p>And <code>values.yaml</code>:</p> - -<pre><code class="language-yaml">pullPolicy: IfNotPresent -</code></pre> - -<p>Similarly, Kubernetes defaults the <code>imagePullPolicy</code> to <code>IfNotPresent</code> if it is not defined at all. If you want a value other than <code>IfNotPresent</code>, simply update the value in <code>values.yaml</code> to your desired value.</p> - -<h2 id="podtemplates-should-declare-selectors">PodTemplates Should Declare Selectors</h2> - -<p>All PodTemplate sections should specify a selector. For example:</p> - -<pre><code class="language-yaml">selector: - matchLabels: - app: MyName -template: - metadata: - labels: - app: MyName -</code></pre> - -<p>This is a good practice because it makes the relationship between the set and -the pod.</p> - -<p>But this is even more important for sets like Deployment. -Without this, the <em>entire</em> set of labels is used to select matching pods, and -this will break if you use labels that change, like version or release date.</p> - - - - - - https://docs.helm.sh/chart_best_practices/rbac/ - Mon, 01 Jan 0001 00:00:00 UTC - https://docs.helm.sh/chart_best_practices/rbac/ - - -<h1 id="role-based-access-control">Role-Based Access Control</h1> - -<p>This part of the Best Practices Guide discusses the creation and formatting of RBAC resources in chart manifests.</p> - -<p>RBAC resources are:</p> - -<ul> -<li>ServiceAccount (namespaced)</li> -<li>Role (namespaced)</li> -<li>ClusterRole</li> -<li>RoleBinding (namespaced)</li> -<li>ClusterRoleBinding</li> -</ul> - -<h2 id="yaml-configuration">YAML Configuration</h2> - -<p>RBAC and ServiceAccount configuration should happen under separate keys. They are separate things. Splitting these two concepts out in the YAML disambiguates them and make this clearer.</p> - -<pre><code class="language-yaml">rbac: - # Specifies whether RBAC resources should be created - create: true - -serviceAccount: - # Specifies whether a ServiceAccount should be created - create: true - # The name of the ServiceAccount to use. - # If not set and create is true, a name is generated using the fullname template - name: -</code></pre> - -<p>This structure can be extended for more complex charts that require multiple ServiceAccounts.</p> - -<pre><code class="language-yaml">serviceAccounts: - client: - create: true - name: - server: - create: true - name: -</code></pre> - -<h2 id="rbac-resources-should-be-created-by-default">RBAC Resources Should be Created by Default</h2> - -<p><code>rbac.create</code> should be a boolean value controlling whether RBAC resources are created. The default should be <code>true</code>. Users who wish to manage RBAC access controls themselves can set this value to <code>false</code> (in which case see below).</p> - -<h2 id="using-rbac-resources">Using RBAC Resources</h2> - -<p><code>serviceAccount.name</code> should set to the name of the ServiceAccount to be used by access-controlled resources created by the chart. If <code>serviceAccount.create</code> is true, then a ServiceAccount with this name should be created. If the name is not set, then a name is generated using the <code>fullname</code> template, If <code>serviceAccount.create</code> is false, then it should not be created, but it should still be associated with the same resources so that manually-created RBAC resources created later that reference it will function correctly. If <code>serviceAccount.create</code> is false and the name is not specified, then the default ServiceAccount is used.</p> - -<p>The following helper template should be used for the ServiceAccount.</p> - -<pre><code class="language-yaml">{{/* -Create the name of the service account to use -*/}} -{{- define &quot;mychart.serviceAccountName&quot; -}} -{{- if .Values.serviceAccount.create -}} - {{ default (include &quot;mychart.fullname&quot; .) .Values.serviceAccount.name }} -{{- else -}} - {{ default &quot;default&quot; .Values.serviceAccount.name }} -{{- end -}} -{{- end -}} -</code></pre> - - - - - - https://docs.helm.sh/chart_best_practices/requirements/ - Mon, 01 Jan 0001 00:00:00 UTC - https://docs.helm.sh/chart_best_practices/requirements/ - - -<h1 id="requirements-files">Requirements Files</h1> - -<p>This section of the guide covers best practices for <code>requirements.yaml</code> files.</p> - -<h2 id="versions">Versions</h2> - -<p>Where possible, use version ranges instead of pinning to an exact version. The suggested default is to use a patch-level version match:</p> - -<pre><code class="language-yaml">version: ~1.2.3 -</code></pre> - -<p>This will match version <code>1.2.3</code> and any patches to that release. In other words, <code>~1.2.3</code> is equivalent to <code>&gt;= 1.2.3, &lt; 1.3.0</code></p> - -<p>For the complete version matching syntax, please see the <a href="https://github.com/Masterminds/semver#checking-version-constraints">semver documentation</a></p> - -<h3 id="repository-urls">Repository URLs</h3> - -<p>Where possible, use <code>https://</code> repository URLs, followed by <code>http://</code> URLs.</p> - -<p>If the repository has been added to the repository index file, the repository name can be used as an alias of URL. Use <code>alias:</code> or <code>@</code> followed by repository names.</p> - -<p>File URLs (<code>file://...</code>) are considered a &ldquo;special case&rdquo; for charts that are assembled by a fixed deployment pipeline. Charts that use <code>file://</code> in a <code>requirements.yaml</code> file are not allowed in the official Helm repository.</p> - -<h2 id="conditions-and-tags">Conditions and Tags</h2> - -<p>Conditions or tags should be added to any dependencies that <em>are optional</em>.</p> - -<p>The preferred form of a condition is:</p> - -<pre><code class="language-yaml">condition: somechart.enabled -</code></pre> - -<p>Where <code>somechart</code> is the chart name of the dependency.</p> - -<p>When multiple subcharts (dependencies) together provide an optional or swappable feature, those charts should share the same tags.</p> - -<p>For example, if both <code>nginx</code> and <code>memcached</code> together provided performance optimizations for the main app in the chart, and were required to both be present when that feature is enabled, then they might both have a -tags section like this:</p> - -<pre><code>tags: - - webaccelerator -</code></pre> - -<p>This allows a user to turn that feature on and off with one tag.</p> - - - - - - https://docs.helm.sh/chart_best_practices/templates/ - Mon, 01 Jan 0001 00:00:00 UTC - https://docs.helm.sh/chart_best_practices/templates/ - - -<h1 id="templates">Templates</h1> - -<p>This part of the Best Practices Guide focuses on templates.</p> - -<h2 id="structure-of-templates">Structure of templates/</h2> - -<p>The templates directory should be structured as follows:</p> - -<ul> -<li>Template files should have the extension <code>.yaml</code> if they produce YAML output. The -extension <code>.tpl</code> may be used for template files that produce no formatted content.</li> -<li>Template file names should use dashed notation (<code>my-example-configmap.yaml</code>), not camelcase.</li> -<li>Each resource definition should be in its own template file.</li> -<li>Template file names should reflect the resource kind in the name. e.g. <code>foo-pod.yaml</code>, -<code>bar-svc.yaml</code></li> -</ul> - -<h2 id="names-of-defined-templates">Names of Defined Templates</h2> - -<p>Defined templates (templates created inside a <code>{{ define }}</code> directive) are -globally accessible. That means that a chart and all of its subcharts will have -access to all of the templates created with <code>{{ define }}</code>.</p> - -<p>For that reason, <em>all defined template names should be namespaced.</em></p> - -<p>Correct:</p> - -<pre><code class="language-yaml">{{- define &quot;nginx.fullname&quot; }} -{{/* ... */}} -{{ end -}} -</code></pre> - -<p>Incorrect:</p> - -<pre><code class="language-yaml">{{- define &quot;fullname&quot; -}} -{{/* ... */}} -{{ end -}} -</code></pre> - -<p>It is highly recommended that new charts are created via <code>helm create</code> command as the template names are automatically defined as per this best practice.</p> - -<h2 id="formatting-templates">Formatting Templates</h2> - -<p>Templates should be indented using <em>two spaces</em> (never tabs).</p> - -<p>Template directives should have whitespace after the opening braces and before the -closing braces:</p> - -<p>Correct:</p> - -<pre><code>{{ .foo }} -{{ print &quot;foo&quot; }} -{{- print &quot;bar&quot; -}} -</code></pre> - -<p>Incorrect:</p> - -<pre><code>{{.foo}} -{{print &quot;foo&quot;}} -{{-print &quot;bar&quot;-}} -</code></pre> - -<p>Templates should chomp whitespace where possible:</p> - -<pre><code>foo: - {{- range .Values.items }} - {{ . }} - {{ end -}} -</code></pre> - -<p>Blocks (such as control structures) may be indented to indicate flow of the template code.</p> - -<pre><code>{{ if $foo -}} - {{- with .Bar }}Hello{{ end -}} -{{- end -}} -</code></pre> - -<p>However, since YAML is a whitespace-oriented language, it is often not possible for code indentation to follow that convention.</p> - -<h2 id="whitespace-in-generated-templates">Whitespace in Generated Templates</h2> - -<p>It is preferable to keep the amount of whitespace in generated templates to -a minimum. In particular, numerous blank lines should not appear adjacent to each -other. But occasional empty lines (particularly between logical sections) is -fine.</p> - -<p>This is best:</p> - -<pre><code class="language-yaml">apiVersion: batch/v1 -kind: Job -metadata: - name: example - labels: - first: first - second: second -</code></pre> - -<p>This is okay:</p> - -<pre><code class="language-yaml">apiVersion: batch/v1 -kind: Job - -metadata: - name: example - - labels: - first: first - second: second - -</code></pre> - -<p>But this should be avoided:</p> - -<pre><code class="language-yaml">apiVersion: batch/v1 -kind: Job - -metadata: - name: example - - - - - - labels: - first: first - - second: second - -</code></pre> - -<h2 id="comments-yaml-comments-vs-template-comments">Comments (YAML Comments vs. Template Comments)</h2> - -<p>Both YAML and Helm Templates have comment markers.</p> - -<p>YAML comments:</p> - -<pre><code class="language-yaml"># This is a comment -type: sprocket -</code></pre> - -<p>Template Comments:</p> - -<pre><code class="language-yaml">{{- /* -This is a comment. -*/ -}} -type: frobnitz -</code></pre> - -<p>Template comments should be used when documenting features of a template, such as explaining a defined template:</p> - -<pre><code class="language-yaml">{{- /* -mychart.shortname provides a 6 char truncated version of the release name. -*/ }} -{{ define &quot;mychart.shortname&quot; -}} -{{ .Release.Name | trunc 6 }} -{{- end -}} - -</code></pre> - -<p>Inside of templates, YAML comments may be used when it is useful for Helm users to (possibly) see the comments during debugging.</p> - -<pre><code># This may cause problems if the value is more than 100Gi -memory: {{ .Values.maxMem | quote }} -</code></pre> - -<p>The comment above is visible when the user runs <code>helm install --debug</code>, while -comments specified in <code>{{- /* */ -}}</code> sections are not.</p> - -<h2 id="use-of-json-in-templates-and-template-output">Use of JSON in Templates and Template Output</h2> - -<p>YAML is a superset of JSON. In some cases, using a JSON syntax can be more -readable than other YAML representations.</p> - -<p>For example, this YAML is closer to the normal YAML method of expressing lists:</p> - -<pre><code class="language-yaml">arguments: - - &quot;--dirname&quot; - - &quot;/foo&quot; -</code></pre> - -<p>But it is easier to read when collapsed into a JSON list style:</p> - -<pre><code class="language-yaml">arguments: [&quot;--dirname&quot;, &quot;/foo&quot;] -</code></pre> - -<p>Using JSON for increased legibility is good. However, JSON syntax should not -be used for representing more complex constructs.</p> - -<p>When dealing with pure JSON embedded inside of YAML (such as init container -configuration), it is of course appropriate to use the JSON format.</p> - - - - - - https://docs.helm.sh/chart_best_practices/third_party_resources/ - Mon, 01 Jan 0001 00:00:00 UTC - https://docs.helm.sh/chart_best_practices/third_party_resources/ - - -<h1 id="third-party-resources">Third Party Resources</h1> - -<p>This section of the Best Practices Guide deals with creating and using Third Party Resource -objects.</p> - -<p>When working with Third Party Resources (TPRs), it is important to distinguish -two different pieces:</p> - -<ul> -<li>There is a declaration of a TPR. This is the YAML file that has the kind <code>ThirdPartyResource</code></li> -<li>Then there are resources that <em>use</em> the TPR. Say a TPR defines <code>foo.example.com/v1</code>. Any resource -that has <code>apiVersion: example.com/v1</code> and kind <code>Foo</code> is a resource that uses the -TPR.</li> -</ul> - -<h2 id="install-a-tpr-declaration-before-using-the-resource">Install a TPR Declaration Before Using the Resource</h2> - -<p>Helm is optimized to load as many resources into Kubernetes as fast as possible. -By design, Kubernetes can take an entire set of manifests and bring them all -online (this is called the reconciliation loop).</p> - -<p>But there&rsquo;s a difference with TPRs.</p> - -<p>For a TPR, the declaration must be registered before any resources of that TPRs -kind(s) can be used. And the registration process sometimes takes a few seconds.</p> - -<h3 id="method-1-separate-charts">Method 1: Separate Charts</h3> - -<p>One way to do this is to put the TPR definition in one chart, and then put any -resources that use that TPR in <em>another</em> chart.</p> - -<p>In this method, each chart must be installed separately.</p> - -<h3 id="method-2-pre-install-hooks">Method 2: Pre-install Hooks</h3> - -<p>To package the two together, add a <code>pre-install</code> hook to the TPR definition so -that it is fully installed before the rest of the chart is executed.</p> - -<p>Note that if you create the TPR with a <code>pre-install</code> hook, that TPR definition -will not be deleted when <code>helm delete</code> is run.</p> - - - - - - https://docs.helm.sh/chart_best_practices/values/ - Mon, 01 Jan 0001 00:00:00 UTC - https://docs.helm.sh/chart_best_practices/values/ - - -<h1 id="values">Values</h1> - -<p>This part of the best practices guide covers using values. In this part of the -guide, we provide recommendations on how you should structure and use your -values, with focus on designing a chart&rsquo;s <code>values.yaml</code> file.</p> - -<h2 id="naming-conventions">Naming Conventions</h2> - -<p>Variables names should begin with a lowercase letter, and words should be -separated with camelcase:</p> - -<p>Correct:</p> - -<pre><code class="language-yaml">chicken: true -chickenNoodleSoup: true -</code></pre> - -<p>Incorrect:</p> - -<pre><code class="language-yaml">Chicken: true # initial caps may conflict with built-ins -chicken-noodle-soup: true # do not use hyphens in the name -</code></pre> - -<p>Note that all of Helm&rsquo;s built-in variables begin with an uppercase letter to -easily distinguish them from user-defined values: <code>.Release.Name</code>, -<code>.Capabilities.KubeVersion</code>.</p> - -<h2 id="flat-or-nested-values">Flat or Nested Values</h2> - -<p>YAML is a flexible format, and values may be nested deeply or flattened.</p> - -<p>Nested:</p> - -<pre><code class="language-yaml">server: - name: nginx - port: 80 -</code></pre> - -<p>Flat:</p> - -<pre><code class="language-yaml">serverName: nginx -serverPort: 80 -</code></pre> - -<p>In most cases, flat should be favored over nested. The reason for this is that -it is simpler for template developers and users.</p> - -<p>For optimal safety, a nested value must be checked at every level:</p> - -<pre><code>{{ if .Values.server }} - {{ default &quot;none&quot; .Values.server.name }} -{{ end }} -</code></pre> - -<p>For every layer of nesting, an existence check must be done. But for flat -configuration, such checks can be skipped, making the template easier to read -and use.</p> - -<pre><code>{{ default &quot;none&quot; .Values.serverName }} -</code></pre> - -<p>When there are a large number of related variables, and at least one of them -is non-optional, nested values may be used to improve readability.</p> - -<h2 id="make-types-clear">Make Types Clear</h2> - -<p>YAML&rsquo;s type coercion rules are sometimes counterintuitive. For example, -<code>foo: false</code> is not the same as <code>foo: &quot;false&quot;</code>. Large integers like <code>foo: 12345678</code> -will get converted to scientific notation in some cases.</p> - -<p>The easiest way to avoid type conversion errors is to be explicit about strings, -and implicit about everything else. Or, in short, <em>quote all strings</em>.</p> - -<p>Often, to avoid the integer casting issues, it is advantageous to store your -integers as strings as well, and use <code>{{ int $value }}</code> in the template to convert -from a string back to an integer.</p> - -<p>In most cases, explicit type tags are respected, so <code>foo: !!string 1234</code> should -treat <code>1234</code> as a string. <em>However</em>, the YAML parser consumes tags, so the type -data is lost after one parse.</p> - -<h2 id="consider-how-users-will-use-your-values">Consider How Users Will Use Your Values</h2> - -<p>There are three potential sources of values:</p> - -<ul> -<li>A chart&rsquo;s <code>values.yaml</code> file</li> -<li>A values file supplied by <code>helm install -f</code> or <code>helm upgrade -f</code></li> -<li>The values passed to a <code>--set</code> flag on <code>helm install</code> or <code>helm upgrade</code></li> -</ul> - -<p>When designing the structure of your values, keep in mind that users of your -chart may want to override them via either the <code>-f</code> flag or with the <code>--set</code> -option.</p> - -<p>Since <code>--set</code> is more limited in expressiveness, the first guidelines for writing -your <code>values.yaml</code> file is <em>make it easy to override from <code>--set</code></em>.</p> - -<p>For this reason, it&rsquo;s often better to structure your values file using maps.</p> - -<p>Difficult to use with <code>--set</code>:</p> - -<pre><code class="language-yaml">servers: - - name: foo - port: 80 - - name: bar - port: 81 -</code></pre> - -<p>The above cannot be expressed with <code>--set</code> in Helm <code>&lt;=2.4</code>. In Helm 2.5, the -accessing the port on foo is <code>--set servers[0].port=80</code>. Not only is it harder -for the user to figure out, but it is prone to errors if at some later time the -order of the <code>servers</code> is changed.</p> - -<p>Easy to use:</p> - -<pre><code class="language-yaml">servers: - foo: - port: 80 - bar: - port: 81 -</code></pre> - -<p>Accessing foo&rsquo;s port is much more obvious: <code>--set servers.foo.port=80</code>.</p> - -<h2 id="document-values-yaml">Document &lsquo;values.yaml&rsquo;</h2> - -<p>Every defined property in &lsquo;values.yaml&rsquo; should be documented. The documentation string should begin with the name of the property that it describes, and then give at least a one-sentence description.</p> - -<p>Incorrect:</p> - -<pre><code># the host name for the webserver -serverHost = example -serverPort = 9191 -</code></pre> - -<p>Correct:</p> - -<pre><code># serverHost is the host name for the webserver -serverHost = example -# serverPort is the HTTP listener port for the webserver -serverPort = 9191 - -</code></pre> - -<p>Beginning each comment with the name of the parameter it documents makes it easy to grep out documentation, and will enable documentation tools to reliably correlate doc strings with the parameters they describe.</p> - - - - - diff --git a/docs.helm.sh/rootfs/public/chart_best_practices/labels/index.html b/docs.helm.sh/rootfs/public/chart_best_practices/labels/index.html deleted file mode 100644 index 1ff0fc7d61..0000000000 --- a/docs.helm.sh/rootfs/public/chart_best_practices/labels/index.html +++ /dev/null @@ -1,1391 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

Labels and Annotations

- -

This part of the Best Practices Guide discusses the best practices for using -labels and annotations in your chart.

- -

Is it a Label or an Annotation?

- -

An item of metadata should be a label under the following conditions:

- -
    -
  • It is used by Kubernetes to identify this resource
  • -
  • It is useful to expose to operators for the purpose of querying the system.
  • -
- -

For example, we suggest using chart: NAME-VERSION as a label so that operators -can conveniently find all of the instances of a particular chart to use.

- -

If an item of metadata is not used for querying, it should be set as an annotation -instead.

- -

Helm hooks are always annotations.

- -

Standard Labels

- -

The following table defines common labels that Helm charts use. Helm itself never requires that a particular label be present. Labels that are marked REC -are recommended, and should be placed onto a chart for global consistency. Those marked OPT are optional. These are idiomatic or commonly in use, but are not relied upon frequently for operational purposes.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameStatusDescription
heritageRECThis should always be set to {{ .Release.Service }}. It is for finding all things managed by Tiller.
releaseRECThis should be the {{ .Release.Name }}.
chartRECThis should be the chart name and version: {{ .Chart.Name }}-{{ .Chart.Version \| replace "+" "_" }}.
appRECThis should be the app name, reflecting the entire app. Usually {{ template "name" . }} is used for this. This is used by many Kubernetes manifests, and is not Helm-specific.
componentOPTThis is a common label for marking the different roles that pieces may play in an application. For example, component: frontend.
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/chart_best_practices/pods/index.html b/docs.helm.sh/rootfs/public/chart_best_practices/pods/index.html deleted file mode 100644 index 4159326b30..0000000000 --- a/docs.helm.sh/rootfs/public/chart_best_practices/pods/index.html +++ /dev/null @@ -1,1385 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

Pods and PodTemplates

- -

This part of the Best Practices Guide discusses formatting the Pod and PodTemplate -portions in chart manifests.

- -

The following (non-exhaustive) list of resources use PodTemplates:

- -
    -
  • Deployment
  • -
  • ReplicationController
  • -
  • ReplicaSet
  • -
  • DaemonSet
  • -
  • StatefulSet
  • -
- -

Images

- -

A container image should use a fixed tag or the SHA of the image. It should not use the tags latest, head, canary, or other tags that are designed to be “floating”.

- -

Images may be defined in the values.yaml file to make it easy to swap out images.

- -
image: {{ .Values.redisImage | quote }}
-
- -

An image and a tag may be defined in values.yaml as two separate fields:

- -
image: "{{ .Values.redisImage }}:{{ .Values.redisTag }}"
-
- -

ImagePullPolicy

- -

helm create sets the imagePullPolicy to IfNotPresent by default by doing the following in your deployment.yaml:

- -
imagePullPolicy: {{ .Values.image.pullPolicy }}
-
- -

And values.yaml:

- -
pullPolicy: IfNotPresent
-
- -

Similarly, Kubernetes defaults the imagePullPolicy to IfNotPresent if it is not defined at all. If you want a value other than IfNotPresent, simply update the value in values.yaml to your desired value.

- -

PodTemplates Should Declare Selectors

- -

All PodTemplate sections should specify a selector. For example:

- -
selector:
-  matchLabels:
-      app: MyName
-template:
-  metadata:
-    labels:
-      app: MyName
-
- -

This is a good practice because it makes the relationship between the set and -the pod.

- -

But this is even more important for sets like Deployment. -Without this, the entire set of labels is used to select matching pods, and -this will break if you use labels that change, like version or release date.

- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/chart_best_practices/rbac/index.html b/docs.helm.sh/rootfs/public/chart_best_practices/rbac/index.html deleted file mode 100644 index 51e2ed139c..0000000000 --- a/docs.helm.sh/rootfs/public/chart_best_practices/rbac/index.html +++ /dev/null @@ -1,1385 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

Role-Based Access Control

- -

This part of the Best Practices Guide discusses the creation and formatting of RBAC resources in chart manifests.

- -

RBAC resources are:

- -
    -
  • ServiceAccount (namespaced)
  • -
  • Role (namespaced)
  • -
  • ClusterRole
  • -
  • RoleBinding (namespaced)
  • -
  • ClusterRoleBinding
  • -
- -

YAML Configuration

- -

RBAC and ServiceAccount configuration should happen under separate keys. They are separate things. Splitting these two concepts out in the YAML disambiguates them and make this clearer.

- -
rbac:
-  # Specifies whether RBAC resources should be created
-  create: true
-
-serviceAccount:
-  # Specifies whether a ServiceAccount should be created
-  create: true
-  # The name of the ServiceAccount to use.
-  # If not set and create is true, a name is generated using the fullname template
-  name:
-
- -

This structure can be extended for more complex charts that require multiple ServiceAccounts.

- -
serviceAccounts:
-  client:
-    create: true
-    name:
-  server: 
-    create: true
-    name:
-
- -

RBAC Resources Should be Created by Default

- -

rbac.create should be a boolean value controlling whether RBAC resources are created. The default should be true. Users who wish to manage RBAC access controls themselves can set this value to false (in which case see below).

- -

Using RBAC Resources

- -

serviceAccount.name should set to the name of the ServiceAccount to be used by access-controlled resources created by the chart. If serviceAccount.create is true, then a ServiceAccount with this name should be created. If the name is not set, then a name is generated using the fullname template, If serviceAccount.create is false, then it should not be created, but it should still be associated with the same resources so that manually-created RBAC resources created later that reference it will function correctly. If serviceAccount.create is false and the name is not specified, then the default ServiceAccount is used.

- -

The following helper template should be used for the ServiceAccount.

- -
{{/*
-Create the name of the service account to use
-*/}}
-{{- define "mychart.serviceAccountName" -}}
-{{- if .Values.serviceAccount.create -}}
-    {{ default (include "mychart.fullname" .) .Values.serviceAccount.name }}
-{{- else -}}
-    {{ default "default" .Values.serviceAccount.name }}
-{{- end -}}
-{{- end -}}
-
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/chart_best_practices/readme/index.html b/docs.helm.sh/rootfs/public/chart_best_practices/readme/index.html deleted file mode 100644 index add296623e..0000000000 --- a/docs.helm.sh/rootfs/public/chart_best_practices/readme/index.html +++ /dev/null @@ -1,1348 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

The Chart Best Practices Guide

- -

This guide covers the Helm Team’s considered best practices for creating charts. -It focuses on how charts should be structured.

- -

We focus primarily on best practices for charts that may be publicly deployed. -We know that many charts are for internal-use only, and authors of such charts -may find that their internal interests override our suggestions here.

- -

Table of Contents

- - - -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/chart_best_practices/requirements/index.html b/docs.helm.sh/rootfs/public/chart_best_practices/requirements/index.html deleted file mode 100644 index d9e539e117..0000000000 --- a/docs.helm.sh/rootfs/public/chart_best_practices/requirements/index.html +++ /dev/null @@ -1,1367 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

Requirements Files

- -

This section of the guide covers best practices for requirements.yaml files.

- -

Versions

- -

Where possible, use version ranges instead of pinning to an exact version. The suggested default is to use a patch-level version match:

- -
version: ~1.2.3
-
- -

This will match version 1.2.3 and any patches to that release. In other words, ~1.2.3 is equivalent to >= 1.2.3, < 1.3.0

- -

For the complete version matching syntax, please see the semver documentation

- -

Repository URLs

- -

Where possible, use https:// repository URLs, followed by http:// URLs.

- -

If the repository has been added to the repository index file, the repository name can be used as an alias of URL. Use alias: or @ followed by repository names.

- -

File URLs (file://...) are considered a “special case” for charts that are assembled by a fixed deployment pipeline. Charts that use file:// in a requirements.yaml file are not allowed in the official Helm repository.

- -

Conditions and Tags

- -

Conditions or tags should be added to any dependencies that are optional.

- -

The preferred form of a condition is:

- -
condition: somechart.enabled
-
- -

Where somechart is the chart name of the dependency.

- -

When multiple subcharts (dependencies) together provide an optional or swappable feature, those charts should share the same tags.

- -

For example, if both nginx and memcached together provided performance optimizations for the main app in the chart, and were required to both be present when that feature is enabled, then they might both have a -tags section like this:

- -
tags:
-  - webaccelerator
-
- -

This allows a user to turn that feature on and off with one tag.

- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/chart_best_practices/templates/index.html b/docs.helm.sh/rootfs/public/chart_best_practices/templates/index.html deleted file mode 100644 index c0df3191fe..0000000000 --- a/docs.helm.sh/rootfs/public/chart_best_practices/templates/index.html +++ /dev/null @@ -1,1513 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

Templates

- -

This part of the Best Practices Guide focuses on templates.

- -

Structure of templates/

- -

The templates directory should be structured as follows:

- -
    -
  • Template files should have the extension .yaml if they produce YAML output. The -extension .tpl may be used for template files that produce no formatted content.
  • -
  • Template file names should use dashed notation (my-example-configmap.yaml), not camelcase.
  • -
  • Each resource definition should be in its own template file.
  • -
  • Template file names should reflect the resource kind in the name. e.g. foo-pod.yaml, -bar-svc.yaml
  • -
- -

Names of Defined Templates

- -

Defined templates (templates created inside a {{ define }} directive) are -globally accessible. That means that a chart and all of its subcharts will have -access to all of the templates created with {{ define }}.

- -

For that reason, all defined template names should be namespaced.

- -

Correct:

- -
{{- define "nginx.fullname" }}
-{{/* ... */}}
-{{ end -}}
-
- -

Incorrect:

- -
{{- define "fullname" -}}
-{{/* ... */}}
-{{ end -}}
-
- -

It is highly recommended that new charts are created via helm create command as the template names are automatically defined as per this best practice.

- -

Formatting Templates

- -

Templates should be indented using two spaces (never tabs).

- -

Template directives should have whitespace after the opening braces and before the -closing braces:

- -

Correct:

- -
{{ .foo }}
-{{ print "foo" }}
-{{- print "bar" -}}
-
- -

Incorrect:

- -
{{.foo}}
-{{print "foo"}}
-{{-print "bar"-}}
-
- -

Templates should chomp whitespace where possible:

- -
foo:
-  {{- range .Values.items }}
-  {{ . }}
-  {{ end -}}
-
- -

Blocks (such as control structures) may be indented to indicate flow of the template code.

- -
{{ if $foo -}}
-  {{- with .Bar }}Hello{{ end -}}
-{{- end -}} 
-
- -

However, since YAML is a whitespace-oriented language, it is often not possible for code indentation to follow that convention.

- -

Whitespace in Generated Templates

- -

It is preferable to keep the amount of whitespace in generated templates to -a minimum. In particular, numerous blank lines should not appear adjacent to each -other. But occasional empty lines (particularly between logical sections) is -fine.

- -

This is best:

- -
apiVersion: batch/v1
-kind: Job
-metadata:
-  name: example
-  labels:
-    first: first
-    second: second
-
- -

This is okay:

- -
apiVersion: batch/v1
-kind: Job
-
-metadata:
-  name: example
-
-  labels:
-    first: first
-    second: second
-
-
- -

But this should be avoided:

- -
apiVersion: batch/v1
-kind: Job
-
-metadata:
-  name: example
-
-
-
-
-
-  labels:
-    first: first
-
-    second: second
-
-
- -

Comments (YAML Comments vs. Template Comments)

- -

Both YAML and Helm Templates have comment markers.

- -

YAML comments:

- -
# This is a comment
-type: sprocket
-
- -

Template Comments:

- -
{{- /*
-This is a comment.
-*/ -}}
-type: frobnitz
-
- -

Template comments should be used when documenting features of a template, such as explaining a defined template:

- -
{{- /*
-mychart.shortname provides a 6 char truncated version of the release name.
-*/ }}
-{{ define "mychart.shortname" -}}
-{{ .Release.Name | trunc 6 }}
-{{- end -}}
-
-
- -

Inside of templates, YAML comments may be used when it is useful for Helm users to (possibly) see the comments during debugging.

- -
# This may cause problems if the value is more than 100Gi
-memory: {{ .Values.maxMem | quote }}
-
- -

The comment above is visible when the user runs helm install --debug, while -comments specified in {{- /* */ -}} sections are not.

- -

Use of JSON in Templates and Template Output

- -

YAML is a superset of JSON. In some cases, using a JSON syntax can be more -readable than other YAML representations.

- -

For example, this YAML is closer to the normal YAML method of expressing lists:

- -
arguments: 
-  - "--dirname"
-  - "/foo"
-
- -

But it is easier to read when collapsed into a JSON list style:

- -
arguments: ["--dirname", "/foo"]
-
- -

Using JSON for increased legibility is good. However, JSON syntax should not -be used for representing more complex constructs.

- -

When dealing with pure JSON embedded inside of YAML (such as init container -configuration), it is of course appropriate to use the JSON format.

- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/chart_best_practices/third_party_resources/index.html b/docs.helm.sh/rootfs/public/chart_best_practices/third_party_resources/index.html deleted file mode 100644 index fdfed42805..0000000000 --- a/docs.helm.sh/rootfs/public/chart_best_practices/third_party_resources/index.html +++ /dev/null @@ -1,1363 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

Third Party Resources

- -

This section of the Best Practices Guide deals with creating and using Third Party Resource -objects.

- -

When working with Third Party Resources (TPRs), it is important to distinguish -two different pieces:

- -
    -
  • There is a declaration of a TPR. This is the YAML file that has the kind ThirdPartyResource
  • -
  • Then there are resources that use the TPR. Say a TPR defines foo.example.com/v1. Any resource -that has apiVersion: example.com/v1 and kind Foo is a resource that uses the -TPR.
  • -
- -

Install a TPR Declaration Before Using the Resource

- -

Helm is optimized to load as many resources into Kubernetes as fast as possible. -By design, Kubernetes can take an entire set of manifests and bring them all -online (this is called the reconciliation loop).

- -

But there’s a difference with TPRs.

- -

For a TPR, the declaration must be registered before any resources of that TPRs -kind(s) can be used. And the registration process sometimes takes a few seconds.

- -

Method 1: Separate Charts

- -

One way to do this is to put the TPR definition in one chart, and then put any -resources that use that TPR in another chart.

- -

In this method, each chart must be installed separately.

- -

Method 2: Pre-install Hooks

- -

To package the two together, add a pre-install hook to the TPR definition so -that it is fully installed before the rest of the chart is executed.

- -

Note that if you create the TPR with a pre-install hook, that TPR definition -will not be deleted when helm delete is run.

- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/chart_best_practices/values/index.html b/docs.helm.sh/rootfs/public/chart_best_practices/values/index.html deleted file mode 100644 index 99420156a4..0000000000 --- a/docs.helm.sh/rootfs/public/chart_best_practices/values/index.html +++ /dev/null @@ -1,1469 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

Values

- -

This part of the best practices guide covers using values. In this part of the -guide, we provide recommendations on how you should structure and use your -values, with focus on designing a chart’s values.yaml file.

- -

Naming Conventions

- -

Variables names should begin with a lowercase letter, and words should be -separated with camelcase:

- -

Correct:

- -
chicken: true
-chickenNoodleSoup: true
-
- -

Incorrect:

- -
Chicken: true  # initial caps may conflict with built-ins
-chicken-noodle-soup: true # do not use hyphens in the name
-
- -

Note that all of Helm’s built-in variables begin with an uppercase letter to -easily distinguish them from user-defined values: .Release.Name, -.Capabilities.KubeVersion.

- -

Flat or Nested Values

- -

YAML is a flexible format, and values may be nested deeply or flattened.

- -

Nested:

- -
server:
-  name: nginx
-  port: 80
-
- -

Flat:

- -
serverName: nginx
-serverPort: 80
-
- -

In most cases, flat should be favored over nested. The reason for this is that -it is simpler for template developers and users.

- -

For optimal safety, a nested value must be checked at every level:

- -
{{ if .Values.server }}
-  {{ default "none" .Values.server.name }}
-{{ end }}
-
- -

For every layer of nesting, an existence check must be done. But for flat -configuration, such checks can be skipped, making the template easier to read -and use.

- -
{{ default "none" .Values.serverName }}
-
- -

When there are a large number of related variables, and at least one of them -is non-optional, nested values may be used to improve readability.

- -

Make Types Clear

- -

YAML’s type coercion rules are sometimes counterintuitive. For example, -foo: false is not the same as foo: "false". Large integers like foo: 12345678 -will get converted to scientific notation in some cases.

- -

The easiest way to avoid type conversion errors is to be explicit about strings, -and implicit about everything else. Or, in short, quote all strings.

- -

Often, to avoid the integer casting issues, it is advantageous to store your -integers as strings as well, and use {{ int $value }} in the template to convert -from a string back to an integer.

- -

In most cases, explicit type tags are respected, so foo: !!string 1234 should -treat 1234 as a string. However, the YAML parser consumes tags, so the type -data is lost after one parse.

- -

Consider How Users Will Use Your Values

- -

There are three potential sources of values:

- -
    -
  • A chart’s values.yaml file
  • -
  • A values file supplied by helm install -f or helm upgrade -f
  • -
  • The values passed to a --set flag on helm install or helm upgrade
  • -
- -

When designing the structure of your values, keep in mind that users of your -chart may want to override them via either the -f flag or with the --set -option.

- -

Since --set is more limited in expressiveness, the first guidelines for writing -your values.yaml file is make it easy to override from --set.

- -

For this reason, it’s often better to structure your values file using maps.

- -

Difficult to use with --set:

- -
servers:
-  - name: foo
-    port: 80
-  - name: bar
-    port: 81
-
- -

The above cannot be expressed with --set in Helm <=2.4. In Helm 2.5, the -accessing the port on foo is --set servers[0].port=80. Not only is it harder -for the user to figure out, but it is prone to errors if at some later time the -order of the servers is changed.

- -

Easy to use:

- -
servers:
-  foo:
-    port: 80
-  bar:
-    port: 81
-
- -

Accessing foo’s port is much more obvious: --set servers.foo.port=80.

- -

Document ‘values.yaml’

- -

Every defined property in ‘values.yaml’ should be documented. The documentation string should begin with the name of the property that it describes, and then give at least a one-sentence description.

- -

Incorrect:

- -
# the host name for the webserver
-serverHost = example
-serverPort = 9191
-
- -

Correct:

- -
# serverHost is the host name for the webserver
-serverHost = example
-# serverPort is the HTTP listener port for the webserver
-serverPort = 9191
-
-
- -

Beginning each comment with the name of the parameter it documents makes it easy to grep out documentation, and will enable documentation tools to reliably correlate doc strings with the parameters they describe.

- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/chart_repository/index.html b/docs.helm.sh/rootfs/public/chart_repository/index.html deleted file mode 100644 index 996a53131b..0000000000 --- a/docs.helm.sh/rootfs/public/chart_repository/index.html +++ /dev/null @@ -1,1609 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

The Chart Repository Guide

- -

This section explains how to create and work with Helm chart repositories. At a -high level, a chart repository is a location where packaged charts can be -stored and shared.

- -

The official chart repository is maintained by the -Kubernetes Charts, and we welcome -participation. But Helm also makes it easy to create and run your own chart -repository. This guide explains how to do so.

- -

Prerequisites

- - - -

Create a chart repository

- -

A chart repository is an HTTP server that houses an index.yaml file and -optionally some packaged charts. When you’re ready to share your charts, the -preferred way to do so is by uploading them to a chart repository.

- -

Note: For Helm 2.0.0, chart repositories do not have any intrinsic -authentication. There is an issue tracking progress -in GitHub.

- -

Because a chart repository can be any HTTP server that can serve YAML and tar -files and can answer GET requests, you have a plethora of options when it comes -down to hosting your own chart repository. For example, you can use a Google -Cloud Storage (GCS) bucket, Amazon S3 bucket, Github Pages, or even create your -own web server.

- -

The chart repository structure

- -

A chart repository consists of packaged charts and a special file called -index.yaml which contains an index of all of the charts in the repository. -Frequently, the charts that index.yaml describes are also hosted on the same -server, as are the provenance files.

- -

For example, the layout of the repository https://example.com/charts might -look like this:

- -
charts/
-  |
-  |- index.yaml
-  |
-  |- alpine-0.1.2.tgz
-  |
-  |- alpine-0.1.2.tgz.prov
-
- -

In this case, the index file would contain information about one chart, the Alpine -chart, and provide the download URL https://example.com/charts/alpine-0.1.2.tgz -for that chart.

- -

It is not required that a chart package be located on the same server as the -index.yaml file. However, doing so is often the easiest.

- -

The index file

- -

The index file is a yaml file called index.yaml. It -contains some metadata about the package, including the contents of a -chart’s Chart.yaml file. A valid chart repository must have an index file. The -index file contains information about each chart in the chart repository. The -helm repo index command will generate an index file based on a given local -directory that contains packaged charts.

- -

This is an example of an index file:

- -
apiVersion: v1
-entries:
-  alpine:
-    - created: 2016-10-06T16:23:20.499814565-06:00
-      description: Deploy a basic Alpine Linux pod
-      digest: 99c76e403d752c84ead610644d4b1c2f2b453a74b921f422b9dcb8a7c8b559cd
-      home: https://k8s.io/helm
-      name: alpine
-      sources:
-      - https://github.com/kubernetes/helm
-      urls:
-      - https://technosophos.github.io/tscharts/alpine-0.2.0.tgz
-      version: 0.2.0
-    - created: 2016-10-06T16:23:20.499543808-06:00
-      description: Deploy a basic Alpine Linux pod
-      digest: 515c58e5f79d8b2913a10cb400ebb6fa9c77fe813287afbacf1a0b897cd78727
-      home: https://k8s.io/helm
-      name: alpine
-      sources:
-      - https://github.com/kubernetes/helm
-      urls:
-      - https://technosophos.github.io/tscharts/alpine-0.1.0.tgz
-      version: 0.1.0
-  nginx:
-    - created: 2016-10-06T16:23:20.499543808-06:00
-      description: Create a basic nginx HTTP server
-      digest: aaff4545f79d8b2913a10cb400ebb6fa9c77fe813287afbacf1a0b897cdffffff
-      home: https://k8s.io/helm
-      name: nginx
-      sources:
-      - https://github.com/kubernetes/charts
-      urls:
-      - https://technosophos.github.io/tscharts/nginx-1.1.0.tgz
-      version: 1.1.0
-generated: 2016-10-06T16:23:20.499029981-06:00
-
- -

A generated index and packages can be served from a basic webserver. You can test -things out locally with the helm serve command, which starts a local server.

- -
$ helm serve --repo-path ./charts
-Regenerating index. This may take a moment.
-Now serving you on 127.0.0.1:8879
-
- -

The above starts a local webserver, serving the charts it finds in ./charts. The -serve command will automatically generate an index.yaml file for you during -startup.

- -

Hosting Chart Repositories

- -

This part shows several ways to serve a chart repository.

- -

Google Cloud Storage

- -

The first step is to create your GCS bucket. We’ll call ours -fantastic-charts.

- -

Create a GCS Bucket

- -

Next, make your bucket public by editing the bucket permissions.

- -

Edit Permissions

- -

Insert this line item to make your bucket public:

- -

Make Bucket Public

- -

Congratulations, now you have an empty GCS bucket ready to serve charts!

- -

You may upload your chart repository using the Google Cloud Storage command line -tool, or using the GCS web UI. This is the technique the official Kubernetes -Charts repository hosts its charts, so you may want to take a -peek at that project if you get stuck.

- -

Note: A public GCS bucket can be accessed via simple HTTPS at this address -https://bucket-name.storage.googleapis.com/.

- -

Github Pages example

- -

In a similar way you can create charts repository using GitHub Pages.

- -

GitHub allows you to serve static web pages in two different ways:

- -
    -
  • By configuring a project to serve the contents of its docs/ directory
  • -
  • By configuring a project to serve a particular branch
  • -
- -

We’ll take the second approach, though the first is just as easy.

- -

The first step will be to create your gh-pages branch. You can do that -locally as.

- -
$ git checkout -b gh-pages
-
- -

Or via web browser using Branch button on your Github repository:

- -

Create Github Pages branch

- -

Next, you’ll want to make sure your gh-pages branch is set as Github Pages, -click on your repo Settings and scroll down to Github pages section and -set as per below:

- -

Create Github Pages branch

- -

By default Source usually gets set to gh-pages branch. If this is not set by default, then select it.

- -

You can use a custom domain there if you wish so.

- -

And check that Enforce HTTPS is ticked, so the HTTPS will be used when -charts are served.

- -

In such setup you can use master branch to store your charts code, and -gh-pages branch as charts repository, e.g.: -https://USERNAME.github.io/REPONAME. The demonstration TS Charts -repository is accessible at https://technosophos.github.io/tscharts/.

- -

Ordinary web servers

- -

To configure an ordinary web server to serve Helm charts, you merely need to do -the following:

- -
    -
  • Put your index and charts in a directory that the server can serve
  • -
  • Make sure the index.yaml file can be accessed with no authentication requirement
  • -
  • Make sure yaml files are served with the correct content type (text/yaml or -text/x-yaml)
  • -
- -

For example, if you want to serve your charts out of $WEBROOT/charts, make sure -there is a charts/ directory in your web root, and put the index file and -charts inside of that folder.

- -

Managing Chart Repositories

- -

Now that you have a chart repository, the last part of this guide explains how -to maintain charts in that repository.

- -

Store charts in your chart repository

- -

Now that you have a chart repository, let’s upload a chart and an index file to -the repository. Charts in a chart repository must be packaged -(helm package chart-name/) and versioned correctly (following -SemVer 2 guidelines).

- -

These next steps compose an example workflow, but you are welcome to use -whatever workflow you fancy for storing and updating charts in your chart -repository.

- -

Once you have a packaged chart ready, create a new directory, and move your -packaged chart to that directory.

- -
$ helm package docs/examples/alpine/
-$ mkdir fantastic-charts
-$ mv alpine-0.1.0.tgz fantastic-charts/
-$ helm repo index fantastic-charts --url https://fantastic-charts.storage.googleapis.com
-
- -

The last command takes the path of the local directory that you just created and -the URL of your remote chart repository and composes an index.yaml file inside the -given directory path.

- -

Now you can upload the chart and the index file to your chart repository using -a sync tool or manually. If you’re using Google Cloud Storage, check out this -example workflow using the gsutil client. For -GitHub, you can simply put the charts in the appropriate destination branch.

- -

Add new charts to an existing repository

- -

Each time you want to add a new chart to your repository, you must regenerate -the index. The helm repo index command will completely rebuild the index.yaml -file from scratch, including only the charts that it finds locally.

- -

However, you can use the --merge flag to incrementally add new charts to an -existing index.yaml file (a great option when working with a remote repository -like GCS). Run helm repo index --help to learn more,

- -

Make sure that you upload both the revised index.yaml file and the chart. And -if you generated a provenance file, upload that too.

- -

Share your charts with others

- -

When you’re ready to share your charts, simply let someone know what the URL of -your repository is.

- -

From there, they will add the repository to their helm client via the helm -repo add [NAME] [URL] command with any name they would like to use to -reference the repository.

- -
$ helm repo add fantastic-charts https://fantastic-charts.storage.googleapis.com
-$ helm repo list
-fantastic-charts    https://fantastic-charts.storage.googleapis.com
-
- -

If the charts are backed by HTTP basic authentication, you can also supply the -username and password here:

- -
$ helm repo add fantastic-charts https://username:password@fantastic-charts.storage.googleapis.com
-$ helm repo list
-fantastic-charts    https://username:password@fantastic-charts.storage.googleapis.com
-
- -

Note: A repository will not be added if it does not contain a valid -index.yaml.

- -

After that, your users will be able to search through your charts. After you’ve updated -the repository, they can use the helm repo update command to get the latest -chart information.

- -

Under the hood, the helm repo add and helm repo update commands are -fetching the index.yaml file and storing them in the -$HELM_HOME/repository/cache/ directory. This is where the helm search -function finds information about charts.

- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/chart_repository_faq/index.html b/docs.helm.sh/rootfs/public/chart_repository_faq/index.html deleted file mode 100644 index 445614c759..0000000000 --- a/docs.helm.sh/rootfs/public/chart_repository_faq/index.html +++ /dev/null @@ -1,1340 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

Chart Repositories: Frequently Asked Questions

- -

This section tracks some of the more frequently encountered issues with using chart repositories.

- -

We’d love your help making this document better. To add, correct, or remove -information, file an issue or -send us a pull request.

- -

Fetching

- -

Q: Why do I get a unsupported protocol scheme "" error when trying to fetch a chart from my custom repo?

- -

A: (Helm < 2.5.0) This is likely caused by you creating your chart repo index without specifying the --url flag. -Try recreating your index.yaml file with a command like helm repo index --url http://my-repo/charts ., -and then re-uploading it to your custom charts repo.

- -

This behavior was changed in Helm 2.5.0.

- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/chart_repository_sync_example/index.html b/docs.helm.sh/rootfs/public/chart_repository_sync_example/index.html deleted file mode 100644 index 2c935d0023..0000000000 --- a/docs.helm.sh/rootfs/public/chart_repository_sync_example/index.html +++ /dev/null @@ -1,1405 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

Syncing Your Chart Repository

- -

Note: This example is specifically for a Google Cloud Storage (GCS) bucket which serves a chart repository.

- -

Prerequisites

- -
    -
  • Install the gsutil tool. We rely heavily on the gsutil rsync functionality
  • -
  • Be sure to have access to the helm binary
  • -
  • _Optional: We recommend you set object versioning on your GCS bucket in case you accidentally delete something._
  • -
- -

Set up a local chart repository directory

- -

Create a local directory like we did in the chart repository guide, and place your packaged charts in that directory.

- -

For example:

- -
$ mkdir fantastic-charts
-$ mv alpine-0.1.0.tgz fantastic-charts/
-
- -

Generate an updated index.yaml

- -

Use helm to generate an updated index.yaml file by passing in the directory path and the url of the remote repository to the helm repo index command like this:

- -
$ helm repo index fantastic-charts/ --url https://fantastic-charts.storage.googleapis.com
-
- -

This will generate an updated index.yaml file and place in the fantastic-charts/ directory.

- -

Sync your local and remote chart repositories

- -

Upload the contents of the directory to your GCS bucket by running scripts/sync-repo.sh and pass in the local directory name and the GCS bucket name.

- -

For example:

- -
$ pwd
-/Users/funuser/go/src/github.com/kubernetes/helm
-$ scripts/sync-repo.sh fantastic-charts/ fantastic-charts
-Getting ready to sync your local directory (fantastic-charts/) to a remote repository at gs://fantastic-charts
-Verifying Prerequisites....
-Thumbs up! Looks like you have gsutil. Let's continue.
-Building synchronization state...
-Starting synchronization
-Would copy file://fantastic-charts/alpine-0.1.0.tgz to gs://fantastic-charts/alpine-0.1.0.tgz
-Would copy file://fantastic-charts/index.yaml to gs://fantastic-charts/index.yaml
-Are you sure you would like to continue with these changes?? [y/N]} y
-Building synchronization state...
-Starting synchronization
-Copying file://fantastic-charts/alpine-0.1.0.tgz [Content-Type=application/x-tar]...
-Uploading   gs://fantastic-charts/alpine-0.1.0.tgz:              740 B/740 B
-Copying file://fantastic-charts/index.yaml [Content-Type=application/octet-stream]...
-Uploading   gs://fantastic-charts/index.yaml:                    347 B/347 B
-Congratulations your remote chart repository now matches the contents of fantastic-charts/
-
- -

Updating your chart repository

- -

You’ll want to keep a local copy of the contents of your chart repository or use gsutil rsync to copy the contents of your remote chart repository to a local directory.

- -

For example:

- -
$ gsutil rsync -d -n gs://bucket-name local-dir/    # the -n flag does a dry run
-Building synchronization state...
-Starting synchronization
-Would copy gs://bucket-name/alpine-0.1.0.tgz to file://local-dir/alpine-0.1.0.tgz
-Would copy gs://bucket-name/index.yaml to file://local-dir/index.yaml
-
-$ gsutil rsync -d gs://bucket-name local-dir/       # performs the copy actions
-Building synchronization state...
-Starting synchronization
-Copying gs://bucket-name/alpine-0.1.0.tgz...
-Downloading file://local-dir/alpine-0.1.0.tgz:                        740 B/740 B
-Copying gs://bucket-name/index.yaml...
-Downloading file://local-dir/index.yaml:                              346 B/346 B
-
- -

Helpful Links: -* Documentation on gsutil rsync -* The Chart Repository Guide -* Documentation on object versioning and concurrency control in Google Cloud Storage

- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/chart_template_guide/index.html b/docs.helm.sh/rootfs/public/chart_template_guide/index.html deleted file mode 100644 index 39162a16db..0000000000 --- a/docs.helm.sh/rootfs/public/chart_template_guide/index.html +++ /dev/null @@ -1,3464 +0,0 @@ - - - - - - - - - Chart Template Guide - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
- -
-
- -

The Chart Template Developer’s Guide

- -

This guide provides an introduction to Helm’s chart templates, with emphasis on -the template language.

- -

Templates generate manifest files, which are YAML-formatted resource descriptions -that Kubernetes can understand. We’ll look at how templates are structured, -how they can be used, how to write Go templates, and how to debug your work.

- -

This guide focuses on the following concepts:

- -
    -
  • The Helm template language
  • -
  • Using values
  • -
  • Techniques for working with templates
  • -
- -

This guide is oriented toward learning the ins and outs of the Helm template language. Other guides provide introductory material, examples, and best practices.

- -

Getting Started with a Chart Template

- -

In this section of the guide, we’ll create a chart and then add a first template. The chart we created here will be used throughout the rest of the guide.

- -

To get going, let’s take a brief look at a Helm chart.

- -

Charts

- -

As described in the Charts Guide, Helm charts are structured like -this:

- -
mychart/
-  Chart.yaml
-  values.yaml
-  charts/
-  templates/
-  ...
-
- -

The templates/ directory is for template files. When Tiller evaluates a chart, -it will send all of the files in the templates/ directory through the -template rendering engine. Tiller then collects the results of those templates -and sends them on to Kubernetes.

- -

The values.yaml file is also important to templates. This file contains the -default values for a chart. These values may be overridden by users during -helm install or helm upgrade.

- -

The Chart.yaml file contains a description of the chart. You can access it -from within a template. The charts/ directory may contain other charts (which -we call subcharts). Later in this guide we will see how those work when it -comes to template rendering.

- -

A Starter Chart

- -

For this guide, we’ll create a simple chart called mychart, and then we’ll -create some templates inside of the chart.

- -
$ helm create mychart
-Creating mychart
-
- -

From here on, we’ll be working in the mychart directory.

- -

A Quick Glimpse of mychart/templates/

- -

If you take a look at the mychart/templates/ directory, you’ll notice a few files -already there.

- -
    -
  • NOTES.txt: The “help text” for your chart. This will be displayed to your users -when they run helm install.
  • -
  • deployment.yaml: A basic manifest for creating a Kubernetes deployment
  • -
  • service.yaml: A basic manifest for creating a service endpoint for your deployment
  • -
  • _helpers.tpl: A place to put template helpers that you can re-use throughout the chart
  • -
- -

And what we’re going to do is… remove them all! That way we can work through our tutorial from scratch. We’ll actually create our own NOTES.txt and _helpers.tpl as we go.

- -
$ rm -rf mychart/templates/*.*
-
- -

When you’re writing production grade charts, having basic versions of these charts can be really useful. So in your day-to-day chart authoring, you probably won’t want to remove them.

- -

A First Template

- -

The first template we are going to create will be a ConfigMap. In Kubernetes, -a ConfigMap is simply a container for storing configuration data. Other things, -like pods, can access the data in a ConfigMap.

- -

Because ConfigMaps are basic resources, they make a great starting point for us.

- -

Let’s begin by creating a file called mychart/templates/configmap.yaml:

- -
apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: mychart-configmap
-data:
-  myvalue: "Hello World"
-
- -

TIP: Template names do not follow a rigid naming pattern. However, we recommend -using the suffix .yaml for YAML files and .tpl for helpers.

- -

The YAML file above is a bare-bones ConfigMap, having the minimal necessary fields. -In virtue of the fact that this file is in the templates/ directory, it will -be sent through the template engine.

- -

It is just fine to put a plain YAML file like this in the templates/ directory. -When Tiller reads this template, it will simply send it to Kubernetes as-is.

- -

With this simple template, we now have an installable chart. And we can install -it like this:

- -
$ helm install ./mychart
-NAME: full-coral
-LAST DEPLOYED: Tue Nov  1 17:36:01 2016
-NAMESPACE: default
-STATUS: DEPLOYED
-
-RESOURCES:
-==> v1/ConfigMap
-NAME                DATA      AGE
-mychart-configmap   1         1m
-
- -

In the output above, we can see that our ConfigMap was created. Using Helm, we -can retrieve the release and see the actual template that was loaded.

- -
$ helm get manifest full-coral
-
----
-# Source: mychart/templates/configmap.yaml
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: mychart-configmap
-data:
-  myvalue: "Hello World"
-
- -

The helm get manifest command takes a release name (full-coral) and prints -out all of the Kubernetes resources that were uploaded to the server. Each file -begins with --- to indicate the start of a YAML document, and then is followed -by an automatically generated comment line that tells us what template file -generated this YAML document.

- -

From there on, we can see that the YAML data is exactly what we put in our -configmap.yaml file.

- -

Now we can delete our release: helm delete full-coral.

- -

Adding a Simple Template Call

- -

Hard-coding the name: into a resource is usually considered to be bad practice. -Names should be unique to a release. So we might want to generate a name field -by inserting the release name.

- -

TIP: The name: field is limited to 63 characters because of limitations to -the DNS system. For that reason, release names are limited to 53 characters. -Kubernetes 1.3 and earlier limited to only 24 characters (thus 14 character names).

- -

Let’s alter configmap.yaml accordingly.

- -
apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: {{ .Release.Name }}-configmap
-data:
-  myvalue: "Hello World"
-
- -

The big change comes in the value of the name: field, which is now -{{ .Release.Name }}-configmap.

- -
-

A template directive is enclosed in {{ and }} blocks.

-
- -

The template directive {{ .Release.Name }} injects the release name into the template. The values that are passed into a template can be thought of as namespaced objects, where a dot (.) separates each namespaced element.

- -

The leading dot before Release indicates that we start with the top-most namespace for this scope (we’ll talk about scope in a bit). So we could read .Release.Name as “start at the top namespace, find the Release object, then look inside of it for an object called Name”.

- -

The Release object is one of the built-in objects for Helm, and we’ll cover it in more depth later. But for now, it is sufficient to say that this will display the release name that Tiller assigns to our release.

- -

Now when we install our resource, we’ll immediately see the result of using this template directive:

- -
$ helm install ./mychart
-NAME: clunky-serval
-LAST DEPLOYED: Tue Nov  1 17:45:37 2016
-NAMESPACE: default
-STATUS: DEPLOYED
-
-RESOURCES:
-==> v1/ConfigMap
-NAME                      DATA      AGE
-clunky-serval-configmap   1         1m
-
- -

Note that in the RESOURCES section, the name we see there is clunky-serval-configmap -instead of mychart-configmap.

- -

You can run helm get manifest clunky-serval to see the entire generated YAML.

- -

At this point, we’ve seen templates at their most basic: YAML files that have template directives embedded in {{ and }}. In the next part, we’ll take a deeper look into templates. But before moving on, there’s one quick trick that can make building templates faster: When you want to test the template rendering, but not actually install anything, you can use helm install --debug --dry-run ./mychart. This will send the chart to the Tiller server, which will render the templates. But instead of installing the chart, it will return the rendered template to you so you can see the output:

- -
$ helm install --debug --dry-run ./mychart
-SERVER: "localhost:44134"
-CHART PATH: /Users/mattbutcher/Code/Go/src/k8s.io/helm/_scratch/mychart
-NAME:   goodly-guppy
-TARGET NAMESPACE:   default
-CHART:  mychart 0.1.0
-MANIFEST:
----
-# Source: mychart/templates/configmap.yaml
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: goodly-guppy-configmap
-data:
-  myvalue: "Hello World"
-
-
- -

Using --dry-run will make it easier to test your code, but it won’t ensure that Kubernetes itself will accept the templates you generate. It’s best not to assume that your chart will install just because --dry-run works.

- -

In the next few sections, we’ll take the basic chart we defined here and explore the Helm template language in detail. And we’ll get started with built-in objects.

- -

Built-in Objects

- -

Objects are passed into a template from the template engine. And your code can pass objects around (we’ll see examples when we look at the with and range statements). There are even a few ways to create new objects within your templates, like with the tuple function we’ll see later.

- -

Objects can be simple, and have just one value. Or they can contain other objects or functions. For example. the Release object contains several objects (like Release.Name) and the Files object has a few functions.

- -

In the previous section, we use {{.Release.Name}} to insert the name of a release into a template. Release is one of the top-level objects that you can access in your templates.

- -
    -
  • Release: This object describes the release itself. It has several objects inside of it: - -
      -
    • Release.Name: The release name
    • -
    • Release.Time: The time of the release
    • -
    • Release.Namespace: The namespace to be released into (if the manifest doesn’t override)
    • -
    • Release.Service: The name of the releasing service (always Tiller).
    • -
    • Release.Revision: The revision number of this release. It begins at 1 and is incremented for each helm upgrade.
    • -
    • Release.IsUpgrade: This is set to true if the current operation is an upgrade or rollback.
    • -
    • Release.IsInstall: This is set to true if the current operation is an install.
    • -
  • -
  • Values: Values passed into the template from the values.yaml file and from user-supplied files. By default, Values is empty.
  • -
  • Chart: The contents of the Chart.yaml file. Any data in Chart.yaml will be accessible here. For example {{.Chart.Name}}-{{.Chart.Version}} will print out the mychart-0.1.0. - -
  • -
  • Files: This provides access to all non-special files in a chart. While you cannot use it to access templates, you can use it to access other files in the chart. See the section Accessing Files for more. - -
      -
    • Files.Get is a function for getting a file by name (.Files.Get config.ini)
    • -
    • Files.GetBytes is a function for getting the contents of a file as an array of bytes instead of as a string. This is useful for things like images.
    • -
  • -
  • Capabilities: This provides information about what capabilities the Kubernetes cluster supports. - -
      -
    • Capabilities.APIVersions is a set of versions.
    • -
    • Capabilities.APIVersions.Has $version indicates whether a version (batch/v1) is enabled on the cluster.
    • -
    • Capabilities.KubeVersion provides a way to look up the Kubernetes version. It has the following values: Major, Minor, GitVersion, GitCommit, GitTreeState, BuildDate, GoVersion, Compiler, and Platform.
    • -
    • Capabilities.TillerVersion provides a way to look up the Tiller version. It has the following values: SemVer, GitCommit, and GitTreeState.
    • -
  • -
  • Template: Contains information about the current template that is being executed - -
      -
    • Name: A namespaced filepath to the current template (e.g. mychart/templates/mytemplate.yaml)
    • -
    • BasePath: The namespaced path to the templates directory of the current chart (e.g. mychart/templates).
    • -
  • -
- -

The values are available to any top-level template. As we will see later, this does not necessarily mean that they will be available everywhere.

- -

The built-in values always begin with a capital letter. This is in keeping with Go’s naming convention. When you create your own names, you are free to use a convention that suits your team. Some teams, like the Kubernetes Charts team, choose to use only initial lower case letters in order to distinguish local names from those built-in. In this guide, we follow that convention.

- -

Values Files

- -

In the previous section we looked at the built-in objects that Helm templates offer. One of the four built-in objects is Values. This object provides access to values passed into the chart. Its contents come from four sources:

- -
    -
  • The values.yaml file in the chart
  • -
  • If this is a subchart, the values.yaml file of a parent chart
  • -
  • A values file if passed into helm install or helm update with the -f flag (helm install -f myvals.yaml ./mychart)
  • -
  • Individual parameters passed with --set (such as helm install --set foo=bar ./mychart)
  • -
- -

The list above is in order of specificity: values.yaml is the default, which can be overridden by a parent chart’s values.yaml, which can in turn be overridden by a user-supplied values file, which can in turn be overridden by --set parameters.

- -

Values files are plain YAML files. Let’s edit mychart/values.yaml and then edit our ConfigMap template.

- -

Removing the defaults in values.yaml, we’ll set just one parameter:

- -
favoriteDrink: coffee
-
- -

Now we can use this inside of a template:

- -
apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: {{ .Release.Name }}-configmap
-data:
-  myvalue: "Hello World"
-  drink: {{ .Values.favoriteDrink }}
-
- -

Notice on the last line we access favoriteDrink as an attribute of Values: {{ .Values.favoriteDrink}}.

- -

Let’s see how this renders.

- -
$ helm install --dry-run --debug ./mychart
-SERVER: "localhost:44134"
-CHART PATH: /Users/mattbutcher/Code/Go/src/k8s.io/helm/_scratch/mychart
-NAME:   geared-marsupi
-TARGET NAMESPACE:   default
-CHART:  mychart 0.1.0
-MANIFEST:
----
-# Source: mychart/templates/configmap.yaml
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: geared-marsupi-configmap
-data:
-  myvalue: "Hello World"
-  drink: coffee
-
- -

Because favoriteDrink is set in the default values.yaml file to coffee, that’s the value displayed in the template. We can easily override that by adding a --set flag in our call to helm install:

- -
helm install --dry-run --debug --set favoriteDrink=slurm ./mychart
-SERVER: "localhost:44134"
-CHART PATH: /Users/mattbutcher/Code/Go/src/k8s.io/helm/_scratch/mychart
-NAME:   solid-vulture
-TARGET NAMESPACE:   default
-CHART:  mychart 0.1.0
-MANIFEST:
----
-# Source: mychart/templates/configmap.yaml
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: solid-vulture-configmap
-data:
-  myvalue: "Hello World"
-  drink: slurm
-
- -

Since --set has a higher precedence than the default values.yaml file, our template generates drink: slurm.

- -

Values files can contain more structured content, too. For example, we could create a favorite section in our values.yaml file, and then add several keys there:

- -
favorite:
-  drink: coffee
-  food: pizza
-
- -

Now we would have to modify the template slightly:

- -
apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: {{ .Release.Name }}-configmap
-data:
-  myvalue: "Hello World"
-  drink: {{ .Values.favorite.drink }}
-  food: {{ .Values.favorite.food }}
-
- -

While structuring data this way is possible, the recommendation is that you keep your values trees shallow, favoring flatness. When we look at assigning values to subcharts, we’ll see how values are named using a tree structure.

- -

Deleting a default key

- -

If you need to delete a key from the default values, you may override the value of the key to be null, in which case Helm will remove the key from the overridden values merge.

- -

For example, the stable Drupal chart allows configuring the liveness probe, in case you configure a custom image. Here are the default values:

- -
livenessProbe:
-  httpGet:
-    path: /user/login
-    port: http
-  initialDelaySeconds: 120
-
- -

If you try to override the livenessProbe handler to exec instead of httpGet using --set livenessProbe.exec.command=[cat,docroot/CHANGELOG.txt], Helm will coalesce the default and overridden keys together, resulting in the following YAML:

- -
livenessProbe:
-  httpGet:
-    path: /user/login
-    port: http
-  exec:
-    command:
-    - cat
-    - docroot/CHANGELOG.txt
-  initialDelaySeconds: 120
-
- -

However, Kubernetes would then fail because you can not declare more than one livenessProbe handler. To overcome this, you may instruct Helm to delete the livenessProbe.httpGet by setting it to null:

- -
helm install stable/drupal --set image=my-registry/drupal:0.1.0 --set livenessProbe.exec.command=[cat,docroot/CHANGELOG.txt] --set livenessProbe.httpGet=null
-
- -

At this point, we’ve seen several built-in objects, and used them to inject information into a template. Now we will take a look at another aspect of the template engine: functions and pipelines.

- -

Template Functions and Pipelines

- -

So far, we’ve seen how to place information into a template. But that information is placed into the template unmodified. Sometimes we want to transform the supplied data in a way that makes it more useable to us.

- -

Let’s start with a best practice: When injecting strings from the .Values object into the template, we ought to quote these strings. We can do that by calling the quote function in the template directive:

- -
apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: {{ .Release.Name }}-configmap
-data:
-  myvalue: "Hello World"
-  drink: {{ quote .Values.favorite.drink }}
-  food: {{ quote .Values.favorite.food }}
-
- -

Template functions follow the syntax functionName arg1 arg2.... In the snippet above, quote .Values.favorite.drink calls the quote function and passes it a single argument.

- -

Helm has over 60 available functions. Some of them are defined by the Go template language itself. Most of the others are part of the Sprig template library. We’ll see many of them as we progress through the examples.

- -
-

While we talk about the “Helm template language” as if it is Helm-specific, it is actually a combination of the Go template language, some extra functions, and a variety of wrappers to expose certain objects to the templates. Many resources on Go templates may be helpful as you learn about templating.

-
- -

Pipelines

- -

One of the powerful features of the template language is its concept of pipelines. Drawing on a concept from UNIX, pipelines are a tool for chaining together a series of template commands to compactly express a series of transformations. In other words, pipelines are an efficient way of getting several things done in sequence. Let’s rewrite the above example using a pipeline.

- -
apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: {{ .Release.Name }}-configmap
-data:
-  myvalue: "Hello World"
-  drink: {{ .Values.favorite.drink | quote }}
-  food: {{ .Values.favorite.food | quote }}
-
- -

In this example, instead of calling quote ARGUMENT, we inverted the order. We “sent” the argument to the function using a pipeline (|): .Values.favorite.drink | quote. Using pipelines, we can chain several functions together:

- -
apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: {{ .Release.Name }}-configmap
-data:
-  myvalue: "Hello World"
-  drink: {{ .Values.favorite.drink | quote }}
-  food: {{ .Values.favorite.food | upper | quote }}
-
- -
-

Inverting the order is a common practice in templates. You will see .val | quote more often than quote .val. Either practice is fine.

-
- -

When evaluated, that template will produce this:

- -
# Source: mychart/templates/configmap.yaml
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: trendsetting-p-configmap
-data:
-  myvalue: "Hello World"
-  drink: "coffee"
-  food: "PIZZA"
-
- -

Note that our original pizza has now been transformed to "PIZZA".

- -

When pipelining arguments like this, the result of the first evaluation (.Values.favorite.drink) is sent as the last argument to the function. We can modify the drink example above to illustrate with a function that takes two arguments: repeat COUNT STRING:

- -
apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: {{ .Release.Name }}-configmap
-data:
-  myvalue: "Hello World"
-  drink: {{ .Values.favorite.drink | repeat 5 | quote }}
-  food: {{ .Values.favorite.food | upper | quote }}
-
- -

The repeat function will echo the given string the given number of times, so we will get this for output:

- -
# Source: mychart/templates/configmap.yaml
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: melting-porcup-configmap
-data:
-  myvalue: "Hello World"
-  drink: "coffeecoffeecoffeecoffeecoffee"
-  food: "PIZZA"
-
- -

Using the default function

- -

One function frequently used in templates is the default function: default DEFAULT_VALUE GIVEN_VALUE. This function allows you to specify a default value inside of the template, in case the value is omitted. Let’s use it to modify the drink example above:

- -
drink: {{ .Values.favorite.drink | default "tea" | quote }}
-
- -

If we run this as normal, we’ll get our coffee:

- -
# Source: mychart/templates/configmap.yaml
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: virtuous-mink-configmap
-data:
-  myvalue: "Hello World"
-  drink: "coffee"
-  food: "PIZZA"
-
- -

Now, we will remove the favorite drink setting from values.yaml:

- -
favorite:
-  #drink: coffee
-  food: pizza
-
- -

Now re-running helm install --dry-run --debug ./mychart will produce this YAML:

- -
# Source: mychart/templates/configmap.yaml
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: fair-worm-configmap
-data:
-  myvalue: "Hello World"
-  drink: "tea"
-  food: "PIZZA"
-
- -

In an actual chart, all static default values should live in the values.yaml, and should not be repeated using the default command (otherwise they would be redundant). However, the default command is perfect for computed values, which can not be declared inside values.yaml. For example:

- -
drink: {{ .Values.favorite.drink | default (printf "%s-tea" (include "fullname" .)) }}
-
- -

In some places, an if conditional guard may be better suited than default. We’ll see those in the next section.

- -

Template functions and pipelines are a powerful way to transform information and then insert it into your YAML. But sometimes it’s necessary to add some template logic that is a little more sophisticated than just inserting a string. In the next section we will look at the control structures provided by the template language.

- -

Operators are functions

- -

For templates, the operators (eq, ne, lt, gt, and, or and so on) are all implemented as functions. In pipelines, operations can be grouped with parentheses ((, and )).

- -

Now we can turn from functions and pipelines to flow control with conditions, loops, and scope modifiers.

- -

Flow Control

- -

Control structures (called “actions” in template parlance) provide you, the template author, with the ability to control the flow of a template’s generation. Helm’s template language provides the following control structures:

- -
    -
  • if/else for creating conditional blocks
  • -
  • with to specify a scope
  • -
  • range, which provides a “for each”-style loop
  • -
- -

In addition to these, it provides a few actions for declaring and using named template segments:

- -
    -
  • define declares a new named template inside of your template
  • -
  • template imports a named template
  • -
  • block declares a special kind of fillable template area
  • -
- -

In this section, we’ll talk about if, with, and range. The others are covered in the “Named Templates” section later in this guide.

- -

If/Else

- -

The first control structure we’ll look at is for conditionally including blocks of text in a template. This is the if/else block.

- -

The basic structure for a conditional looks like this:

- -
{{ if PIPELINE }}
-  # Do something
-{{ else if OTHER PIPELINE }}
-  # Do something else
-{{ else }}
-  # Default case
-{{ end }}
-
- -

Notice that we’re now talking about pipelines instead of values. The reason for this is to make it clear that control structures can execute an entire pipeline, not just evaluate a value.

- -

A pipeline is evaluated as false if the value is:

- -
    -
  • a boolean false
  • -
  • a numeric zero
  • -
  • an empty string
  • -
  • a nil (empty or null)
  • -
  • an empty collection (map, slice, tuple, dict, array)
  • -
- -

Under all other conditions, the condition is true.

- -

Let’s add a simple conditional to our ConfigMap. We’ll add another setting if the drink is set to coffee:

- -
apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: {{ .Release.Name }}-configmap
-data:
-  myvalue: "Hello World"
-  drink: {{ .Values.favorite.drink | default "tea" | quote }}
-  food: {{ .Values.favorite.food | upper | quote }}
-  {{ if eq .Values.favorite.drink "coffee" }}mug: true{{ end }}
-
- -

Since we commented out drink: coffee in our last example, the output should not include a mug: true flag. But if we add that line back into our values.yaml file, the output should look like this:

- -
# Source: mychart/templates/configmap.yaml
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: eyewitness-elk-configmap
-data:
-  myvalue: "Hello World"
-  drink: "coffee"
-  food: "PIZZA"
-  mug: true
-
- -

Controlling Whitespace

- -

While we’re looking at conditionals, we should take a quick look at the way whitespace is controlled in templates. Let’s take the previous example and format it to be a little easier to read:

- -
apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: {{ .Release.Name }}-configmap
-data:
-  myvalue: "Hello World"
-  drink: {{ .Values.favorite.drink | default "tea" | quote }}
-  food: {{ .Values.favorite.food | upper | quote }}
-  {{if eq .Values.favorite.drink "coffee"}}
-    mug: true
-  {{end}}
-
- -

Initially, this looks good. But if we run it through the template engine, we’ll get an unfortunate result:

- -
$ helm install --dry-run --debug ./mychart
-SERVER: "localhost:44134"
-CHART PATH: /Users/mattbutcher/Code/Go/src/k8s.io/helm/_scratch/mychart
-Error: YAML parse error on mychart/templates/configmap.yaml: error converting YAML to JSON: yaml: line 9: did not find expected key
-
- -

What happened? We generated incorrect YAML because of the whitespacing above.

- -
# Source: mychart/templates/configmap.yaml
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: eyewitness-elk-configmap
-data:
-  myvalue: "Hello World"
-  drink: "coffee"
-  food: "PIZZA"
-    mug: true
-
- -

mug is incorrectly indented. Let’s simply out-dent that one line, and re-run:

- -
apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: {{ .Release.Name }}-configmap
-data:
-  myvalue: "Hello World"
-  drink: {{ .Values.favorite.drink | default "tea" | quote }}
-  food: {{ .Values.favorite.food | upper | quote }}
-  {{if eq .Values.favorite.drink "coffee"}}
-  mug: true
-  {{end}}
-
- -

When we sent that, we’ll get YAML that is valid, but still looks a little funny:

- -
# Source: mychart/templates/configmap.yaml
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: telling-chimp-configmap
-data:
-  myvalue: "Hello World"
-  drink: "coffee"
-  food: "PIZZA"
-
-  mug: true
-
-
- -

Notice that we received a few empty lines in our YAML. Why? When the template engine runs, it removes the contents inside of {{ and }}, but it leaves the remaining whitespace exactly as is.

- -

YAML ascribes meaning to whitespace, so managing the whitespace becomes pretty important. Fortunately, Helm templates have a few tools to help.

- -

First, the curly brace syntax of template declarations can be modified with special characters to tell the template engine to chomp whitespace. {{- (with the dash and space added) indicates that whitespace should be chomped left, while -}} means whitespace to the right should be consumed. Be careful! Newlines are whitespace!

- -
-

Make sure there is a space between the - and the rest of your directive. {{- 3 }} means “trim left whitespace and print 3” while {{-3}} means “print -3”.

-
- -

Using this syntax, we can modify our template to get rid of those new lines:

- -
apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: {{ .Release.Name }}-configmap
-data:
-  myvalue: "Hello World"
-  drink: {{ .Values.favorite.drink | default "tea" | quote }}
-  food: {{ .Values.favorite.food | upper | quote }}
-  {{- if eq .Values.favorite.drink "coffee"}}
-  mug: true
-  {{- end}}
-
- -

Just for the sake of making this point clear, let’s adjust the above, and substitute an * for each whitespace that will be deleted following this rule. an * at the end of the line indicates a newline character that would be removed

- -
apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: {{ .Release.Name }}-configmap
-data:
-  myvalue: "Hello World"
-  drink: {{ .Values.favorite.drink | default "tea" | quote }}
-  food: {{ .Values.favorite.food | upper | quote }}*
-**{{- if eq .Values.favorite.drink "coffee"}}
-  mug: true*
-**{{- end}}
-
-
- -

Keeping that in mind, we can run our template through Helm and see the result:

- -
# Source: mychart/templates/configmap.yaml
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: clunky-cat-configmap
-data:
-  myvalue: "Hello World"
-  drink: "coffee"
-  food: "PIZZA"
-  mug: true
-
- -

Be careful with the chomping modifiers. It is easy to accidentally do things like this:

- -
  food: {{ .Values.favorite.food | upper | quote }}
-  {{- if eq .Values.favorite.drink "coffee" -}}
-  mug: true
-  {{- end -}}
-
-
- -

That will produce food: "PIZZA"mug:true because it consumed newlines on both sides.

- -
-

For the details on whitespace control in templates, see the Official Go template documentation

-
- -

Finally, sometimes it’s easier to tell the template system how to indent for you instead of trying to master the spacing of template directives. For that reason, you may sometimes find it useful to use the indent function ({{indent 2 "mug:true"}}).

- -

Modifying scope using with

- -

The next control structure to look at is the with action. This controls variable scoping. Recall that . is a reference to the current scope. So .Values tells the template to find the Values object in the current scope.

- -

The syntax for with is similar to a simple if statement:

- -
{{ with PIPELINE }}
-  # restricted scope
-{{ end }}
-
- -

Scopes can be changed. with can allow you to set the current scope (.) to a particular object. For example, we’ve been working with .Values.favorites. Let’s rewrite our ConfigMap to alter the . scope to point to .Values.favorites:

- -
apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: {{ .Release.Name }}-configmap
-data:
-  myvalue: "Hello World"
-  {{- with .Values.favorite }}
-  drink: {{ .drink | default "tea" | quote }}
-  food: {{ .food | upper | quote }}
-  {{- end }}
-
- -

(Note that we removed the if conditional from the previous exercise)

- -

Notice that now we can reference .drink and .food without qualifying them. That is because the with statement sets . to point to .Values.favorite. The . is reset to its previous scope after {{ end }}.

- -

But here’s a note of caution! Inside of the restricted scope, you will not be able to access the other objects from the parent scope. This, for example, will fail:

- -
  {{- with .Values.favorite }}
-  drink: {{ .drink | default "tea" | quote }}
-  food: {{ .food | upper | quote }}
-  release: {{ .Release.Name }}
-  {{- end }}
-
- -

It will produce an error because Release.Name is not inside of the restricted scope for .. However, if we swap the last two lines, all will work as expected because the scope is reset after {{end}}.

- -
  {{- with .Values.favorite }}
-  drink: {{ .drink | default "tea" | quote }}
-  food: {{ .food | upper | quote }}
-  {{- end }}
-  release: {{ .Release.Name }}
-
- -

After looking a range, we will take a look at template variables, which offer one solution to the scoping issue above.

- -

Looping with the range action

- -

Many programming languages have support for looping using for loops, foreach loops, or similar functional mechanisms. In Helm’s template language, the way to iterate through a collection is to use the range operator.

- -

To start, let’s add a list of pizza toppings to our values.yaml file:

- -
favorite:
-  drink: coffee
-  food: pizza
-pizzaToppings:
-  - mushrooms
-  - cheese
-  - peppers
-  - onions
-
- -

Now we have a list (called a slice in templates) of pizzaToppings. We can modify our template to print this list into our ConfigMap:

- -
apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: {{ .Release.Name }}-configmap
-data:
-  myvalue: "Hello World"
-  {{- with .Values.favorite }}
-  drink: {{ .drink | default "tea" | quote }}
-  food: {{ .food | upper | quote }}
-  {{- end }}
-  toppings: |-
-    {{- range .Values.pizzaToppings }}
-    - {{ . | title | quote }}
-    {{- end }}
-
-
- -

Let’s take a closer look at the toppings: list. The range function will “range over” (iterate through) the pizzaToppings list. But now something interesting happens. Just like with sets the scope of ., so does a range operator. Each time through the loop, . is set to the current pizza topping. That is, the first time, . is set to mushrooms. The second iteration it is set to cheese, and so on.

- -

We can send the value of . directly down a pipeline, so when we do {{ . | title | quote }}, it sends . to title (title case function) and then to quote. If we run this template, the output will be:

- -
# Source: mychart/templates/configmap.yaml
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: edgy-dragonfly-configmap
-data:
-  myvalue: "Hello World"
-  drink: "coffee"
-  food: "PIZZA"
-  toppings: |-
-    - "Mushrooms"
-    - "Cheese"
-    - "Peppers"
-    - "Onions"
-
- -

Now, in this example we’ve done something tricky. The toppings: |- line is declaring a multi-line string. So our list of toppings is actually not a YAML list. It’s a big string. Why would we do this? Because the data in ConfigMaps data is composed of key/value pairs, where both the key and the value are simple strings. To understand why this is the case, take a look at the Kubernetes ConfigMap docs. For us, though, this detail doesn’t matter much.

- -
-

The |- marker in YAML takes a multi-line string. This can be a useful technique for embedding big blocks of data inside of your manifests, as exemplified here.

-
- -

Sometimes it’s useful to be able to quickly make a list inside of your template, and then iterate over that list. Helm templates have a function to make this easy: tuple. In computer science, a tuple is a list-like collection of fixed size, but with arbitrary data types. This roughly conveys the way a tuple is used.

- -
  sizes: |-
-    {{- range tuple "small" "medium" "large" }}
-    - {{ . }}
-    {{- end }}
-
- -

The above will produce this:

- -
  sizes: |-
-    - small
-    - medium
-    - large
-
- -

In addition to lists and tuples, range can be used to iterate over collections that have a key and a value (like a map or dict). We’ll see how to do that in the next section when we introduce template variables.

- -

Variables

- -

With functions, pipelines, objects, and control structures under our belts, we can turn to one of the more basic ideas in many programming languages: variables. In templates, they are less frequently used. But we will see how to use them to simplify code, and to make better use of with and range.

- -

In an earlier example, we saw that this code will fail:

- -
  {{- with .Values.favorite }}
-  drink: {{ .drink | default "tea" | quote }}
-  food: {{ .food | upper | quote }}
-  release: {{ .Release.Name }}
-  {{- end }}
-
- -

Release.Name is not inside of the scope that’s restricted in the with block. One way to work around scoping issues is to assign objects to variables that can be accessed without respect to the present scope.

- -

In Helm templates, a variable is a named reference to another object. It follows the form $name. Variables are assigned with a special assignment operator: :=. We can rewrite the above to use a variable for Release.Name.

- -
apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: {{ .Release.Name }}-configmap
-data:
-  myvalue: "Hello World"
-  {{- $relname := .Release.Name -}}
-  {{- with .Values.favorite }}
-  drink: {{ .drink | default "tea" | quote }}
-  food: {{ .food | upper | quote }}
-  release: {{ $relname }}
-  {{- end }}
-
- -

Notice that before we start the with block, we assign $relname := .Release.Name. Now inside of the with block, the $relname variable still points to the release name.

- -

Running that will produce this:

- -
# Source: mychart/templates/configmap.yaml
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: viable-badger-configmap
-data:
-  myvalue: "Hello World"
-  drink: "coffee"
-  food: "PIZZA"
-  release: viable-badger
-
- -

Variables are particularly useful in range loops. They can be used on list-like objects to capture both the index and the value:

- -
  toppings: |-
-    {{- range $index, $topping := .Values.pizzaToppings }}
-      {{ $index }}: {{ $topping }}
-    {{- end }}
-
-
- -

Note that range comes first, then the variables, then the assignment operator, then the list. This will assign the integer index (starting from zero) to $index and the value to $topping. Running it will produce:

- -
  toppings: |-
-      0: mushrooms
-      1: cheese
-      2: peppers
-      3: onions
-
- -

For data structures that have both a key and a value, we can use range to get both. For example, we can loop through .Values.favorite like this:

- -
apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: {{ .Release.Name }}-configmap
-data:
-  myvalue: "Hello World"
-  {{- range $key, $val := .Values.favorite }}
-  {{ $key }}: {{ $val | quote }}
-  {{- end}}
-
- -

Now on the first iteration, $key will be drink and $val will be coffee, and on the second, $key will be food and $val will be pizza. Running the above will generate this:

- -
# Source: mychart/templates/configmap.yaml
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: eager-rabbit-configmap
-data:
-  myvalue: "Hello World"
-  drink: "coffee"
-  food: "pizza"
-
- -

Variables are normally not “global”. They are scoped to the block in which they are declared. Earlier, we assigned $relname in the top level of the template. That variable will be in scope for the entire template. But in our last example, $key and $val will only be in scope inside of the {{range...}}{{end}} block.

- -

However, there is one variable that is always global - $ - this -variable will always point to the root context. This can be very -useful when you are looping in a range need to know the chart’s release -name.

- -

An example illustrating this:

- -
{{- range .Values.tlsSecrets }}
-apiVersion: v1
-kind: Secret
-metadata:
-  name: {{ .name }}
-  labels:
-    # Many helm templates would use `.` below, but that will not work, 
-    # however `$` will work here 
-    app: {{ template "fullname" $ }}
-    # I cannot reference .Chart.Name, but I can do $.Chart.Name
-    chart: "{{ $.Chart.Name }}-{{ $.Chart.Version }}"
-    release: "{{ $.Release.Name }}"
-    heritage: "{{ $.Release.Service }}"
-type: kubernetes.io/tls
-data:
-  tls.crt: {{ .certificate }}
-  tls.key: {{ .key }}
----
-{{- end }}
-
- -

So far we have looked at just one template declared in just one file. But one of the powerful features of the Helm template language is its ability to declare multiple templates and use them together. We’ll turn to that in the next section.

- -

Named Templates

- -

It is time to move beyond one template, and begin to create others. In this section, we will see how to define named templates in one file, and then use them elsewhere. A named template (sometimes called a partial or a subtemplate) is simply a template defined inside of a file, and given a name. We’ll see two ways to create them, and a few different ways to use them.

- -

In the “Flow Control” section we introduced three actions for declaring and managing templates: define, template, and block. In this section, we’ll cover those three actions, and also introduce a special-purpose include function that works similarly to the template action.

- -

Partials and _ files

- -

So far, we’ve used one file, and that one file has contained a single template. But Helm’s template language allows you to create named embedded templates, that can be accessed by name elsewhere.

- -

Before we get to the nuts-and-bolts of writing those templates, there is file naming convention that deserves mention:

- -
    -
  • Most files in templates/ are treated as if they contain Kubernetes manifests
  • -
  • The NOTES.txt is one exception
  • -
  • But files whose name begins with an underscore (_) are assumed to not have a manifest inside. These files are not rendered to Kubernetes object definitions, but are available everywhere within other chart templates for use.
  • -
- -

These files are used to store partials and helpers. In fact, when we first created mychart, we saw a file called _helpers.tpl. That file is the default location for template partials.

- -

Declaring and using templates with define and template

- -

The define action allows us to create a named template inside of a template file. Its syntax goes like this:

- -
{{ define "MY_NAME" }}
-  # body of template here
-{{ end }}
-
- -

For example, we can define a template to encapsulate a Kubernetes block of labels:

- -
{{- define "my_labels" }}
-  labels:
-    generator: helm
-    date: {{ now | htmlDate }}
-{{- end }}
-
- -

Now we can embed this template inside of our existing ConfigMap, and then include it with the template action:

- -
{{- define "my_labels" }}
-  labels:
-    generator: helm
-    date: {{ now | htmlDate }}
-{{- end }}
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: {{ .Release.Name }}-configmap
-  {{- template "my_labels" }}
-data:
-  myvalue: "Hello World"
-  {{- range $key, $val := .Values.favorite }}
-  {{ $key }}: {{ $val | quote }}
-  {{- end }}
-
- -

When the template engine reads this file, it will store away the reference to my_labels until template "my_labels" is called. Then it will render that template inline. So the result will look like this:

- -
# Source: mychart/templates/configmap.yaml
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: running-panda-configmap
-  labels:
-    generator: helm
-    date: 2016-11-02
-data:
-  myvalue: "Hello World"
-  drink: "coffee"
-  food: "pizza"
-
- -

Conventionally, Helm charts put these templates inside of a partials file, usually _helpers.tpl. Let’s move this function there:

- -
{{/* Generate basic labels */}}
-{{- define "my_labels" }}
-  labels:
-    generator: helm
-    date: {{ now | htmlDate }}
-{{- end }}
-
- -

By convention, define functions should have a simple documentation block ({{/* ... */}}) describing what they do.

- -

Even though this definition is in _helpers.tpl, it can still be accessed in configmap.yaml:

- -
apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: {{ .Release.Name }}-configmap
-  {{- template "my_labels" }}
-data:
-  myvalue: "Hello World"
-  {{- range $key, $val := .Values.favorite }}
-  {{ $key }}: {{ $val | quote }}
-  {{- end }}
-
- -

There is one really important detail to keep in mind when naming templates: template names are global. If you declare two templates with the same name, whichever one is loaded last will be the one used. Because templates in subcharts are compiled together with top-level templates, you should be careful to name your templates with chart-specific names.

- -

One popular naming convention is to prefix each defined template with the name of the chart: {{ define "mychart.labels" }} or {{ define "mychart_labels" }}.

- -

Setting the scope of a template

- -

In the template we defined above, we did not use any objects. We just used functions. Let’s modify our defined template to include the chart name and chart version:

- -
{{/* Generate basic labels */}}
-{{- define "my_labels" }}
-  labels:
-    generator: helm
-    date: {{ now | htmlDate }}
-    chart: {{ .Chart.Name }}
-    version: {{ .Chart.Version }}
-{{- end }}
-
- -

If we render this, the result will not be what we expect:

- -
# Source: mychart/templates/configmap.yaml
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: moldy-jaguar-configmap
-  labels:
-    generator: helm
-    date: 2016-11-02
-    chart:
-    version:
-
- -

What happened to the name and version? They weren’t in the scope for our defined template. When a named template (created with define) is rendered, it will receive the scope passed in by the template call. In our example, we included the template like this:

- -
{{- template "my_labels" }}
-
- -

No scope was passed in, so within the template we cannot access anything in .. This is easy enough to fix, though. We simply pass a scope to the template:

- -
apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: {{ .Release.Name }}-configmap
-  {{- template "my_labels" . }}
-
- -

Note that we pass . at the end of the template call. We could just as easily pass .Values or .Values.favorite or whatever scope we want. But what we want is the top-level scope.

- -

Now when we execute this template with helm install --dry-run --debug ./mychart, we get this:

- -
# Source: mychart/templates/configmap.yaml
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: plinking-anaco-configmap
-  labels:
-    generator: helm
-    date: 2016-11-02
-    chart: mychart
-    version: 0.1.0
-
- -

Now {{ .Chart.Name }} resolves to mychart, and {{ .Chart.Version }} resolves to 0.1.0.

- -

The include function

- -

Say we’ve defined a simple template that looks like this:

- -
{{- define "mychart_app" -}}
-app_name: {{ .Chart.Name }}
-app_version: "{{ .Chart.Version }}+{{ .Release.Time.Seconds }}"
-{{- end -}}
-
- -

Now say I want to insert this both into the labels: section of my template, and also the data: section:

- -
apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: {{ .Release.Name }}-configmap
-  labels:
-    {{ template "mychart_app" .}}
-data:
-  myvalue: "Hello World"
-  {{- range $key, $val := .Values.favorite }}
-  {{ $key }}: {{ $val | quote }}
-  {{- end }}
-  {{ template "mychart_app" . }}
-
-
- -

The output will not be what we expect:

- -
# Source: mychart/templates/configmap.yaml
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: measly-whippet-configmap
-  labels:
-    app_name: mychart
-app_version: "0.1.0+1478129847"
-data:
-  myvalue: "Hello World"
-  drink: "coffee"
-  food: "pizza"
-  app_name: mychart
-app_version: "0.1.0+1478129847"
-
- -

Note that the indentation on app_version is wrong in both places. Why? Because the template that is substituted in has the text aligned to the right. Because template is an action, and not a function, there is no way to pass the output of a template call to other functions; the data is simply inserted inline.

- -

To work around this case, Helm provides an alternative to template that will import the contents of a template into the present pipeline where it can be passed along to other functions in the pipeline.

- -

Here’s the example above, corrected to use indent to indent the mychart_app template correctly:

- -
apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: {{ .Release.Name }}-configmap
-  labels:
-{{ include "mychart_app" . | indent 4 }}
-data:
-  myvalue: "Hello World"
-  {{- range $key, $val := .Values.favorite }}
-  {{ $key }}: {{ $val | quote }}
-  {{- end }}
-{{ include "mychart_app" . | indent 2 }}
-
- -

Now the produced YAML is correctly indented for each section:

- -
# Source: mychart/templates/configmap.yaml
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: edgy-mole-configmap
-  labels:
-    app_name: mychart
-    app_version: "0.1.0+1478129987"
-data:
-  myvalue: "Hello World"
-  drink: "coffee"
-  food: "pizza"
-  app_name: mychart
-  app_version: "0.1.0+1478129987"
-
- -
-

It is considered preferable to use include over template in Helm templates simply so that the output formatting can be handled better for YAML documents.

-
- -

Sometimes we want to import content, but not as templates. That is, we want to import files verbatim. We can achieve this by accessing files through the .Files object described in the next section.

- -

Accessing Files Inside Templates

- -

In the previous section we looked at several ways to create and access named templates. This makes it easy to import one template from within another template. But sometimes it is desirable to import a file that is not a template and inject its contents without sending the contents through the template renderer.

- -

Helm provides access to files through the .Files object. Before we get going with the template examples, though, there are a few things to note about how this works:

- -
    -
  • It is okay to add extra files to your Helm chart. These files will be bundled and sent to Tiller. Be careful, though. Charts must be smaller than 1M because of the storage limitations of Kubernetes objects.
  • -
  • Some files cannot be accessed through the .Files object, usually for security reasons. - -
      -
    • Files in templates/ cannot be accessed.
    • -
    • Files excluded using .helmignore cannot be accessed.
    • -
  • -
  • Charts do not preserve UNIX mode information, so file-level permissions will have no impact on the availability of a file when it comes to the .Files object.
  • -
- - - - - - - - - -

Basic example

- -

With those caveats behind, let’s write a template that reads three files into our ConfigMap. To get started, we will add three files to the chart, putting all three directly inside of the mychart/ directory.

- -

config1.toml:

- -
message = Hello from config 1
-
- -

config2.toml:

- -
message = This is config 2
-
- -

config3.toml:

- -
message = Goodbye from config 3
-
- -

Each of these is a simple TOML file (think old-school Windows INI files). We know the names of these files, so we can use a range function to loop through them and inject their contents into our ConfigMap.

- -
apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: {{ .Release.Name }}-configmap
-data:
-  {{- $files := .Files }}
-  {{- range tuple "config1.toml" "config2.toml" "config3.toml" }}
-  {{ . }}: |-
-    {{ $files.Get . }}
-  {{- end }}
-
- -

This config map uses several of the techniques discussed in previous sections. For example, we create a $files variable to hold a reference to the .Files object. We also use the tuple function to create a list of files that we loop through. Then we print each file name ({{.}}: |-) followed by the contents of the file {{ $files.Get . }}.

- -

Running this template will produce a single ConfigMap with the contents of all three files:

- -
# Source: mychart/templates/configmap.yaml
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: quieting-giraf-configmap
-data:
-  config1.toml: |-
-    message = Hello from config 1
-
-  config2.toml: |-
-    message = This is config 2
-
-  config3.toml: |-
-    message = Goodbye from config 3
-
- -

Path helpers

- -

When working with files, it can be very useful to perform some standard -operations on the file paths themselves. To help with this, Helm imports many of -the functions from Go’s path package for your -use. They are all accessible with the same names as in the Go package, but -with a lowercase first letter. For example, Base becomes base, etc.

- -

The imported functions are: -- Base -- Dir -- Ext -- IsAbs -- Clean

- -

Glob patterns

- -

As your chart grows, you may find you have a greater need to organize your -files more, and so we provide a Files.Glob(pattern string) method to assist -in extracting certain files with all the flexibility of glob patterns.

- -

.Glob returns a Files type, so you may call any of the Files methods on -the returned object.

- -

For example, imagine the directory structure:

- -
foo/: 
-  foo.txt foo.yaml
-
-bar/:
-  bar.go bar.conf baz.yaml
-
- -

You have multiple options with Globs:

- -
{{ range $path := .Files.Glob "**.yaml" }}
-{{ $path }}: |
-{{ .Files.Get $path }}
-{{ end }}
-
- -

Or

- -
{{ range $path, $bytes := .Files.Glob "foo/*" }}
-{{ $path }}: '{{ b64enc $bytes }}'
-{{ end }}
-
- -

ConfigMap and Secrets utility functions

- -

(Not present in version 2.0.2 or prior)

- -

It is very common to want to place file content into both configmaps and -secrets, for mounting into your pods at run time. To help with this, we provide a -couple utility methods on the Files type.

- -

For further organization, it is especially useful to use these methods in -conjunction with the Glob method.

- -

Given the directory structure from the Glob example above:

- -
apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: conf
-data:
-{{ (.Files.Glob "foo/*").AsConfig | indent 2 }}
----
-apiVersion: v1
-kind: Secret
-metadata:
-  name: very-secret
-type: Opaque
-data:
-{{ (.Files.Glob "bar/*").AsSecrets | indent 2 }}
-
- -

Encoding

- -

You can import a file and have the template base-64 encode it to ensure successful transmission:

- -
apiVersion: v1
-kind: Secret
-metadata:
-  name: {{ .Release.Name }}-secret
-type: Opaque
-data:
-  token: |-
-    {{ .Files.Get "config1.toml" | b64enc }}
-
- -

The above will take the same config1.toml file we used before and encode it:

- -
# Source: mychart/templates/secret.yaml
-apiVersion: v1
-kind: Secret
-metadata:
-  name: lucky-turkey-secret
-type: Opaque
-data:
-  token: |-
-    bWVzc2FnZSA9IEhlbGxvIGZyb20gY29uZmlnIDEK
-
- -

Lines

- -

Sometimes it is desirable to access each line of a file in your template. We -provide a convenient Lines method for this.

- -
data:
-  some-file.txt: {{ range .Files.Lines "foo/bar.txt" }}
-    {{ . }}{{ end }}
-
- -

Currently, there is no way to pass files external to the chart during helm install. So if you are asking users to supply data, it must be loaded using helm install -f or helm install --set.

- -

This discussion wraps up our dive into the tools and techniques for writing Helm templates. In the next section we will see how you can use one special file, templates/NOTES.txt, to send post-installation instructions to the users of your chart.

- -

Creating a NOTES.txt File

- -

In this section we are going to look at Helm’s tool for providing instructions to your chart users. At the end of a chart install or chart upgrade, Helm can print out a block of helpful information for users. This information is highly customizable using templates.

- -

To add installation notes to your chart, simply create a templates/NOTES.txt file. This file is plain text, but it is processed like as a template, and has all the normal template functions and objects available.

- -

Let’s create a simple NOTES.txt file:

- -
Thank you for installing {{ .Chart.Name }}.
-
-Your release is named {{ .Release.Name }}.
-
-To learn more about the release, try:
-
-  $ helm status {{ .Release.Name }}
-  $ helm get {{ .Release.Name }}
-
-
- -

Now if we run helm install ./mychart we will see this message at the bottom:

- -
RESOURCES:
-==> v1/Secret
-NAME                   TYPE      DATA      AGE
-rude-cardinal-secret   Opaque    1         0s
-
-==> v1/ConfigMap
-NAME                      DATA      AGE
-rude-cardinal-configmap   3         0s
-
-
-NOTES:
-Thank you for installing mychart.
-
-Your release is named rude-cardinal.
-
-To learn more about the release, try:
-
-  $ helm status rude-cardinal
-  $ helm get rude-cardinal
-
- -

Using NOTES.txt this way is a great way to give your users detailed information about how to use their newly installed chart. Creating a NOTES.txt file is strongly recommended, though it is not required.

- -

Subcharts and Global Values

- -

To this point we have been working only with one chart. But charts can have dependencies, called subcharts, that also have their own values and templates. In this section we will create a subchart and see the different ways we can access values from within templates.

- -

Before we dive into the code, there are a few important details to learn about subcharts.

- -
    -
  1. A subchart is considered “stand-alone”, which means a subchart can never explicitly depend on its parent chart.
  2. -
  3. For that reason, a subchart cannot access the values of its parent.
  4. -
  5. A parent chart can override values for subcharts.
  6. -
  7. Helm has a concept of global values that can be accessed by all charts.
  8. -
- -

As we walk through the examples in this section, many of these concepts will become clearer.

- -

Creating a Subchart

- -

For these exercises, we’ll start with the mychart/ chart we created at the beginning of this guide, and we’ll add a new chart inside of it.

- -
$ cd mychart/charts
-$ helm create mysubchart
-Creating mysubchart
-$ rm -rf mysubchart/templates/*.*
-
- -

Notice that just as before, we deleted all of the base templates so that we can start from scratch. In this guide, we are focused on how templates work, not on managing dependencies. But the Charts Guide has more information on how subcharts work.

- -

Adding Values and a Template to the Subchart

- -

Next, let’s create a simple template and values file for our mysubchart chart. There should already be a values.yaml in mychart/charts/mysubchart. We’ll set it up like this:

- -
dessert: cake
-
- -

Next, we’ll create a new ConfigMap template in mychart/charts/mysubchart/templates/configmap.yaml:

- -
apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: {{ .Release.Name }}-cfgmap2
-data:
-  dessert: {{ .Values.dessert }}
-
- -

Because every subchart is a stand-alone chart, we can test mysubchart on its own:

- -
$ helm install --dry-run --debug mychart/charts/mysubchart
-SERVER: "localhost:44134"
-CHART PATH: /Users/mattbutcher/Code/Go/src/k8s.io/helm/_scratch/mychart/charts/mysubchart
-NAME:   newbie-elk
-TARGET NAMESPACE:   default
-CHART:  mysubchart 0.1.0
-MANIFEST:
----
-# Source: mysubchart/templates/configmap.yaml
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: newbie-elk-cfgmap2
-data:
-  dessert: cake
-
- -

Overriding Values from a Parent Chart

- -

Our original chart, mychart is now the parent chart of mysubchart. This relationship is based entirely on the fact that mysubchart is within mychart/charts.

- -

Because mychart is a parent, we can specify configuration in mychart and have that configuration pushed into mysubchart. For example, we can modify mychart/values.yaml like this:

- -
favorite:
-  drink: coffee
-  food: pizza
-pizzaToppings:
-  - mushrooms
-  - cheese
-  - peppers
-  - onions
-
-mysubchart:
-  dessert: ice cream
-
- -

Note the last two lines. Any directives inside of the mysubchart section will be sent to the mysubchart chart. So if we run helm install --dry-run --debug mychart, one of the things we will see is the mysubchart ConfigMap:

- -
# Source: mychart/charts/mysubchart/templates/configmap.yaml
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: unhinged-bee-cfgmap2
-data:
-  dessert: ice cream
-
- -

The value at the top level has now overridden the value of the subchart.

- -

There’s an important detail to notice here. We didn’t change the template of mychart/charts/mysubchart/templates/configmap.yaml to point to .Values.mysubchart.dessert. From that template’s perspective, the value is still located at .Values.dessert. As the template engine passes values along, it sets the scope. So for the mysubchart templates, only values specifically for mysubchart will be available in .Values.

- -

Sometimes, though, you do want certain values to be available to all of the templates. This is accomplished using global chart values.

- -

Global Chart Values

- -

Global values are values that can be accessed from any chart or subchart by exactly the same name. Globals require explicit declaration. You can’t use an existing non-global as if it were a global.

- -

The Values data type has a reserved section called Values.global where global values can be set. Let’s set one in our mychart/values.yaml file.

- -
favorite:
-  drink: coffee
-  food: pizza
-pizzaToppings:
-  - mushrooms
-  - cheese
-  - peppers
-  - onions
-
-mysubchart:
-  dessert: ice cream
-
-global:
-  salad: caesar
-
- -

Because of the way globals work, both mychart/templates/configmap.yaml and mysubchart/templates/configmap.yaml should be able to access that value as {{ .Values.global.salad}}.

- -

mychart/templates/configmap.yaml:

- -
apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: {{ .Release.Name }}-configmap
-data:
-  salad: {{ .Values.global.salad }}
-
- -

mysubchart/templates/configmap.yaml:

- -
apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: {{ .Release.Name }}-cfgmap2
-data:
-  dessert: {{ .Values.dessert }}
-  salad: {{ .Values.global.salad }}
-
- -

Now if we run a dry run install, we’ll see the same value in both outputs:

- -
# Source: mychart/templates/configmap.yaml
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: silly-snake-configmap
-data:
-  salad: caesar
-
----
-# Source: mychart/charts/mysubchart/templates/configmap.yaml
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: silly-snake-cfgmap2
-data:
-  dessert: ice cream
-  salad: caesar
-
- -

Globals are useful for passing information like this, though it does take some planning to make sure the right templates are configured to use globals.

- -

Sharing Templates with Subcharts

- -

Parent charts and subcharts can share templates. Any defined block in any chart is -available to other charts.

- -

For example, we can define a simple template like this:

- -
{{- define "labels" }}from: mychart{{ end }}
-
- -

Recall how the labels on templates are globally shared. Thus, the labels chart -can be included from any other chart.

- -

While chart developers have a choice between include and template, one advantage -of using include is that include can dynamically reference templates:

- -
{{ include $mytemplate }}
-
- -

The above will dereference $mytemplate. The template function, in contrast, -will only accept a string literal.

- -

Avoid Using Blocks

- -

The Go template language provides a block keyword that allows developers to provide -a default implementation which is overridden later. In Helm charts, blocks are not -the best tool for overriding because it if multiple implementations of the same block -are provided, the one selected is unpredictable.

- -

The suggestion is to instead use include.

- -

Debugging Templates

- -

Debugging templates can be tricky simply because the templates are rendered on the Tiller server, not the Helm client. And then the rendered templates are sent to the Kubernetes API server, which may reject the YAML files for reasons other than formatting.

- -

There are a few commands that can help you debug.

- -
    -
  • helm lint is your go-to tool for verifying that your chart follows best practices
  • -
  • helm install --dry-run --debug: We’ve seen this trick already. It’s a great way to have the server render your templates, then return the resulting manifest file.
  • -
  • helm get manifest: This is a good way to see what templates are installed on the server.
  • -
- -

When your YAML is failing to parse, but you want to see what is generated, one -easy way to retrieve the YAML is to comment out the problem section in the template, -and then re-run helm install --dry-run --debug:

- -
apiVersion: v1
-# some: problem section
-# {{ .Values.foo | quote }}
-
- -

The above will be rendered and returned with the comments intact:

- -
apiVersion: v1
-# some: problem section
-#  "bar"
-
- -

This provides a quick way of viewing the generated content without YAML parse -errors blocking.

- -

Wrapping Up

- -

This guide is intended to give you, the chart developer, a strong understanding of how to use Helm’s template language. The guide focuses on the technical aspects of template development.

- -

But there are many things this guide has not covered when it comes to the practical day-to-day development of charts. Here are some useful pointers to other documentation that will help you as you create new charts:

- -
    -
  • The Kubernetes Charts project is an indispensable source of charts. That project is also sets the standard for best practices in chart development.
  • -
  • The Kubernetes User’s Guide provides detailed examples of the various resource kinds that you can use, from ConfigMaps and Secrets to DaemonSets and Deployments.
  • -
  • The Helm Charts Guide explains the workflow of using charts.
  • -
  • The Helm Chart Hooks Guide explains how to create lifecycle hooks.
  • -
  • The Helm Charts Tips and Tricks article provides some useful tips for writing charts.
  • -
  • The Sprig documentation documents more than sixty of the template functions.
  • -
  • The Go template docs explain the template syntax in detail.
  • -
  • The Schelm tool is a nice helper utility for debugging charts.
  • -
- -

Sometimes it’s easier to ask a few questions and get answers from experienced developers. The best place to do that is in the Kubernetes #Helm Slack channel:

- - - -

Finally, if you find errors or omissions in this document, want to suggest some new content, or would like to contribute, visit The Helm Project.

- -

YAML Techniques

- -

Most of this guide has been focused on writing the template language. Here, -we’ll look at the YAML format. YAML has some useful features that we, as -template authors, can use to make our templates less error prone and easier -to read.

- -

Scalars and Collections

- -

According to the YAML spec, there are two -types of collections, and many scalar types.

- -

The two types of collections are maps and sequences:

- -
map:
-  one: 1
-  two: 2
-  three: 3
-
-sequence:
-  - one
-  - two
-  - three
-
- -

Scalar values are individual values (as opposed to collections)

- -

Scalar Types in YAML

- -

In Helm’s dialect of YAML, the scalar data type of a value is determined by a -complex set of rules, including the Kubernetes schema for resource definitions. -But when inferring types, the following rules tend to hold true.

- -

If an integer or float is an unquoted bare word, it is typically treated as -a numeric type:

- -
count: 1
-size: 2.34
-
- -

But if they are quoted, they are treated as strings:

- -
count: "1" # <-- string, not int
-size: '2.34' # <-- string, not float
-
- -

The same is true of booleans:

- -
isGood: true   # bool
-answer: "true" # string
-
- -

The word for an empty value is null (not nil).

- -

Note that port: "80" is valid YAML, and will pass through both the -template engine and the YAML parser, but will fail if Kubernetes expects -port to be an integer.

- -

In some cases, you can force a particular type inference using YAML node tags:

- -
coffee: "yes, please"
-age: !!str 21
-port: !!int "80"
-
- -

In the above, !!str tells the parser that age is a string, even if it looks -like an int. And port is treated as an int, even though it is quoted.

- -

Strings in YAML

- -

Much of the data that we place in YAML documents are strings. YAML has more than -one way to represent a string. This section explains the ways and demonstrates -how to use some of them.

- -

There are three “inline” ways of declaring a string:

- -
way1: bare words
-way2: "double-quoted strings"
-way3: 'single-quoted strings'
-
- -

All inline styles must be on one line.

- -
    -
  • Bare words are unquoted, and are not escaped. For this reason, you have to -be careful what characters you use.
  • -
  • Double-quoted strings can have specific characters escaped with \. For -example "\"Hello\", she said". You can escape line breaks with \n.
  • -
  • Single-quoted strings are “literal” strings, and do not use the \ to -escape characters. The only escape sequence is '', which is decoded as -a single '.
  • -
- -

In addition to the one-line strings, you can declare multi-line strings:

- -
coffee: |
-  Latte
-  Cappuccino
-  Espresso
-
- -

The above will treat the value of coffee as a single string equivalent to -Latte\nCappuccino\nEspresso\n.

- -

Note that the first line after the | must be correctly indented. So we could -break the example above by doing this:

- -
coffee: |
-         Latte
-  Cappuccino
-  Espresso
-
-
- -

Because Latte is incorrectly indented, we’d get an error like this:

- -
Error parsing file: error converting YAML to JSON: yaml: line 7: did not find expected key
-
- -

In templates, it is sometimes safer to put a fake “first line” of content in a -multi-line document just for protection from the above error:

- -
coffee: |
-  # Commented first line
-         Latte
-  Cappuccino
-  Espresso
-
-
- -

Note that whatever that first line is, it will be preserved in the output of the -string. So if you are, for example, using this technique to inject a file’s contents -into a ConfigMap, the comment should be of the type expected by whatever is -reading that entry.

- -

Controlling Spaces in Multi-line Strings

- -

In the example above, we used | to indicate a multi-line string. But notice -that the content of our string was followed with a trailing \n. If we want -the YAML processor to strip off the trailing newline, we can add a - after the -|:

- -
coffee: |-
-  Latte
-  Cappuccino
-  Espresso
-
- -

Now the coffee value will be: Latte\nCappuccino\nEspresso (with no trailing -\n).

- -

Other times, we might want all trailing whitespace to be preserved. We can do -this with the |+ notation:

- -
coffee: |+
-  Latte
-  Cappuccino
-  Espresso
-
-
-another: value
-
- -

Now the value of coffee will be Latte\nCappuccino\nEspresso\n\n\n.

- -

Indentation inside of a text block is preserved, and results in the preservation -of line breaks, too:

- -
coffee: |-
-  Latte
-    12 oz
-    16 oz
-  Cappuccino
-  Espresso
-
- -

In the above case, coffee will be Latte\n 12 oz\n 16 oz\nCappuccino\nEspresso.

- -

Indenting and Templates

- -

When writing templates, you may find yourself wanting to inject the contents of -a file into the template. As we saw in previous chapters, there are two ways -of doing this:

- -
    -
  • Use {{ .Files.Get "FILENAME" }} to get the contents of a file in the chart.
  • -
  • Use {{ include "TEMPLATE" . }} to render a template and then place its -contents into the chart.
  • -
- -

When inserting files into YAML, it’s good to understand the multi-line rules above. -Often times, the easiest way to insert a static file is to do something like -this:

- -
myfile: |
-{{ .Files.Get "myfile.txt" | indent 2 }}
-
- -

Note how we do the indentation above: indent 2 tells the template engine to -indent every line in “myfile.txt” with two spaces. Note that we do not indent -that template line. That’s because if we did, the file content of the first line -would be indented twice.

- -

Folded Multi-line Strings

- -

Sometimes you want to represent a string in your YAML with multiple lines, but -want it to be treated as one long line when it is interpreted. This is called -“folding”. To declare a folded block, use > instead of |:

- -
coffee: >
-  Latte
-  Cappuccino
-  Espresso
-
-
-
- -

The value of coffee above will be Latte Cappuccino Espresso\n. Note that all -but the last line feed will be converted to spaces. You can combine the whitespace -controls with the folded text marker, so >- will replace or trim all newlines.

- -

Note that in the folded syntax, indenting text will cause lines to be preserved.

- -
coffee: >-
-  Latte
-    12 oz
-    16 oz
-  Cappuccino
-  Espresso
-
- -

The above will produce Latte\n 12 oz\n 16 oz\nCappuccino Espresso. Note that -both the spacing and the newlines are still there.

- -

Embedding Multiple Documents in One File

- -

It is possible to place more than one YAML documents into a single file. This -is done by prefixing a new document with --- and ending the document with -...

- -

----
-document:1
-...
----
-document: 2
-...
-
- -

In many cases, either the --- or the ... may be omitted.

- -

Some files in Helm cannot contain more than one doc. If, for example, more -than one document is provided inside of a values.yaml file, only the first -will be used.

- -

Template files, however, may have more than one document. When this happens, -the file (and all of its documents) is treated as one object during -template rendering. But then the resulting YAML is split into multiple -documents before it is fed to Kubernetes.

- -

We recommend only using multiple documents per file when it is absolutely -necessary. Having multiple documents in a file can be difficult to debug.

- -

YAML is a Superset of JSON

- -

Because YAML is a superset of JSON, any valid JSON document should be valid -YAML.

- -
{
-  "coffee": "yes, please",
-  "coffees": [
-    "Latte", "Cappuccino", "Espresso"
-  ]
-}
-
- -

The above is another way of representing this:

- -
coffee: yes, please
-coffees:
-- Latte
-- Cappuccino
-- Espresso
-
- -

And the two can be mixed (with care):

- -
coffee: "yes, please"
-coffees: [ "Latte", "Cappuccino", "Espresso"]
-
- -

All three of these should parse into the same internal representation.

- -

While this means that files such as values.yaml may contain JSON data, Helm -does not treat the file extension .json as a valid suffix.

- -

YAML Anchors

- -

The YAML spec provides a way to store a reference to a value, and later -refer to that value by reference. YAML refers to this as “anchoring”:

- -
coffee: "yes, please"
-favorite: &favoriteCoffee "Cappucino"
-coffees:
-  - Latte
-  - *favoriteCoffee
-  - Espresso
-
- -

In the above, &favoriteCoffee sets a reference to Cappuccino. Later, that -reference is used as *favoriteCoffee. So coffees becomes -Latte, Cappuccino, Espresso.

- -

While there are a few cases where anchors are useful, there is one aspect of -them that can cause subtle bugs: The first time the YAML is consumed, the -reference is expanded and then discarded.

- -

So if we were to decode and then re-encode the example above, the resulting -YAML would be:

- -
coffee: yes, please
-favorite: Cappucino
-coffees:
-- Latte
-- Cappucino
-- Espresso
-
- -

Because Helm and Kubernetes often read, modify, and then rewrite YAML files, -the anchors will be lost.

- -

Appendix: Go Data Types and Templates

- -

The Helm template language is implemented in the strongly typed Go programming language. For that reason, variables in templates are typed. For the most part, variables will be exposed as one of the following types:

- -
    -
  • string: A string of text
  • -
  • bool: a true or false
  • -
  • int: An integer value (there are also 8, 16, 32, and 64 bit signed and unsigned variants of this)
  • -
  • float64: a 64-bit floating point value (there are also 8, 16, and 32 bit varieties of this)
  • -
  • a byte slice ([]byte), often used to hold (potentially) binary data
  • -
  • struct: an object with properties and methods
  • -
  • a slice (indexed list) of one of the previous types
  • -
  • a string-keyed map (map[string]interface{}) where the value is one of the previous types
  • -
- -

There are many other types in Go, and sometimes you will have to convert between them in your templates. The easiest way to debug an object’s type is to pass it through printf "%t" in a template, which will print the type. Also see the typeOf and kindOf functions.

-
-
- -
-
 
-
- -
-
-

- Helm is supported by and built with a community of over 250 developers. -

-

- helm.sh and docs.helm.sh are maintained by Microsoft -

-
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/chart_template_guide/index.md/index.html b/docs.helm.sh/rootfs/public/chart_template_guide/index.md/index.html deleted file mode 100644 index 46ab06f877..0000000000 --- a/docs.helm.sh/rootfs/public/chart_template_guide/index.md/index.html +++ /dev/null @@ -1 +0,0 @@ -https://docs.helm.sh/chart_template_guide/ \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/chart_template_guide/index.xml b/docs.helm.sh/rootfs/public/chart_template_guide/index.xml deleted file mode 100644 index b537949632..0000000000 --- a/docs.helm.sh/rootfs/public/chart_template_guide/index.xml +++ /dev/null @@ -1,2147 +0,0 @@ - - - - Chart_template_guide - https://docs.helm.sh/chart_template_guide/ - en-us - Mon, 01 Jan 0001 00:00:00 UTC - - - - https://docs.helm.sh/chart_template_guide/ - Mon, 01 Jan 0001 00:00:00 UTC - https://docs.helm.sh/chart_template_guide/ - - -<h1 id="the-chart-template-developer-s-guide">The Chart Template Developer&rsquo;s Guide</h1> - -<p>This guide provides an introduction to Helm&rsquo;s chart templates, with emphasis on -the template language.</p> - -<p>Templates generate manifest files, which are YAML-formatted resource descriptions -that Kubernetes can understand. We&rsquo;ll look at how templates are structured, -how they can be used, how to write Go templates, and how to debug your work.</p> - -<p>This guide focuses on the following concepts:</p> - -<ul> -<li>The Helm template language</li> -<li>Using values</li> -<li>Techniques for working with templates</li> -</ul> - -<p>This guide is oriented toward learning the ins and outs of the Helm template language. Other guides provide introductory material, examples, and best practices.</p> - -<h1 id="getting-started-with-a-chart-template">Getting Started with a Chart Template</h1> - -<p>In this section of the guide, we&rsquo;ll create a chart and then add a first template. The chart we created here will be used throughout the rest of the guide.</p> - -<p>To get going, let&rsquo;s take a brief look at a Helm chart.</p> - -<h2 id="charts">Charts</h2> - -<p>As described in the <a href="./#../charts">Charts Guide</a>, Helm charts are structured like -this:</p> - -<pre><code>mychart/ - Chart.yaml - values.yaml - charts/ - templates/ - ... -</code></pre> - -<p>The <code>templates/</code> directory is for template files. When Tiller evaluates a chart, -it will send all of the files in the <code>templates/</code> directory through the -template rendering engine. Tiller then collects the results of those templates -and sends them on to Kubernetes.</p> - -<p>The <code>values.yaml</code> file is also important to templates. This file contains the -<em>default values</em> for a chart. These values may be overridden by users during -<code>helm install</code> or <code>helm upgrade</code>.</p> - -<p>The <code>Chart.yaml</code> file contains a description of the chart. You can access it -from within a template. The <code>charts/</code> directory <em>may</em> contain other charts (which -we call <em>subcharts</em>). Later in this guide we will see how those work when it -comes to template rendering.</p> - -<h2 id="a-starter-chart">A Starter Chart</h2> - -<p>For this guide, we&rsquo;ll create a simple chart called <code>mychart</code>, and then we&rsquo;ll -create some templates inside of the chart.</p> - -<pre><code class="language-console">$ helm create mychart -Creating mychart -</code></pre> - -<p>From here on, we&rsquo;ll be working in the <code>mychart</code> directory.</p> - -<h3 id="a-quick-glimpse-of-mychart-templates">A Quick Glimpse of <code>mychart/templates/</code></h3> - -<p>If you take a look at the <code>mychart/templates/</code> directory, you&rsquo;ll notice a few files -already there.</p> - -<ul> -<li><code>NOTES.txt</code>: The &ldquo;help text&rdquo; for your chart. This will be displayed to your users -when they run <code>helm install</code>.</li> -<li><code>deployment.yaml</code>: A basic manifest for creating a Kubernetes <a href="http://kubernetes.io/docs/user-guide/deployments/">deployment</a></li> -<li><code>service.yaml</code>: A basic manifest for creating a <a href="http://kubernetes.io/docs/user-guide/services/">service endpoint</a> for your deployment</li> -<li><code>_helpers.tpl</code>: A place to put template helpers that you can re-use throughout the chart</li> -</ul> - -<p>And what we&rsquo;re going to do is&hellip; <em>remove them all!</em> That way we can work through our tutorial from scratch. We&rsquo;ll actually create our own <code>NOTES.txt</code> and <code>_helpers.tpl</code> as we go.</p> - -<pre><code class="language-console">$ rm -rf mychart/templates/*.* -</code></pre> - -<p>When you&rsquo;re writing production grade charts, having basic versions of these charts can be really useful. So in your day-to-day chart authoring, you probably won&rsquo;t want to remove them.</p> - -<h2 id="a-first-template">A First Template</h2> - -<p>The first template we are going to create will be a <code>ConfigMap</code>. In Kubernetes, -a ConfigMap is simply a container for storing configuration data. Other things, -like pods, can access the data in a ConfigMap.</p> - -<p>Because ConfigMaps are basic resources, they make a great starting point for us.</p> - -<p>Let&rsquo;s begin by creating a file called <code>mychart/templates/configmap.yaml</code>:</p> - -<pre><code class="language-yaml">apiVersion: v1 -kind: ConfigMap -metadata: - name: mychart-configmap -data: - myvalue: &quot;Hello World&quot; -</code></pre> - -<p><strong>TIP:</strong> Template names do not follow a rigid naming pattern. However, we recommend -using the suffix <code>.yaml</code> for YAML files and <code>.tpl</code> for helpers.</p> - -<p>The YAML file above is a bare-bones ConfigMap, having the minimal necessary fields. -In virtue of the fact that this file is in the <code>templates/</code> directory, it will -be sent through the template engine.</p> - -<p>It is just fine to put a plain YAML file like this in the <code>templates/</code> directory. -When Tiller reads this template, it will simply send it to Kubernetes as-is.</p> - -<p>With this simple template, we now have an installable chart. And we can install -it like this:</p> - -<pre><code class="language-console">$ helm install ./mychart -NAME: full-coral -LAST DEPLOYED: Tue Nov 1 17:36:01 2016 -NAMESPACE: default -STATUS: DEPLOYED - -RESOURCES: -==&gt; v1/ConfigMap -NAME DATA AGE -mychart-configmap 1 1m -</code></pre> - -<p>In the output above, we can see that our ConfigMap was created. Using Helm, we -can retrieve the release and see the actual template that was loaded.</p> - -<pre><code class="language-console">$ helm get manifest full-coral - ---- -# Source: mychart/templates/configmap.yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: mychart-configmap -data: - myvalue: &quot;Hello World&quot; -</code></pre> - -<p>The <code>helm get manifest</code> command takes a release name (<code>full-coral</code>) and prints -out all of the Kubernetes resources that were uploaded to the server. Each file -begins with <code>---</code> to indicate the start of a YAML document, and then is followed -by an automatically generated comment line that tells us what template file -generated this YAML document.</p> - -<p>From there on, we can see that the YAML data is exactly what we put in our -<code>configmap.yaml</code> file.</p> - -<p>Now we can delete our release: <code>helm delete full-coral</code>.</p> - -<h3 id="adding-a-simple-template-call">Adding a Simple Template Call</h3> - -<p>Hard-coding the <code>name:</code> into a resource is usually considered to be bad practice. -Names should be unique to a release. So we might want to generate a name field -by inserting the release name.</p> - -<p><strong>TIP:</strong> The <code>name:</code> field is limited to 63 characters because of limitations to -the DNS system. For that reason, release names are limited to 53 characters. -Kubernetes 1.3 and earlier limited to only 24 characters (thus 14 character names).</p> - -<p>Let&rsquo;s alter <code>configmap.yaml</code> accordingly.</p> - -<pre><code class="language-yaml">apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ .Release.Name }}-configmap -data: - myvalue: &quot;Hello World&quot; -</code></pre> - -<p>The big change comes in the value of the <code>name:</code> field, which is now -<code>{{ .Release.Name }}-configmap</code>.</p> - -<blockquote> -<p>A template directive is enclosed in <code>{{</code> and <code>}}</code> blocks.</p> -</blockquote> - -<p>The template directive <code>{{ .Release.Name }}</code> injects the release name into the template. The values that are passed into a template can be thought of as <em>namespaced objects</em>, where a dot (<code>.</code>) separates each namespaced element.</p> - -<p>The leading dot before <code>Release</code> indicates that we start with the top-most namespace for this scope (we&rsquo;ll talk about scope in a bit). So we could read <code>.Release.Name</code> as &ldquo;start at the top namespace, find the <code>Release</code> object, then look inside of it for an object called <code>Name</code>&rdquo;.</p> - -<p>The <code>Release</code> object is one of the built-in objects for Helm, and we&rsquo;ll cover it in more depth later. But for now, it is sufficient to say that this will display the release name that Tiller assigns to our release.</p> - -<p>Now when we install our resource, we&rsquo;ll immediately see the result of using this template directive:</p> - -<pre><code class="language-console">$ helm install ./mychart -NAME: clunky-serval -LAST DEPLOYED: Tue Nov 1 17:45:37 2016 -NAMESPACE: default -STATUS: DEPLOYED - -RESOURCES: -==&gt; v1/ConfigMap -NAME DATA AGE -clunky-serval-configmap 1 1m -</code></pre> - -<p>Note that in the <code>RESOURCES</code> section, the name we see there is <code>clunky-serval-configmap</code> -instead of <code>mychart-configmap</code>.</p> - -<p>You can run <code>helm get manifest clunky-serval</code> to see the entire generated YAML.</p> - -<p>At this point, we&rsquo;ve seen templates at their most basic: YAML files that have template directives embedded in <code>{{</code> and <code>}}</code>. In the next part, we&rsquo;ll take a deeper look into templates. But before moving on, there&rsquo;s one quick trick that can make building templates faster: When you want to test the template rendering, but not actually install anything, you can use <code>helm install --debug --dry-run ./mychart</code>. This will send the chart to the Tiller server, which will render the templates. But instead of installing the chart, it will return the rendered template to you so you can see the output:</p> - -<pre><code class="language-console">$ helm install --debug --dry-run ./mychart -SERVER: &quot;localhost:44134&quot; -CHART PATH: /Users/mattbutcher/Code/Go/src/k8s.io/helm/_scratch/mychart -NAME: goodly-guppy -TARGET NAMESPACE: default -CHART: mychart 0.1.0 -MANIFEST: ---- -# Source: mychart/templates/configmap.yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: goodly-guppy-configmap -data: - myvalue: &quot;Hello World&quot; - -</code></pre> - -<p>Using <code>--dry-run</code> will make it easier to test your code, but it won&rsquo;t ensure that Kubernetes itself will accept the templates you generate. It&rsquo;s best not to assume that your chart will install just because <code>--dry-run</code> works.</p> - -<p>In the next few sections, we&rsquo;ll take the basic chart we defined here and explore the Helm template language in detail. And we&rsquo;ll get started with built-in objects.</p> - -<h1 id="built-in-objects">Built-in Objects</h1> - -<p>Objects are passed into a template from the template engine. And your code can pass objects around (we&rsquo;ll see examples when we look at the <code>with</code> and <code>range</code> statements). There are even a few ways to create new objects within your templates, like with the <code>tuple</code> function we&rsquo;ll see later.</p> - -<p>Objects can be simple, and have just one value. Or they can contain other objects or functions. For example. the <code>Release</code> object contains several objects (like <code>Release.Name</code>) and the <code>Files</code> object has a few functions.</p> - -<p>In the previous section, we use <code>{{.Release.Name}}</code> to insert the name of a release into a template. <code>Release</code> is one of the top-level objects that you can access in your templates.</p> - -<ul> -<li><code>Release</code>: This object describes the release itself. It has several objects inside of it: - -<ul> -<li><code>Release.Name</code>: The release name</li> -<li><code>Release.Time</code>: The time of the release</li> -<li><code>Release.Namespace</code>: The namespace to be released into (if the manifest doesn&rsquo;t override)</li> -<li><code>Release.Service</code>: The name of the releasing service (always <code>Tiller</code>).</li> -<li><code>Release.Revision</code>: The revision number of this release. It begins at 1 and is incremented for each <code>helm upgrade</code>.</li> -<li><code>Release.IsUpgrade</code>: This is set to <code>true</code> if the current operation is an upgrade or rollback.</li> -<li><code>Release.IsInstall</code>: This is set to <code>true</code> if the current operation is an install.</li> -</ul></li> -<li><code>Values</code>: Values passed into the template from the <code>values.yaml</code> file and from user-supplied files. By default, <code>Values</code> is empty.</li> -<li><code>Chart</code>: The contents of the <code>Chart.yaml</code> file. Any data in <code>Chart.yaml</code> will be accessible here. For example <code>{{.Chart.Name}}-{{.Chart.Version}}</code> will print out the <code>mychart-0.1.0</code>. - -<ul> -<li>The available fields are listed in the <a href="https://github.com/kubernetes/helm/blob/master/docs/charts.md#the-chartyaml-file">Charts Guide</a></li> -</ul></li> -<li><code>Files</code>: This provides access to all non-special files in a chart. While you cannot use it to access templates, you can use it to access other files in the chart. See the section <em>Accessing Files</em> for more. - -<ul> -<li><code>Files.Get</code> is a function for getting a file by name (<code>.Files.Get config.ini</code>)</li> -<li><code>Files.GetBytes</code> is a function for getting the contents of a file as an array of bytes instead of as a string. This is useful for things like images.</li> -</ul></li> -<li><code>Capabilities</code>: This provides information about what capabilities the Kubernetes cluster supports. - -<ul> -<li><code>Capabilities.APIVersions</code> is a set of versions.</li> -<li><code>Capabilities.APIVersions.Has $version</code> indicates whether a version (<code>batch/v1</code>) is enabled on the cluster.</li> -<li><code>Capabilities.KubeVersion</code> provides a way to look up the Kubernetes version. It has the following values: <code>Major</code>, <code>Minor</code>, <code>GitVersion</code>, <code>GitCommit</code>, <code>GitTreeState</code>, <code>BuildDate</code>, <code>GoVersion</code>, <code>Compiler</code>, and <code>Platform</code>.</li> -<li><code>Capabilities.TillerVersion</code> provides a way to look up the Tiller version. It has the following values: <code>SemVer</code>, <code>GitCommit</code>, and <code>GitTreeState</code>.</li> -</ul></li> -<li><code>Template</code>: Contains information about the current template that is being executed - -<ul> -<li><code>Name</code>: A namespaced filepath to the current template (e.g. <code>mychart/templates/mytemplate.yaml</code>)</li> -<li><code>BasePath</code>: The namespaced path to the templates directory of the current chart (e.g. <code>mychart/templates</code>).</li> -</ul></li> -</ul> - -<p>The values are available to any top-level template. As we will see later, this does not necessarily mean that they will be available <em>everywhere</em>.</p> - -<p>The built-in values always begin with a capital letter. This is in keeping with Go&rsquo;s naming convention. When you create your own names, you are free to use a convention that suits your team. Some teams, like the <a href="https://github.com/kubernetes/charts">Kubernetes Charts</a> team, choose to use only initial lower case letters in order to distinguish local names from those built-in. In this guide, we follow that convention.</p> - -<h1 id="values-files">Values Files</h1> - -<p>In the previous section we looked at the built-in objects that Helm templates offer. One of the four built-in objects is <code>Values</code>. This object provides access to values passed into the chart. Its contents come from four sources:</p> - -<ul> -<li>The <code>values.yaml</code> file in the chart</li> -<li>If this is a subchart, the <code>values.yaml</code> file of a parent chart</li> -<li>A values file if passed into <code>helm install</code> or <code>helm update</code> with the <code>-f</code> flag (<code>helm install -f myvals.yaml ./mychart</code>)</li> -<li>Individual parameters passed with <code>--set</code> (such as <code>helm install --set foo=bar ./mychart</code>)</li> -</ul> - -<p>The list above is in order of specificity: <code>values.yaml</code> is the default, which can be overridden by a parent chart&rsquo;s <code>values.yaml</code>, which can in turn be overridden by a user-supplied values file, which can in turn be overridden by <code>--set</code> parameters.</p> - -<p>Values files are plain YAML files. Let&rsquo;s edit <code>mychart/values.yaml</code> and then edit our ConfigMap template.</p> - -<p>Removing the defaults in <code>values.yaml</code>, we&rsquo;ll set just one parameter:</p> - -<pre><code class="language-yaml">favoriteDrink: coffee -</code></pre> - -<p>Now we can use this inside of a template:</p> - -<pre><code class="language-yaml">apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ .Release.Name }}-configmap -data: - myvalue: &quot;Hello World&quot; - drink: {{ .Values.favoriteDrink }} -</code></pre> - -<p>Notice on the last line we access <code>favoriteDrink</code> as an attribute of <code>Values</code>: <code>{{ .Values.favoriteDrink}}</code>.</p> - -<p>Let&rsquo;s see how this renders.</p> - -<pre><code class="language-console">$ helm install --dry-run --debug ./mychart -SERVER: &quot;localhost:44134&quot; -CHART PATH: /Users/mattbutcher/Code/Go/src/k8s.io/helm/_scratch/mychart -NAME: geared-marsupi -TARGET NAMESPACE: default -CHART: mychart 0.1.0 -MANIFEST: ---- -# Source: mychart/templates/configmap.yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: geared-marsupi-configmap -data: - myvalue: &quot;Hello World&quot; - drink: coffee -</code></pre> - -<p>Because <code>favoriteDrink</code> is set in the default <code>values.yaml</code> file to <code>coffee</code>, that&rsquo;s the value displayed in the template. We can easily override that by adding a <code>--set</code> flag in our call to <code>helm install</code>:</p> - -<pre><code>helm install --dry-run --debug --set favoriteDrink=slurm ./mychart -SERVER: &quot;localhost:44134&quot; -CHART PATH: /Users/mattbutcher/Code/Go/src/k8s.io/helm/_scratch/mychart -NAME: solid-vulture -TARGET NAMESPACE: default -CHART: mychart 0.1.0 -MANIFEST: ---- -# Source: mychart/templates/configmap.yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: solid-vulture-configmap -data: - myvalue: &quot;Hello World&quot; - drink: slurm -</code></pre> - -<p>Since <code>--set</code> has a higher precedence than the default <code>values.yaml</code> file, our template generates <code>drink: slurm</code>.</p> - -<p>Values files can contain more structured content, too. For example, we could create a <code>favorite</code> section in our <code>values.yaml</code> file, and then add several keys there:</p> - -<pre><code class="language-yaml">favorite: - drink: coffee - food: pizza -</code></pre> - -<p>Now we would have to modify the template slightly:</p> - -<pre><code>apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ .Release.Name }}-configmap -data: - myvalue: &quot;Hello World&quot; - drink: {{ .Values.favorite.drink }} - food: {{ .Values.favorite.food }} -</code></pre> - -<p>While structuring data this way is possible, the recommendation is that you keep your values trees shallow, favoring flatness. When we look at assigning values to subcharts, we&rsquo;ll see how values are named using a tree structure.</p> - -<h2 id="deleting-a-default-key">Deleting a default key</h2> - -<p>If you need to delete a key from the default values, you may override the value of the key to be <code>null</code>, in which case Helm will remove the key from the overridden values merge.</p> - -<p>For example, the stable Drupal chart allows configuring the liveness probe, in case you configure a custom image. Here are the default values:</p> - -<pre><code class="language-yaml">livenessProbe: - httpGet: - path: /user/login - port: http - initialDelaySeconds: 120 -</code></pre> - -<p>If you try to override the livenessProbe handler to <code>exec</code> instead of <code>httpGet</code> using <code>--set livenessProbe.exec.command=[cat,docroot/CHANGELOG.txt]</code>, Helm will coalesce the default and overridden keys together, resulting in the following YAML:</p> - -<pre><code class="language-yaml">livenessProbe: - httpGet: - path: /user/login - port: http - exec: - command: - - cat - - docroot/CHANGELOG.txt - initialDelaySeconds: 120 -</code></pre> - -<p>However, Kubernetes would then fail because you can not declare more than one livenessProbe handler. To overcome this, you may instruct Helm to delete the <code>livenessProbe.httpGet</code> by setting it to null:</p> - -<pre><code class="language-sh">helm install stable/drupal --set image=my-registry/drupal:0.1.0 --set livenessProbe.exec.command=[cat,docroot/CHANGELOG.txt] --set livenessProbe.httpGet=null -</code></pre> - -<p>At this point, we&rsquo;ve seen several built-in objects, and used them to inject information into a template. Now we will take a look at another aspect of the template engine: functions and pipelines.</p> - -<h1 id="template-functions-and-pipelines">Template Functions and Pipelines</h1> - -<p>So far, we&rsquo;ve seen how to place information into a template. But that information is placed into the template unmodified. Sometimes we want to transform the supplied data in a way that makes it more useable to us.</p> - -<p>Let&rsquo;s start with a best practice: When injecting strings from the <code>.Values</code> object into the template, we ought to quote these strings. We can do that by calling the <code>quote</code> function in the template directive:</p> - -<pre><code>apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ .Release.Name }}-configmap -data: - myvalue: &quot;Hello World&quot; - drink: {{ quote .Values.favorite.drink }} - food: {{ quote .Values.favorite.food }} -</code></pre> - -<p>Template functions follow the syntax <code>functionName arg1 arg2...</code>. In the snippet above, <code>quote .Values.favorite.drink</code> calls the <code>quote</code> function and passes it a single argument.</p> - -<p>Helm has over 60 available functions. Some of them are defined by the <a href="https://godoc.org/text/template">Go template language</a> itself. Most of the others are part of the <a href="https://godoc.org/github.com/Masterminds/sprig">Sprig template library</a>. We&rsquo;ll see many of them as we progress through the examples.</p> - -<blockquote> -<p>While we talk about the &ldquo;Helm template language&rdquo; as if it is Helm-specific, it is actually a combination of the Go template language, some extra functions, and a variety of wrappers to expose certain objects to the templates. Many resources on Go templates may be helpful as you learn about templating.</p> -</blockquote> - -<h2 id="pipelines">Pipelines</h2> - -<p>One of the powerful features of the template language is its concept of <em>pipelines</em>. Drawing on a concept from UNIX, pipelines are a tool for chaining together a series of template commands to compactly express a series of transformations. In other words, pipelines are an efficient way of getting several things done in sequence. Let&rsquo;s rewrite the above example using a pipeline.</p> - -<pre><code class="language-yaml">apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ .Release.Name }}-configmap -data: - myvalue: &quot;Hello World&quot; - drink: {{ .Values.favorite.drink | quote }} - food: {{ .Values.favorite.food | quote }} -</code></pre> - -<p>In this example, instead of calling <code>quote ARGUMENT</code>, we inverted the order. We &ldquo;sent&rdquo; the argument to the function using a pipeline (<code>|</code>): <code>.Values.favorite.drink | quote</code>. Using pipelines, we can chain several functions together:</p> - -<pre><code class="language-yaml">apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ .Release.Name }}-configmap -data: - myvalue: &quot;Hello World&quot; - drink: {{ .Values.favorite.drink | quote }} - food: {{ .Values.favorite.food | upper | quote }} -</code></pre> - -<blockquote> -<p>Inverting the order is a common practice in templates. You will see <code>.val | quote</code> more often than <code>quote .val</code>. Either practice is fine.</p> -</blockquote> - -<p>When evaluated, that template will produce this:</p> - -<pre><code class="language-yaml"># Source: mychart/templates/configmap.yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: trendsetting-p-configmap -data: - myvalue: &quot;Hello World&quot; - drink: &quot;coffee&quot; - food: &quot;PIZZA&quot; -</code></pre> - -<p>Note that our original <code>pizza</code> has now been transformed to <code>&quot;PIZZA&quot;</code>.</p> - -<p>When pipelining arguments like this, the result of the first evaluation (<code>.Values.favorite.drink</code>) is sent as the <em>last argument to the function</em>. We can modify the drink example above to illustrate with a function that takes two arguments: <code>repeat COUNT STRING</code>:</p> - -<pre><code class="language-yaml">apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ .Release.Name }}-configmap -data: - myvalue: &quot;Hello World&quot; - drink: {{ .Values.favorite.drink | repeat 5 | quote }} - food: {{ .Values.favorite.food | upper | quote }} -</code></pre> - -<p>The <code>repeat</code> function will echo the given string the given number of times, so we will get this for output:</p> - -<pre><code class="language-yaml"># Source: mychart/templates/configmap.yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: melting-porcup-configmap -data: - myvalue: &quot;Hello World&quot; - drink: &quot;coffeecoffeecoffeecoffeecoffee&quot; - food: &quot;PIZZA&quot; -</code></pre> - -<h2 id="using-the-default-function">Using the <code>default</code> function</h2> - -<p>One function frequently used in templates is the <code>default</code> function: <code>default DEFAULT_VALUE GIVEN_VALUE</code>. This function allows you to specify a default value inside of the template, in case the value is omitted. Let&rsquo;s use it to modify the drink example above:</p> - -<pre><code class="language-yaml">drink: {{ .Values.favorite.drink | default &quot;tea&quot; | quote }} -</code></pre> - -<p>If we run this as normal, we&rsquo;ll get our <code>coffee</code>:</p> - -<pre><code># Source: mychart/templates/configmap.yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: virtuous-mink-configmap -data: - myvalue: &quot;Hello World&quot; - drink: &quot;coffee&quot; - food: &quot;PIZZA&quot; -</code></pre> - -<p>Now, we will remove the favorite drink setting from <code>values.yaml</code>:</p> - -<pre><code class="language-yaml">favorite: - #drink: coffee - food: pizza -</code></pre> - -<p>Now re-running <code>helm install --dry-run --debug ./mychart</code> will produce this YAML:</p> - -<pre><code class="language-yaml"># Source: mychart/templates/configmap.yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: fair-worm-configmap -data: - myvalue: &quot;Hello World&quot; - drink: &quot;tea&quot; - food: &quot;PIZZA&quot; -</code></pre> - -<p>In an actual chart, all static default values should live in the values.yaml, and should not be repeated using the <code>default</code> command (otherwise they would be redundant). However, the <code>default</code> command is perfect for computed values, which can not be declared inside values.yaml. For example:</p> - -<pre><code class="language-yaml">drink: {{ .Values.favorite.drink | default (printf &quot;%s-tea&quot; (include &quot;fullname&quot; .)) }} -</code></pre> - -<p>In some places, an <code>if</code> conditional guard may be better suited than <code>default</code>. We&rsquo;ll see those in the next section.</p> - -<p>Template functions and pipelines are a powerful way to transform information and then insert it into your YAML. But sometimes it&rsquo;s necessary to add some template logic that is a little more sophisticated than just inserting a string. In the next section we will look at the control structures provided by the template language.</p> - -<h2 id="operators-are-functions">Operators are functions</h2> - -<p>For templates, the operators (<code>eq</code>, <code>ne</code>, <code>lt</code>, <code>gt</code>, <code>and</code>, <code>or</code> and so on) are all implemented as functions. In pipelines, operations can be grouped with parentheses (<code>(</code>, and <code>)</code>).</p> - -<p>Now we can turn from functions and pipelines to flow control with conditions, loops, and scope modifiers.</p> - -<h1 id="flow-control">Flow Control</h1> - -<p>Control structures (called &ldquo;actions&rdquo; in template parlance) provide you, the template author, with the ability to control the flow of a template&rsquo;s generation. Helm&rsquo;s template language provides the following control structures:</p> - -<ul> -<li><code>if</code>/<code>else</code> for creating conditional blocks</li> -<li><code>with</code> to specify a scope</li> -<li><code>range</code>, which provides a &ldquo;for each&rdquo;-style loop</li> -</ul> - -<p>In addition to these, it provides a few actions for declaring and using named template segments:</p> - -<ul> -<li><code>define</code> declares a new named template inside of your template</li> -<li><code>template</code> imports a named template</li> -<li><code>block</code> declares a special kind of fillable template area</li> -</ul> - -<p>In this section, we&rsquo;ll talk about <code>if</code>, <code>with</code>, and <code>range</code>. The others are covered in the &ldquo;Named Templates&rdquo; section later in this guide.</p> - -<h2 id="if-else">If/Else</h2> - -<p>The first control structure we&rsquo;ll look at is for conditionally including blocks of text in a template. This is the <code>if</code>/<code>else</code> block.</p> - -<p>The basic structure for a conditional looks like this:</p> - -<pre><code>{{ if PIPELINE }} - # Do something -{{ else if OTHER PIPELINE }} - # Do something else -{{ else }} - # Default case -{{ end }} -</code></pre> - -<p>Notice that we&rsquo;re now talking about <em>pipelines</em> instead of values. The reason for this is to make it clear that control structures can execute an entire pipeline, not just evaluate a value.</p> - -<p>A pipeline is evaluated as <em>false</em> if the value is:</p> - -<ul> -<li>a boolean false</li> -<li>a numeric zero</li> -<li>an empty string</li> -<li>a <code>nil</code> (empty or null)</li> -<li>an empty collection (<code>map</code>, <code>slice</code>, <code>tuple</code>, <code>dict</code>, <code>array</code>)</li> -</ul> - -<p>Under all other conditions, the condition is true.</p> - -<p>Let&rsquo;s add a simple conditional to our ConfigMap. We&rsquo;ll add another setting if the drink is set to coffee:</p> - -<pre><code class="language-yaml">apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ .Release.Name }}-configmap -data: - myvalue: &quot;Hello World&quot; - drink: {{ .Values.favorite.drink | default &quot;tea&quot; | quote }} - food: {{ .Values.favorite.food | upper | quote }} - {{ if eq .Values.favorite.drink &quot;coffee&quot; }}mug: true{{ end }} -</code></pre> - -<p>Since we commented out <code>drink: coffee</code> in our last example, the output should not include a <code>mug: true</code> flag. But if we add that line back into our <code>values.yaml</code> file, the output should look like this:</p> - -<pre><code class="language-yaml"># Source: mychart/templates/configmap.yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: eyewitness-elk-configmap -data: - myvalue: &quot;Hello World&quot; - drink: &quot;coffee&quot; - food: &quot;PIZZA&quot; - mug: true -</code></pre> - -<h2 id="controlling-whitespace">Controlling Whitespace</h2> - -<p>While we&rsquo;re looking at conditionals, we should take a quick look at the way whitespace is controlled in templates. Let&rsquo;s take the previous example and format it to be a little easier to read:</p> - -<pre><code>apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ .Release.Name }}-configmap -data: - myvalue: &quot;Hello World&quot; - drink: {{ .Values.favorite.drink | default &quot;tea&quot; | quote }} - food: {{ .Values.favorite.food | upper | quote }} - {{if eq .Values.favorite.drink &quot;coffee&quot;}} - mug: true - {{end}} -</code></pre> - -<p>Initially, this looks good. But if we run it through the template engine, we&rsquo;ll get an unfortunate result:</p> - -<pre><code class="language-console">$ helm install --dry-run --debug ./mychart -SERVER: &quot;localhost:44134&quot; -CHART PATH: /Users/mattbutcher/Code/Go/src/k8s.io/helm/_scratch/mychart -Error: YAML parse error on mychart/templates/configmap.yaml: error converting YAML to JSON: yaml: line 9: did not find expected key -</code></pre> - -<p>What happened? We generated incorrect YAML because of the whitespacing above.</p> - -<pre><code class="language-yaml"># Source: mychart/templates/configmap.yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: eyewitness-elk-configmap -data: - myvalue: &quot;Hello World&quot; - drink: &quot;coffee&quot; - food: &quot;PIZZA&quot; - mug: true -</code></pre> - -<p><code>mug</code> is incorrectly indented. Let&rsquo;s simply out-dent that one line, and re-run:</p> - -<pre><code>apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ .Release.Name }}-configmap -data: - myvalue: &quot;Hello World&quot; - drink: {{ .Values.favorite.drink | default &quot;tea&quot; | quote }} - food: {{ .Values.favorite.food | upper | quote }} - {{if eq .Values.favorite.drink &quot;coffee&quot;}} - mug: true - {{end}} -</code></pre> - -<p>When we sent that, we&rsquo;ll get YAML that is valid, but still looks a little funny:</p> - -<pre><code class="language-yaml"># Source: mychart/templates/configmap.yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: telling-chimp-configmap -data: - myvalue: &quot;Hello World&quot; - drink: &quot;coffee&quot; - food: &quot;PIZZA&quot; - - mug: true - -</code></pre> - -<p>Notice that we received a few empty lines in our YAML. Why? When the template engine runs, it <em>removes</em> the contents inside of <code>{{</code> and <code>}}</code>, but it leaves the remaining whitespace exactly as is.</p> - -<p>YAML ascribes meaning to whitespace, so managing the whitespace becomes pretty important. Fortunately, Helm templates have a few tools to help.</p> - -<p>First, the curly brace syntax of template declarations can be modified with special characters to tell the template engine to chomp whitespace. <code>{{-</code> (with the dash and space added) indicates that whitespace should be chomped left, while <code>-}}</code> means whitespace to the right should be consumed. <em>Be careful! Newlines are whitespace!</em></p> - -<blockquote> -<p>Make sure there is a space between the <code>-</code> and the rest of your directive. <code>{{- 3 }}</code> means &ldquo;trim left whitespace and print 3&rdquo; while <code>{{-3}}</code> means &ldquo;print -3&rdquo;.</p> -</blockquote> - -<p>Using this syntax, we can modify our template to get rid of those new lines:</p> - -<pre><code class="language-yaml">apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ .Release.Name }}-configmap -data: - myvalue: &quot;Hello World&quot; - drink: {{ .Values.favorite.drink | default &quot;tea&quot; | quote }} - food: {{ .Values.favorite.food | upper | quote }} - {{- if eq .Values.favorite.drink &quot;coffee&quot;}} - mug: true - {{- end}} -</code></pre> - -<p>Just for the sake of making this point clear, let&rsquo;s adjust the above, and substitute an <code>*</code> for each whitespace that will be deleted following this rule. an <code>*</code> at the end of the line indicates a newline character that would be removed</p> - -<pre><code class="language-yaml">apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ .Release.Name }}-configmap -data: - myvalue: &quot;Hello World&quot; - drink: {{ .Values.favorite.drink | default &quot;tea&quot; | quote }} - food: {{ .Values.favorite.food | upper | quote }}* -**{{- if eq .Values.favorite.drink &quot;coffee&quot;}} - mug: true* -**{{- end}} - -</code></pre> - -<p>Keeping that in mind, we can run our template through Helm and see the result:</p> - -<pre><code class="language-yaml"># Source: mychart/templates/configmap.yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: clunky-cat-configmap -data: - myvalue: &quot;Hello World&quot; - drink: &quot;coffee&quot; - food: &quot;PIZZA&quot; - mug: true -</code></pre> - -<p>Be careful with the chomping modifiers. It is easy to accidentally do things like this:</p> - -<pre><code class="language-yaml"> food: {{ .Values.favorite.food | upper | quote }} - {{- if eq .Values.favorite.drink &quot;coffee&quot; -}} - mug: true - {{- end -}} - -</code></pre> - -<p>That will produce <code>food: &quot;PIZZA&quot;mug:true</code> because it consumed newlines on both sides.</p> - -<blockquote> -<p>For the details on whitespace control in templates, see the <a href="https://godoc.org/text/template">Official Go template documentation</a></p> -</blockquote> - -<p>Finally, sometimes it&rsquo;s easier to tell the template system how to indent for you instead of trying to master the spacing of template directives. For that reason, you may sometimes find it useful to use the <code>indent</code> function (<code>{{indent 2 &quot;mug:true&quot;}}</code>).</p> - -<h2 id="modifying-scope-using-with">Modifying scope using <code>with</code></h2> - -<p>The next control structure to look at is the <code>with</code> action. This controls variable scoping. Recall that <code>.</code> is a reference to <em>the current scope</em>. So <code>.Values</code> tells the template to find the <code>Values</code> object in the current scope.</p> - -<p>The syntax for <code>with</code> is similar to a simple <code>if</code> statement:</p> - -<pre><code>{{ with PIPELINE }} - # restricted scope -{{ end }} -</code></pre> - -<p>Scopes can be changed. <code>with</code> can allow you to set the current scope (<code>.</code>) to a particular object. For example, we&rsquo;ve been working with <code>.Values.favorites</code>. Let&rsquo;s rewrite our ConfigMap to alter the <code>.</code> scope to point to <code>.Values.favorites</code>:</p> - -<pre><code class="language-yaml">apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ .Release.Name }}-configmap -data: - myvalue: &quot;Hello World&quot; - {{- with .Values.favorite }} - drink: {{ .drink | default &quot;tea&quot; | quote }} - food: {{ .food | upper | quote }} - {{- end }} -</code></pre> - -<p>(Note that we removed the <code>if</code> conditional from the previous exercise)</p> - -<p>Notice that now we can reference <code>.drink</code> and <code>.food</code> without qualifying them. That is because the <code>with</code> statement sets <code>.</code> to point to <code>.Values.favorite</code>. The <code>.</code> is reset to its previous scope after <code>{{ end }}</code>.</p> - -<p>But here&rsquo;s a note of caution! Inside of the restricted scope, you will not be able to access the other objects from the parent scope. This, for example, will fail:</p> - -<pre><code class="language-yaml"> {{- with .Values.favorite }} - drink: {{ .drink | default &quot;tea&quot; | quote }} - food: {{ .food | upper | quote }} - release: {{ .Release.Name }} - {{- end }} -</code></pre> - -<p>It will produce an error because <code>Release.Name</code> is not inside of the restricted scope for <code>.</code>. However, if we swap the last two lines, all will work as expected because the scope is reset after <code>{{end}}</code>.</p> - -<pre><code class="language-yaml"> {{- with .Values.favorite }} - drink: {{ .drink | default &quot;tea&quot; | quote }} - food: {{ .food | upper | quote }} - {{- end }} - release: {{ .Release.Name }} -</code></pre> - -<p>After looking a <code>range</code>, we will take a look at template variables, which offer one solution to the scoping issue above.</p> - -<h2 id="looping-with-the-range-action">Looping with the <code>range</code> action</h2> - -<p>Many programming languages have support for looping using <code>for</code> loops, <code>foreach</code> loops, or similar functional mechanisms. In Helm&rsquo;s template language, the way to iterate through a collection is to use the <code>range</code> operator.</p> - -<p>To start, let&rsquo;s add a list of pizza toppings to our <code>values.yaml</code> file:</p> - -<pre><code class="language-yaml">favorite: - drink: coffee - food: pizza -pizzaToppings: - - mushrooms - - cheese - - peppers - - onions -</code></pre> - -<p>Now we have a list (called a <code>slice</code> in templates) of <code>pizzaToppings</code>. We can modify our template to print this list into our ConfigMap:</p> - -<pre><code class="language-yaml">apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ .Release.Name }}-configmap -data: - myvalue: &quot;Hello World&quot; - {{- with .Values.favorite }} - drink: {{ .drink | default &quot;tea&quot; | quote }} - food: {{ .food | upper | quote }} - {{- end }} - toppings: |- - {{- range .Values.pizzaToppings }} - - {{ . | title | quote }} - {{- end }} - -</code></pre> - -<p>Let&rsquo;s take a closer look at the <code>toppings:</code> list. The <code>range</code> function will &ldquo;range over&rdquo; (iterate through) the <code>pizzaToppings</code> list. But now something interesting happens. Just like <code>with</code> sets the scope of <code>.</code>, so does a <code>range</code> operator. Each time through the loop, <code>.</code> is set to the current pizza topping. That is, the first time, <code>.</code> is set to <code>mushrooms</code>. The second iteration it is set to <code>cheese</code>, and so on.</p> - -<p>We can send the value of <code>.</code> directly down a pipeline, so when we do <code>{{ . | title | quote }}</code>, it sends <code>.</code> to <code>title</code> (title case function) and then to <code>quote</code>. If we run this template, the output will be:</p> - -<pre><code class="language-yaml"># Source: mychart/templates/configmap.yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: edgy-dragonfly-configmap -data: - myvalue: &quot;Hello World&quot; - drink: &quot;coffee&quot; - food: &quot;PIZZA&quot; - toppings: |- - - &quot;Mushrooms&quot; - - &quot;Cheese&quot; - - &quot;Peppers&quot; - - &quot;Onions&quot; -</code></pre> - -<p>Now, in this example we&rsquo;ve done something tricky. The <code>toppings: |-</code> line is declaring a multi-line string. So our list of toppings is actually not a YAML list. It&rsquo;s a big string. Why would we do this? Because the data in ConfigMaps <code>data</code> is composed of key/value pairs, where both the key and the value are simple strings. To understand why this is the case, take a look at the <a href="http://kubernetes.io/docs/user-guide/configmap/">Kubernetes ConfigMap docs</a>. For us, though, this detail doesn&rsquo;t matter much.</p> - -<blockquote> -<p>The <code>|-</code> marker in YAML takes a multi-line string. This can be a useful technique for embedding big blocks of data inside of your manifests, as exemplified here.</p> -</blockquote> - -<p>Sometimes it&rsquo;s useful to be able to quickly make a list inside of your template, and then iterate over that list. Helm templates have a function to make this easy: <code>tuple</code>. In computer science, a tuple is a list-like collection of fixed size, but with arbitrary data types. This roughly conveys the way a <code>tuple</code> is used.</p> - -<pre><code class="language-yaml"> sizes: |- - {{- range tuple &quot;small&quot; &quot;medium&quot; &quot;large&quot; }} - - {{ . }} - {{- end }} -</code></pre> - -<p>The above will produce this:</p> - -<pre><code class="language-yaml"> sizes: |- - - small - - medium - - large -</code></pre> - -<p>In addition to lists and tuples, <code>range</code> can be used to iterate over collections that have a key and a value (like a <code>map</code> or <code>dict</code>). We&rsquo;ll see how to do that in the next section when we introduce template variables.</p> - -<h1 id="variables">Variables</h1> - -<p>With functions, pipelines, objects, and control structures under our belts, we can turn to one of the more basic ideas in many programming languages: variables. In templates, they are less frequently used. But we will see how to use them to simplify code, and to make better use of <code>with</code> and <code>range</code>.</p> - -<p>In an earlier example, we saw that this code will fail:</p> - -<pre><code class="language-yaml"> {{- with .Values.favorite }} - drink: {{ .drink | default &quot;tea&quot; | quote }} - food: {{ .food | upper | quote }} - release: {{ .Release.Name }} - {{- end }} -</code></pre> - -<p><code>Release.Name</code> is not inside of the scope that&rsquo;s restricted in the <code>with</code> block. One way to work around scoping issues is to assign objects to variables that can be accessed without respect to the present scope.</p> - -<p>In Helm templates, a variable is a named reference to another object. It follows the form <code>$name</code>. Variables are assigned with a special assignment operator: <code>:=</code>. We can rewrite the above to use a variable for <code>Release.Name</code>.</p> - -<pre><code class="language-yaml">apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ .Release.Name }}-configmap -data: - myvalue: &quot;Hello World&quot; - {{- $relname := .Release.Name -}} - {{- with .Values.favorite }} - drink: {{ .drink | default &quot;tea&quot; | quote }} - food: {{ .food | upper | quote }} - release: {{ $relname }} - {{- end }} -</code></pre> - -<p>Notice that before we start the <code>with</code> block, we assign <code>$relname := .Release.Name</code>. Now inside of the <code>with</code> block, the <code>$relname</code> variable still points to the release name.</p> - -<p>Running that will produce this:</p> - -<pre><code class="language-yaml"># Source: mychart/templates/configmap.yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: viable-badger-configmap -data: - myvalue: &quot;Hello World&quot; - drink: &quot;coffee&quot; - food: &quot;PIZZA&quot; - release: viable-badger -</code></pre> - -<p>Variables are particularly useful in <code>range</code> loops. They can be used on list-like objects to capture both the index and the value:</p> - -<pre><code class="language-yaml"> toppings: |- - {{- range $index, $topping := .Values.pizzaToppings }} - {{ $index }}: {{ $topping }} - {{- end }} - -</code></pre> - -<p>Note that <code>range</code> comes first, then the variables, then the assignment operator, then the list. This will assign the integer index (starting from zero) to <code>$index</code> and the value to <code>$topping</code>. Running it will produce:</p> - -<pre><code class="language-yaml"> toppings: |- - 0: mushrooms - 1: cheese - 2: peppers - 3: onions -</code></pre> - -<p>For data structures that have both a key and a value, we can use <code>range</code> to get both. For example, we can loop through <code>.Values.favorite</code> like this:</p> - -<pre><code class="language-yaml">apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ .Release.Name }}-configmap -data: - myvalue: &quot;Hello World&quot; - {{- range $key, $val := .Values.favorite }} - {{ $key }}: {{ $val | quote }} - {{- end}} -</code></pre> - -<p>Now on the first iteration, <code>$key</code> will be <code>drink</code> and <code>$val</code> will be <code>coffee</code>, and on the second, <code>$key</code> will be <code>food</code> and <code>$val</code> will be <code>pizza</code>. Running the above will generate this:</p> - -<pre><code class="language-yaml"># Source: mychart/templates/configmap.yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: eager-rabbit-configmap -data: - myvalue: &quot;Hello World&quot; - drink: &quot;coffee&quot; - food: &quot;pizza&quot; -</code></pre> - -<p>Variables are normally not &ldquo;global&rdquo;. They are scoped to the block in which they are declared. Earlier, we assigned <code>$relname</code> in the top level of the template. That variable will be in scope for the entire template. But in our last example, <code>$key</code> and <code>$val</code> will only be in scope inside of the <code>{{range...}}{{end}}</code> block.</p> - -<p>However, there is one variable that is always global - <code>$</code> - this -variable will always point to the root context. This can be very -useful when you are looping in a range need to know the chart&rsquo;s release -name.</p> - -<p>An example illustrating this:</p> - -<pre><code class="language-yaml">{{- range .Values.tlsSecrets }} -apiVersion: v1 -kind: Secret -metadata: - name: {{ .name }} - labels: - # Many helm templates would use `.` below, but that will not work, - # however `$` will work here - app: {{ template &quot;fullname&quot; $ }} - # I cannot reference .Chart.Name, but I can do $.Chart.Name - chart: &quot;{{ $.Chart.Name }}-{{ $.Chart.Version }}&quot; - release: &quot;{{ $.Release.Name }}&quot; - heritage: &quot;{{ $.Release.Service }}&quot; -type: kubernetes.io/tls -data: - tls.crt: {{ .certificate }} - tls.key: {{ .key }} ---- -{{- end }} -</code></pre> - -<p>So far we have looked at just one template declared in just one file. But one of the powerful features of the Helm template language is its ability to declare multiple templates and use them together. We&rsquo;ll turn to that in the next section.</p> - -<h1 id="named-templates">Named Templates</h1> - -<p>It is time to move beyond one template, and begin to create others. In this section, we will see how to define <em>named templates</em> in one file, and then use them elsewhere. A <em>named template</em> (sometimes called a <em>partial</em> or a <em>subtemplate</em>) is simply a template defined inside of a file, and given a name. We&rsquo;ll see two ways to create them, and a few different ways to use them.</p> - -<p>In the &ldquo;Flow Control&rdquo; section we introduced three actions for declaring and managing templates: <code>define</code>, <code>template</code>, and <code>block</code>. In this section, we&rsquo;ll cover those three actions, and also introduce a special-purpose <code>include</code> function that works similarly to the <code>template</code> action.</p> - -<h2 id="partials-and-files">Partials and <code>_</code> files</h2> - -<p>So far, we&rsquo;ve used one file, and that one file has contained a single template. But Helm&rsquo;s template language allows you to create named embedded templates, that can be accessed by name elsewhere.</p> - -<p>Before we get to the nuts-and-bolts of writing those templates, there is file naming convention that deserves mention:</p> - -<ul> -<li>Most files in <code>templates/</code> are treated as if they contain Kubernetes manifests</li> -<li>The <code>NOTES.txt</code> is one exception</li> -<li>But files whose name begins with an underscore (<code>_</code>) are assumed to <em>not</em> have a manifest inside. These files are not rendered to Kubernetes object definitions, but are available everywhere within other chart templates for use.</li> -</ul> - -<p>These files are used to store partials and helpers. In fact, when we first created <code>mychart</code>, we saw a file called <code>_helpers.tpl</code>. That file is the default location for template partials.</p> - -<h2 id="declaring-and-using-templates-with-define-and-template">Declaring and using templates with <code>define</code> and <code>template</code></h2> - -<p>The <code>define</code> action allows us to create a named template inside of a template file. Its syntax goes like this:</p> - -<pre><code class="language-yaml">{{ define &quot;MY_NAME&quot; }} - # body of template here -{{ end }} -</code></pre> - -<p>For example, we can define a template to encapsulate a Kubernetes block of labels:</p> - -<pre><code class="language-yaml">{{- define &quot;my_labels&quot; }} - labels: - generator: helm - date: {{ now | htmlDate }} -{{- end }} -</code></pre> - -<p>Now we can embed this template inside of our existing ConfigMap, and then include it with the <code>template</code> action:</p> - -<pre><code class="language-yaml">{{- define &quot;my_labels&quot; }} - labels: - generator: helm - date: {{ now | htmlDate }} -{{- end }} -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ .Release.Name }}-configmap - {{- template &quot;my_labels&quot; }} -data: - myvalue: &quot;Hello World&quot; - {{- range $key, $val := .Values.favorite }} - {{ $key }}: {{ $val | quote }} - {{- end }} -</code></pre> - -<p>When the template engine reads this file, it will store away the reference to <code>my_labels</code> until <code>template &quot;my_labels&quot;</code> is called. Then it will render that template inline. So the result will look like this:</p> - -<pre><code class="language-yaml"># Source: mychart/templates/configmap.yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: running-panda-configmap - labels: - generator: helm - date: 2016-11-02 -data: - myvalue: &quot;Hello World&quot; - drink: &quot;coffee&quot; - food: &quot;pizza&quot; -</code></pre> - -<p>Conventionally, Helm charts put these templates inside of a partials file, usually <code>_helpers.tpl</code>. Let&rsquo;s move this function there:</p> - -<pre><code class="language-yaml">{{/* Generate basic labels */}} -{{- define &quot;my_labels&quot; }} - labels: - generator: helm - date: {{ now | htmlDate }} -{{- end }} -</code></pre> - -<p>By convention, <code>define</code> functions should have a simple documentation block (<code>{{/* ... */}}</code>) describing what they do.</p> - -<p>Even though this definition is in <code>_helpers.tpl</code>, it can still be accessed in <code>configmap.yaml</code>:</p> - -<pre><code class="language-yaml">apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ .Release.Name }}-configmap - {{- template &quot;my_labels&quot; }} -data: - myvalue: &quot;Hello World&quot; - {{- range $key, $val := .Values.favorite }} - {{ $key }}: {{ $val | quote }} - {{- end }} -</code></pre> - -<p>There is one <em>really important detail</em> to keep in mind when naming templates: <strong>template names are global</strong>. If you declare two templates with the same name, whichever one is loaded last will be the one used. Because templates in subcharts are compiled together with top-level templates, you should be careful to name your templates with chart-specific names.</p> - -<p>One popular naming convention is to prefix each defined template with the name of the chart: <code>{{ define &quot;mychart.labels&quot; }}</code> or <code>{{ define &quot;mychart_labels&quot; }}</code>.</p> - -<h2 id="setting-the-scope-of-a-template">Setting the scope of a template</h2> - -<p>In the template we defined above, we did not use any objects. We just used functions. Let&rsquo;s modify our defined template to include the chart name and chart version:</p> - -<pre><code class="language-yaml">{{/* Generate basic labels */}} -{{- define &quot;my_labels&quot; }} - labels: - generator: helm - date: {{ now | htmlDate }} - chart: {{ .Chart.Name }} - version: {{ .Chart.Version }} -{{- end }} -</code></pre> - -<p>If we render this, the result will not be what we expect:</p> - -<pre><code class="language-yaml"># Source: mychart/templates/configmap.yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: moldy-jaguar-configmap - labels: - generator: helm - date: 2016-11-02 - chart: - version: -</code></pre> - -<p>What happened to the name and version? They weren&rsquo;t in the scope for our defined template. When a named template (created with <code>define</code>) is rendered, it will receive the scope passed in by the <code>template</code> call. In our example, we included the template like this:</p> - -<pre><code class="language-yaml">{{- template &quot;my_labels&quot; }} -</code></pre> - -<p>No scope was passed in, so within the template we cannot access anything in <code>.</code>. This is easy enough to fix, though. We simply pass a scope to the template:</p> - -<pre><code class="language-yaml">apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ .Release.Name }}-configmap - {{- template &quot;my_labels&quot; . }} -</code></pre> - -<p>Note that we pass <code>.</code> at the end of the <code>template</code> call. We could just as easily pass <code>.Values</code> or <code>.Values.favorite</code> or whatever scope we want. But what we want is the top-level scope.</p> - -<p>Now when we execute this template with <code>helm install --dry-run --debug ./mychart</code>, we get this:</p> - -<pre><code class="language-yaml"># Source: mychart/templates/configmap.yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: plinking-anaco-configmap - labels: - generator: helm - date: 2016-11-02 - chart: mychart - version: 0.1.0 -</code></pre> - -<p>Now <code>{{ .Chart.Name }}</code> resolves to <code>mychart</code>, and <code>{{ .Chart.Version }}</code> resolves to <code>0.1.0</code>.</p> - -<h2 id="the-include-function">The <code>include</code> function</h2> - -<p>Say we&rsquo;ve defined a simple template that looks like this:</p> - -<pre><code>{{- define &quot;mychart_app&quot; -}} -app_name: {{ .Chart.Name }} -app_version: &quot;{{ .Chart.Version }}+{{ .Release.Time.Seconds }}&quot; -{{- end -}} -</code></pre> - -<p>Now say I want to insert this both into the <code>labels:</code> section of my template, and also the <code>data:</code> section:</p> - -<pre><code class="language-yaml">apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ .Release.Name }}-configmap - labels: - {{ template &quot;mychart_app&quot; .}} -data: - myvalue: &quot;Hello World&quot; - {{- range $key, $val := .Values.favorite }} - {{ $key }}: {{ $val | quote }} - {{- end }} - {{ template &quot;mychart_app&quot; . }} - -</code></pre> - -<p>The output will not be what we expect:</p> - -<pre><code class="language-yaml"># Source: mychart/templates/configmap.yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: measly-whippet-configmap - labels: - app_name: mychart -app_version: &quot;0.1.0+1478129847&quot; -data: - myvalue: &quot;Hello World&quot; - drink: &quot;coffee&quot; - food: &quot;pizza&quot; - app_name: mychart -app_version: &quot;0.1.0+1478129847&quot; -</code></pre> - -<p>Note that the indentation on <code>app_version</code> is wrong in both places. Why? Because the template that is substituted in has the text aligned to the right. Because <code>template</code> is an action, and not a function, there is no way to pass the output of a <code>template</code> call to other functions; the data is simply inserted inline.</p> - -<p>To work around this case, Helm provides an alternative to <code>template</code> that will import the contents of a template into the present pipeline where it can be passed along to other functions in the pipeline.</p> - -<p>Here&rsquo;s the example above, corrected to use <code>indent</code> to indent the <code>mychart_app</code> template correctly:</p> - -<pre><code class="language-yaml">apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ .Release.Name }}-configmap - labels: -{{ include &quot;mychart_app&quot; . | indent 4 }} -data: - myvalue: &quot;Hello World&quot; - {{- range $key, $val := .Values.favorite }} - {{ $key }}: {{ $val | quote }} - {{- end }} -{{ include &quot;mychart_app&quot; . | indent 2 }} -</code></pre> - -<p>Now the produced YAML is correctly indented for each section:</p> - -<pre><code class="language-yaml"># Source: mychart/templates/configmap.yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: edgy-mole-configmap - labels: - app_name: mychart - app_version: &quot;0.1.0+1478129987&quot; -data: - myvalue: &quot;Hello World&quot; - drink: &quot;coffee&quot; - food: &quot;pizza&quot; - app_name: mychart - app_version: &quot;0.1.0+1478129987&quot; -</code></pre> - -<blockquote> -<p>It is considered preferable to use <code>include</code> over <code>template</code> in Helm templates simply so that the output formatting can be handled better for YAML documents.</p> -</blockquote> - -<p>Sometimes we want to import content, but not as templates. That is, we want to import files verbatim. We can achieve this by accessing files through the <code>.Files</code> object described in the next section.</p> - -<h1 id="accessing-files-inside-templates">Accessing Files Inside Templates</h1> - -<p>In the previous section we looked at several ways to create and access named templates. This makes it easy to import one template from within another template. But sometimes it is desirable to import a <em>file that is not a template</em> and inject its contents without sending the contents through the template renderer.</p> - -<p>Helm provides access to files through the <code>.Files</code> object. Before we get going with the template examples, though, there are a few things to note about how this works:</p> - -<ul> -<li>It is okay to add extra files to your Helm chart. These files will be bundled and sent to Tiller. Be careful, though. Charts must be smaller than 1M because of the storage limitations of Kubernetes objects.</li> -<li>Some files cannot be accessed through the <code>.Files</code> object, usually for security reasons. - -<ul> -<li>Files in <code>templates/</code> cannot be accessed.</li> -<li>Files excluded using <code>.helmignore</code> cannot be accessed.</li> -</ul></li> -<li>Charts do not preserve UNIX mode information, so file-level permissions will have no impact on the availability of a file when it comes to the <code>.Files</code> object.</li> -</ul> - -<!-- (see https://github.com/jonschlinkert/markdown-toc) --> - -<!-- toc --> - -<ul> -<li><a href="#basic-example">Basic example</a></li> -<li><a href="#path-helpers">Path helpers</a></li> -<li><a href="#glob-patterns">Glob patterns</a></li> -<li><a href="#configmap-and-secrets-utility-functions">ConfigMap and Secrets utility functions</a></li> -<li><a href="#encoding">Encoding</a></li> -<li><a href="#lines">Lines</a></li> -</ul> - -<!-- tocstop --> - -<h2 id="basic-example">Basic example</h2> - -<p>With those caveats behind, let&rsquo;s write a template that reads three files into our ConfigMap. To get started, we will add three files to the chart, putting all three directly inside of the <code>mychart/</code> directory.</p> - -<p><code>config1.toml</code>:</p> - -<pre><code class="language-toml">message = Hello from config 1 -</code></pre> - -<p><code>config2.toml</code>:</p> - -<pre><code class="language-toml">message = This is config 2 -</code></pre> - -<p><code>config3.toml</code>:</p> - -<pre><code class="language-toml">message = Goodbye from config 3 -</code></pre> - -<p>Each of these is a simple TOML file (think old-school Windows INI files). We know the names of these files, so we can use a <code>range</code> function to loop through them and inject their contents into our ConfigMap.</p> - -<pre><code class="language-yaml">apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ .Release.Name }}-configmap -data: - {{- $files := .Files }} - {{- range tuple &quot;config1.toml&quot; &quot;config2.toml&quot; &quot;config3.toml&quot; }} - {{ . }}: |- - {{ $files.Get . }} - {{- end }} -</code></pre> - -<p>This config map uses several of the techniques discussed in previous sections. For example, we create a <code>$files</code> variable to hold a reference to the <code>.Files</code> object. We also use the <code>tuple</code> function to create a list of files that we loop through. Then we print each file name (<code>{{.}}: |-</code>) followed by the contents of the file <code>{{ $files.Get . }}</code>.</p> - -<p>Running this template will produce a single ConfigMap with the contents of all three files:</p> - -<pre><code class="language-yaml"># Source: mychart/templates/configmap.yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: quieting-giraf-configmap -data: - config1.toml: |- - message = Hello from config 1 - - config2.toml: |- - message = This is config 2 - - config3.toml: |- - message = Goodbye from config 3 -</code></pre> - -<h2 id="path-helpers">Path helpers</h2> - -<p>When working with files, it can be very useful to perform some standard -operations on the file paths themselves. To help with this, Helm imports many of -the functions from Go&rsquo;s <a href="https://golang.org/pkg/path/">path</a> package for your -use. They are all accessible with the same names as in the Go package, but -with a lowercase first letter. For example, <code>Base</code> becomes <code>base</code>, etc.</p> - -<p>The imported functions are: -- Base -- Dir -- Ext -- IsAbs -- Clean</p> - -<h2 id="glob-patterns">Glob patterns</h2> - -<p>As your chart grows, you may find you have a greater need to organize your -files more, and so we provide a <code>Files.Glob(pattern string)</code> method to assist -in extracting certain files with all the flexibility of <a href="https://godoc.org/github.com/gobwas/glob">glob patterns</a>.</p> - -<p><code>.Glob</code> returns a <code>Files</code> type, so you may call any of the <code>Files</code> methods on -the returned object.</p> - -<p>For example, imagine the directory structure:</p> - -<pre><code>foo/: - foo.txt foo.yaml - -bar/: - bar.go bar.conf baz.yaml -</code></pre> - -<p>You have multiple options with Globs:</p> - -<pre><code class="language-yaml">{{ range $path := .Files.Glob &quot;**.yaml&quot; }} -{{ $path }}: | -{{ .Files.Get $path }} -{{ end }} -</code></pre> - -<p>Or</p> - -<pre><code class="language-yaml">{{ range $path, $bytes := .Files.Glob &quot;foo/*&quot; }} -{{ $path }}: '{{ b64enc $bytes }}' -{{ end }} -</code></pre> - -<h2 id="configmap-and-secrets-utility-functions">ConfigMap and Secrets utility functions</h2> - -<p>(Not present in version 2.0.2 or prior)</p> - -<p>It is very common to want to place file content into both configmaps and -secrets, for mounting into your pods at run time. To help with this, we provide a -couple utility methods on the <code>Files</code> type.</p> - -<p>For further organization, it is especially useful to use these methods in -conjunction with the <code>Glob</code> method.</p> - -<p>Given the directory structure from the <a href="#glob-patterns">Glob</a> example above:</p> - -<pre><code class="language-yaml">apiVersion: v1 -kind: ConfigMap -metadata: - name: conf -data: -{{ (.Files.Glob &quot;foo/*&quot;).AsConfig | indent 2 }} ---- -apiVersion: v1 -kind: Secret -metadata: - name: very-secret -type: Opaque -data: -{{ (.Files.Glob &quot;bar/*&quot;).AsSecrets | indent 2 }} -</code></pre> - -<h2 id="encoding">Encoding</h2> - -<p>You can import a file and have the template base-64 encode it to ensure successful transmission:</p> - -<pre><code class="language-yaml">apiVersion: v1 -kind: Secret -metadata: - name: {{ .Release.Name }}-secret -type: Opaque -data: - token: |- - {{ .Files.Get &quot;config1.toml&quot; | b64enc }} -</code></pre> - -<p>The above will take the same <code>config1.toml</code> file we used before and encode it:</p> - -<pre><code class="language-yaml"># Source: mychart/templates/secret.yaml -apiVersion: v1 -kind: Secret -metadata: - name: lucky-turkey-secret -type: Opaque -data: - token: |- - bWVzc2FnZSA9IEhlbGxvIGZyb20gY29uZmlnIDEK -</code></pre> - -<h2 id="lines">Lines</h2> - -<p>Sometimes it is desirable to access each line of a file in your template. We -provide a convenient <code>Lines</code> method for this.</p> - -<pre><code class="language-yaml">data: - some-file.txt: {{ range .Files.Lines &quot;foo/bar.txt&quot; }} - {{ . }}{{ end }} -</code></pre> - -<p>Currently, there is no way to pass files external to the chart during <code>helm install</code>. So if you are asking users to supply data, it must be loaded using <code>helm install -f</code> or <code>helm install --set</code>.</p> - -<p>This discussion wraps up our dive into the tools and techniques for writing Helm templates. In the next section we will see how you can use one special file, <code>templates/NOTES.txt</code>, to send post-installation instructions to the users of your chart.</p> - -<h1 id="creating-a-notes-txt-file">Creating a NOTES.txt File</h1> - -<p>In this section we are going to look at Helm&rsquo;s tool for providing instructions to your chart users. At the end of a <code>chart install</code> or <code>chart upgrade</code>, Helm can print out a block of helpful information for users. This information is highly customizable using templates.</p> - -<p>To add installation notes to your chart, simply create a <code>templates/NOTES.txt</code> file. This file is plain text, but it is processed like as a template, and has all the normal template functions and objects available.</p> - -<p>Let&rsquo;s create a simple <code>NOTES.txt</code> file:</p> - -<pre><code>Thank you for installing {{ .Chart.Name }}. - -Your release is named {{ .Release.Name }}. - -To learn more about the release, try: - - $ helm status {{ .Release.Name }} - $ helm get {{ .Release.Name }} - -</code></pre> - -<p>Now if we run <code>helm install ./mychart</code> we will see this message at the bottom:</p> - -<pre><code>RESOURCES: -==&gt; v1/Secret -NAME TYPE DATA AGE -rude-cardinal-secret Opaque 1 0s - -==&gt; v1/ConfigMap -NAME DATA AGE -rude-cardinal-configmap 3 0s - - -NOTES: -Thank you for installing mychart. - -Your release is named rude-cardinal. - -To learn more about the release, try: - - $ helm status rude-cardinal - $ helm get rude-cardinal -</code></pre> - -<p>Using <code>NOTES.txt</code> this way is a great way to give your users detailed information about how to use their newly installed chart. Creating a <code>NOTES.txt</code> file is strongly recommended, though it is not required.</p> - -<h1 id="subcharts-and-global-values">Subcharts and Global Values</h1> - -<p>To this point we have been working only with one chart. But charts can have dependencies, called <em>subcharts</em>, that also have their own values and templates. In this section we will create a subchart and see the different ways we can access values from within templates.</p> - -<p>Before we dive into the code, there are a few important details to learn about subcharts.</p> - -<ol> -<li>A subchart is considered &ldquo;stand-alone&rdquo;, which means a subchart can never explicitly depend on its parent chart.</li> -<li>For that reason, a subchart cannot access the values of its parent.</li> -<li>A parent chart can override values for subcharts.</li> -<li>Helm has a concept of <em>global values</em> that can be accessed by all charts.</li> -</ol> - -<p>As we walk through the examples in this section, many of these concepts will become clearer.</p> - -<h2 id="creating-a-subchart">Creating a Subchart</h2> - -<p>For these exercises, we&rsquo;ll start with the <code>mychart/</code> chart we created at the beginning of this guide, and we&rsquo;ll add a new chart inside of it.</p> - -<pre><code class="language-console">$ cd mychart/charts -$ helm create mysubchart -Creating mysubchart -$ rm -rf mysubchart/templates/*.* -</code></pre> - -<p>Notice that just as before, we deleted all of the base templates so that we can start from scratch. In this guide, we are focused on how templates work, not on managing dependencies. But the <a href="./#../charts">Charts Guide</a> has more information on how subcharts work.</p> - -<h2 id="adding-values-and-a-template-to-the-subchart">Adding Values and a Template to the Subchart</h2> - -<p>Next, let&rsquo;s create a simple template and values file for our <code>mysubchart</code> chart. There should already be a <code>values.yaml</code> in <code>mychart/charts/mysubchart</code>. We&rsquo;ll set it up like this:</p> - -<pre><code class="language-yaml">dessert: cake -</code></pre> - -<p>Next, we&rsquo;ll create a new ConfigMap template in <code>mychart/charts/mysubchart/templates/configmap.yaml</code>:</p> - -<pre><code>apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ .Release.Name }}-cfgmap2 -data: - dessert: {{ .Values.dessert }} -</code></pre> - -<p>Because every subchart is a <em>stand-alone chart</em>, we can test <code>mysubchart</code> on its own:</p> - -<pre><code class="language-console">$ helm install --dry-run --debug mychart/charts/mysubchart -SERVER: &quot;localhost:44134&quot; -CHART PATH: /Users/mattbutcher/Code/Go/src/k8s.io/helm/_scratch/mychart/charts/mysubchart -NAME: newbie-elk -TARGET NAMESPACE: default -CHART: mysubchart 0.1.0 -MANIFEST: ---- -# Source: mysubchart/templates/configmap.yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: newbie-elk-cfgmap2 -data: - dessert: cake -</code></pre> - -<h2 id="overriding-values-from-a-parent-chart">Overriding Values from a Parent Chart</h2> - -<p>Our original chart, <code>mychart</code> is now the <em>parent</em> chart of <code>mysubchart</code>. This relationship is based entirely on the fact that <code>mysubchart</code> is within <code>mychart/charts</code>.</p> - -<p>Because <code>mychart</code> is a parent, we can specify configuration in <code>mychart</code> and have that configuration pushed into <code>mysubchart</code>. For example, we can modify <code>mychart/values.yaml</code> like this:</p> - -<pre><code class="language-yaml">favorite: - drink: coffee - food: pizza -pizzaToppings: - - mushrooms - - cheese - - peppers - - onions - -mysubchart: - dessert: ice cream -</code></pre> - -<p>Note the last two lines. Any directives inside of the <code>mysubchart</code> section will be sent to the <code>mysubchart</code> chart. So if we run <code>helm install --dry-run --debug mychart</code>, one of the things we will see is the <code>mysubchart</code> ConfigMap:</p> - -<pre><code class="language-yaml"># Source: mychart/charts/mysubchart/templates/configmap.yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: unhinged-bee-cfgmap2 -data: - dessert: ice cream -</code></pre> - -<p>The value at the top level has now overridden the value of the subchart.</p> - -<p>There&rsquo;s an important detail to notice here. We didn&rsquo;t change the template of <code>mychart/charts/mysubchart/templates/configmap.yaml</code> to point to <code>.Values.mysubchart.dessert</code>. From that template&rsquo;s perspective, the value is still located at <code>.Values.dessert</code>. As the template engine passes values along, it sets the scope. So for the <code>mysubchart</code> templates, only values specifically for <code>mysubchart</code> will be available in <code>.Values</code>.</p> - -<p>Sometimes, though, you do want certain values to be available to all of the templates. This is accomplished using global chart values.</p> - -<h2 id="global-chart-values">Global Chart Values</h2> - -<p>Global values are values that can be accessed from any chart or subchart by exactly the same name. Globals require explicit declaration. You can&rsquo;t use an existing non-global as if it were a global.</p> - -<p>The Values data type has a reserved section called <code>Values.global</code> where global values can be set. Let&rsquo;s set one in our <code>mychart/values.yaml</code> file.</p> - -<pre><code class="language-yaml">favorite: - drink: coffee - food: pizza -pizzaToppings: - - mushrooms - - cheese - - peppers - - onions - -mysubchart: - dessert: ice cream - -global: - salad: caesar -</code></pre> - -<p>Because of the way globals work, both <code>mychart/templates/configmap.yaml</code> and <code>mysubchart/templates/configmap.yaml</code> should be able to access that value as <code>{{ .Values.global.salad}}</code>.</p> - -<p><code>mychart/templates/configmap.yaml</code>:</p> - -<pre><code class="language-yaml">apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ .Release.Name }}-configmap -data: - salad: {{ .Values.global.salad }} -</code></pre> - -<p><code>mysubchart/templates/configmap.yaml</code>:</p> - -<pre><code class="language-yaml">apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ .Release.Name }}-cfgmap2 -data: - dessert: {{ .Values.dessert }} - salad: {{ .Values.global.salad }} -</code></pre> - -<p>Now if we run a dry run install, we&rsquo;ll see the same value in both outputs:</p> - -<pre><code class="language-yaml"># Source: mychart/templates/configmap.yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: silly-snake-configmap -data: - salad: caesar - ---- -# Source: mychart/charts/mysubchart/templates/configmap.yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: silly-snake-cfgmap2 -data: - dessert: ice cream - salad: caesar -</code></pre> - -<p>Globals are useful for passing information like this, though it does take some planning to make sure the right templates are configured to use globals.</p> - -<h2 id="sharing-templates-with-subcharts">Sharing Templates with Subcharts</h2> - -<p>Parent charts and subcharts can share templates. Any defined block in any chart is -available to other charts.</p> - -<p>For example, we can define a simple template like this:</p> - -<pre><code class="language-yaml">{{- define &quot;labels&quot; }}from: mychart{{ end }} -</code></pre> - -<p>Recall how the labels on templates are <em>globally shared</em>. Thus, the <code>labels</code> chart -can be included from any other chart.</p> - -<p>While chart developers have a choice between <code>include</code> and <code>template</code>, one advantage -of using <code>include</code> is that <code>include</code> can dynamically reference templates:</p> - -<pre><code class="language-yaml">{{ include $mytemplate }} -</code></pre> - -<p>The above will dereference <code>$mytemplate</code>. The <code>template</code> function, in contrast, -will only accept a string literal.</p> - -<h2 id="avoid-using-blocks">Avoid Using Blocks</h2> - -<p>The Go template language provides a <code>block</code> keyword that allows developers to provide -a default implementation which is overridden later. In Helm charts, blocks are not -the best tool for overriding because it if multiple implementations of the same block -are provided, the one selected is unpredictable.</p> - -<p>The suggestion is to instead use <code>include</code>.</p> - -<h1 id="debugging-templates">Debugging Templates</h1> - -<p>Debugging templates can be tricky simply because the templates are rendered on the Tiller server, not the Helm client. And then the rendered templates are sent to the Kubernetes API server, which may reject the YAML files for reasons other than formatting.</p> - -<p>There are a few commands that can help you debug.</p> - -<ul> -<li><code>helm lint</code> is your go-to tool for verifying that your chart follows best practices</li> -<li><code>helm install --dry-run --debug</code>: We&rsquo;ve seen this trick already. It&rsquo;s a great way to have the server render your templates, then return the resulting manifest file.</li> -<li><code>helm get manifest</code>: This is a good way to see what templates are installed on the server.</li> -</ul> - -<p>When your YAML is failing to parse, but you want to see what is generated, one -easy way to retrieve the YAML is to comment out the problem section in the template, -and then re-run <code>helm install --dry-run --debug</code>:</p> - -<pre><code class="language-YAML">apiVersion: v1 -# some: problem section -# {{ .Values.foo | quote }} -</code></pre> - -<p>The above will be rendered and returned with the comments intact:</p> - -<pre><code class="language-YAML">apiVersion: v1 -# some: problem section -# &quot;bar&quot; -</code></pre> - -<p>This provides a quick way of viewing the generated content without YAML parse -errors blocking.</p> - -<h1 id="wrapping-up">Wrapping Up</h1> - -<p>This guide is intended to give you, the chart developer, a strong understanding of how to use Helm&rsquo;s template language. The guide focuses on the technical aspects of template development.</p> - -<p>But there are many things this guide has not covered when it comes to the practical day-to-day development of charts. Here are some useful pointers to other documentation that will help you as you create new charts:</p> - -<ul> -<li>The <a href="https://github.com/kubernetes/charts">Kubernetes Charts project</a> is an indispensable source of charts. That project is also sets the standard for best practices in chart development.</li> -<li>The Kubernetes <a href="http://kubernetes.io/docs/user-guide/">User&rsquo;s Guide</a> provides detailed examples of the various resource kinds that you can use, from ConfigMaps and Secrets to DaemonSets and Deployments.</li> -<li>The Helm <a href="./#../charts">Charts Guide</a> explains the workflow of using charts.</li> -<li>The Helm <a href="./#../charts_hooks">Chart Hooks Guide</a> explains how to create lifecycle hooks.</li> -<li>The Helm <a href="./#../chart-development-tips-and-tricks">Charts Tips and Tricks</a> article provides some useful tips for writing charts.</li> -<li>The <a href="https://github.com/Masterminds/sprig">Sprig documentation</a> documents more than sixty of the template functions.</li> -<li>The <a href="https://godoc.org/text/template">Go template docs</a> explain the template syntax in detail.</li> -<li>The <a href="https://github.com/databus23/schelm">Schelm tool</a> is a nice helper utility for debugging charts.</li> -</ul> - -<p>Sometimes it&rsquo;s easier to ask a few questions and get answers from experienced developers. The best place to do that is in the Kubernetes <code>#Helm</code> Slack channel:</p> - -<ul> -<li><a href="https://slack.k8s.io/">Kubernetes Slack</a>: <code>#helm</code></li> -</ul> - -<p>Finally, if you find errors or omissions in this document, want to suggest some new content, or would like to contribute, visit <a href="https://github.com/kubernetes/helm">The Helm Project</a>.</p> - -<h1 id="yaml-techniques">YAML Techniques</h1> - -<p>Most of this guide has been focused on writing the template language. Here, -we&rsquo;ll look at the YAML format. YAML has some useful features that we, as -template authors, can use to make our templates less error prone and easier -to read.</p> - -<h2 id="scalars-and-collections">Scalars and Collections</h2> - -<p>According to the <a href="http://yaml.org/spec/1.2/spec.html">YAML spec</a>, there are two -types of collections, and many scalar types.</p> - -<p>The two types of collections are maps and sequences:</p> - -<pre><code class="language-yaml">map: - one: 1 - two: 2 - three: 3 - -sequence: - - one - - two - - three -</code></pre> - -<p>Scalar values are individual values (as opposed to collections)</p> - -<h3 id="scalar-types-in-yaml">Scalar Types in YAML</h3> - -<p>In Helm&rsquo;s dialect of YAML, the scalar data type of a value is determined by a -complex set of rules, including the Kubernetes schema for resource definitions. -But when inferring types, the following rules tend to hold true.</p> - -<p>If an integer or float is an unquoted bare word, it is typically treated as -a numeric type:</p> - -<pre><code class="language-yaml">count: 1 -size: 2.34 -</code></pre> - -<p>But if they are quoted, they are treated as strings:</p> - -<pre><code class="language-yaml">count: &quot;1&quot; # &lt;-- string, not int -size: '2.34' # &lt;-- string, not float -</code></pre> - -<p>The same is true of booleans:</p> - -<pre><code class="language-yaml">isGood: true # bool -answer: &quot;true&quot; # string -</code></pre> - -<p>The word for an empty value is <code>null</code> (not <code>nil</code>).</p> - -<p>Note that <code>port: &quot;80&quot;</code> is valid YAML, and will pass through both the -template engine and the YAML parser, but will fail if Kubernetes expects -<code>port</code> to be an integer.</p> - -<p>In some cases, you can force a particular type inference using YAML node tags:</p> - -<pre><code class="language-yaml">coffee: &quot;yes, please&quot; -age: !!str 21 -port: !!int &quot;80&quot; -</code></pre> - -<p>In the above, <code>!!str</code> tells the parser that <code>age</code> is a string, even if it looks -like an int. And <code>port</code> is treated as an int, even though it is quoted.</p> - -<h2 id="strings-in-yaml">Strings in YAML</h2> - -<p>Much of the data that we place in YAML documents are strings. YAML has more than -one way to represent a string. This section explains the ways and demonstrates -how to use some of them.</p> - -<p>There are three &ldquo;inline&rdquo; ways of declaring a string:</p> - -<pre><code class="language-yaml">way1: bare words -way2: &quot;double-quoted strings&quot; -way3: 'single-quoted strings' -</code></pre> - -<p>All inline styles must be on one line.</p> - -<ul> -<li>Bare words are unquoted, and are not escaped. For this reason, you have to -be careful what characters you use.</li> -<li>Double-quoted strings can have specific characters escaped with <code>\</code>. For -example <code>&quot;\&quot;Hello\&quot;, she said&quot;</code>. You can escape line breaks with <code>\n</code>.</li> -<li>Single-quoted strings are &ldquo;literal&rdquo; strings, and do not use the <code>\</code> to -escape characters. The only escape sequence is <code>''</code>, which is decoded as -a single <code>'</code>.</li> -</ul> - -<p>In addition to the one-line strings, you can declare multi-line strings:</p> - -<pre><code class="language-yaml">coffee: | - Latte - Cappuccino - Espresso -</code></pre> - -<p>The above will treat the value of <code>coffee</code> as a single string equivalent to -<code>Latte\nCappuccino\nEspresso\n</code>.</p> - -<p>Note that the first line after the <code>|</code> must be correctly indented. So we could -break the example above by doing this:</p> - -<pre><code class="language-yaml">coffee: | - Latte - Cappuccino - Espresso - -</code></pre> - -<p>Because <code>Latte</code> is incorrectly indented, we&rsquo;d get an error like this:</p> - -<pre><code>Error parsing file: error converting YAML to JSON: yaml: line 7: did not find expected key -</code></pre> - -<p>In templates, it is sometimes safer to put a fake &ldquo;first line&rdquo; of content in a -multi-line document just for protection from the above error:</p> - -<pre><code class="language-yaml">coffee: | - # Commented first line - Latte - Cappuccino - Espresso - -</code></pre> - -<p>Note that whatever that first line is, it will be preserved in the output of the -string. So if you are, for example, using this technique to inject a file&rsquo;s contents -into a ConfigMap, the comment should be of the type expected by whatever is -reading that entry.</p> - -<h3 id="controlling-spaces-in-multi-line-strings">Controlling Spaces in Multi-line Strings</h3> - -<p>In the example above, we used <code>|</code> to indicate a multi-line string. But notice -that the content of our string was followed with a trailing <code>\n</code>. If we want -the YAML processor to strip off the trailing newline, we can add a <code>-</code> after the -<code>|</code>:</p> - -<pre><code class="language-yaml">coffee: |- - Latte - Cappuccino - Espresso -</code></pre> - -<p>Now the <code>coffee</code> value will be: <code>Latte\nCappuccino\nEspresso</code> (with no trailing -<code>\n</code>).</p> - -<p>Other times, we might want all trailing whitespace to be preserved. We can do -this with the <code>|+</code> notation:</p> - -<pre><code class="language-yaml">coffee: |+ - Latte - Cappuccino - Espresso - - -another: value -</code></pre> - -<p>Now the value of <code>coffee</code> will be <code>Latte\nCappuccino\nEspresso\n\n\n</code>.</p> - -<p>Indentation inside of a text block is preserved, and results in the preservation -of line breaks, too:</p> - -<pre><code>coffee: |- - Latte - 12 oz - 16 oz - Cappuccino - Espresso -</code></pre> - -<p>In the above case, <code>coffee</code> will be <code>Latte\n 12 oz\n 16 oz\nCappuccino\nEspresso</code>.</p> - -<h3 id="indenting-and-templates">Indenting and Templates</h3> - -<p>When writing templates, you may find yourself wanting to inject the contents of -a file into the template. As we saw in previous chapters, there are two ways -of doing this:</p> - -<ul> -<li>Use <code>{{ .Files.Get &quot;FILENAME&quot; }}</code> to get the contents of a file in the chart.</li> -<li>Use <code>{{ include &quot;TEMPLATE&quot; . }}</code> to render a template and then place its -contents into the chart.</li> -</ul> - -<p>When inserting files into YAML, it&rsquo;s good to understand the multi-line rules above. -Often times, the easiest way to insert a static file is to do something like -this:</p> - -<pre><code class="language-yaml">myfile: | -{{ .Files.Get &quot;myfile.txt&quot; | indent 2 }} -</code></pre> - -<p>Note how we do the indentation above: <code>indent 2</code> tells the template engine to -indent every line in &ldquo;myfile.txt&rdquo; with two spaces. Note that we do not indent -that template line. That&rsquo;s because if we did, the file content of the first line -would be indented twice.</p> - -<h3 id="folded-multi-line-strings">Folded Multi-line Strings</h3> - -<p>Sometimes you want to represent a string in your YAML with multiple lines, but -want it to be treated as one long line when it is interpreted. This is called -&ldquo;folding&rdquo;. To declare a folded block, use <code>&gt;</code> instead of <code>|</code>:</p> - -<pre><code class="language-yaml">coffee: &gt; - Latte - Cappuccino - Espresso - - -</code></pre> - -<p>The value of <code>coffee</code> above will be <code>Latte Cappuccino Espresso\n</code>. Note that all -but the last line feed will be converted to spaces. You can combine the whitespace -controls with the folded text marker, so <code>&gt;-</code> will replace or trim all newlines.</p> - -<p>Note that in the folded syntax, indenting text will cause lines to be preserved.</p> - -<pre><code class="language-yaml">coffee: &gt;- - Latte - 12 oz - 16 oz - Cappuccino - Espresso -</code></pre> - -<p>The above will produce <code>Latte\n 12 oz\n 16 oz\nCappuccino Espresso</code>. Note that -both the spacing and the newlines are still there.</p> - -<h2 id="embedding-multiple-documents-in-one-file">Embedding Multiple Documents in One File</h2> - -<p>It is possible to place more than one YAML documents into a single file. This -is done by prefixing a new document with <code>---</code> and ending the document with -<code>...</code></p> - -<pre><code class="language-yaml"> ---- -document:1 -... ---- -document: 2 -... -</code></pre> - -<p>In many cases, either the <code>---</code> or the <code>...</code> may be omitted.</p> - -<p>Some files in Helm cannot contain more than one doc. If, for example, more -than one document is provided inside of a <code>values.yaml</code> file, only the first -will be used.</p> - -<p>Template files, however, may have more than one document. When this happens, -the file (and all of its documents) is treated as one object during -template rendering. But then the resulting YAML is split into multiple -documents before it is fed to Kubernetes.</p> - -<p>We recommend only using multiple documents per file when it is absolutely -necessary. Having multiple documents in a file can be difficult to debug.</p> - -<h2 id="yaml-is-a-superset-of-json">YAML is a Superset of JSON</h2> - -<p>Because YAML is a superset of JSON, any valid JSON document <em>should</em> be valid -YAML.</p> - -<pre><code class="language-json">{ - &quot;coffee&quot;: &quot;yes, please&quot;, - &quot;coffees&quot;: [ - &quot;Latte&quot;, &quot;Cappuccino&quot;, &quot;Espresso&quot; - ] -} -</code></pre> - -<p>The above is another way of representing this:</p> - -<pre><code class="language-yaml">coffee: yes, please -coffees: -- Latte -- Cappuccino -- Espresso -</code></pre> - -<p>And the two can be mixed (with care):</p> - -<pre><code class="language-yaml">coffee: &quot;yes, please&quot; -coffees: [ &quot;Latte&quot;, &quot;Cappuccino&quot;, &quot;Espresso&quot;] -</code></pre> - -<p>All three of these should parse into the same internal representation.</p> - -<p>While this means that files such as <code>values.yaml</code> may contain JSON data, Helm -does not treat the file extension <code>.json</code> as a valid suffix.</p> - -<h2 id="yaml-anchors">YAML Anchors</h2> - -<p>The YAML spec provides a way to store a reference to a value, and later -refer to that value by reference. YAML refers to this as &ldquo;anchoring&rdquo;:</p> - -<pre><code class="language-yaml">coffee: &quot;yes, please&quot; -favorite: &amp;favoriteCoffee &quot;Cappucino&quot; -coffees: - - Latte - - *favoriteCoffee - - Espresso -</code></pre> - -<p>In the above, <code>&amp;favoriteCoffee</code> sets a reference to <code>Cappuccino</code>. Later, that -reference is used as <code>*favoriteCoffee</code>. So <code>coffees</code> becomes -<code>Latte, Cappuccino, Espresso</code>.</p> - -<p>While there are a few cases where anchors are useful, there is one aspect of -them that can cause subtle bugs: The first time the YAML is consumed, the -reference is expanded and then discarded.</p> - -<p>So if we were to decode and then re-encode the example above, the resulting -YAML would be:</p> - -<pre><code class="language-YAML">coffee: yes, please -favorite: Cappucino -coffees: -- Latte -- Cappucino -- Espresso -</code></pre> - -<p>Because Helm and Kubernetes often read, modify, and then rewrite YAML files, -the anchors will be lost.</p> - -<h1 id="appendix-go-data-types-and-templates">Appendix: Go Data Types and Templates</h1> - -<p>The Helm template language is implemented in the strongly typed Go programming language. For that reason, variables in templates are <em>typed</em>. For the most part, variables will be exposed as one of the following types:</p> - -<ul> -<li>string: A string of text</li> -<li>bool: a <code>true</code> or <code>false</code></li> -<li>int: An integer value (there are also 8, 16, 32, and 64 bit signed and unsigned variants of this)</li> -<li>float64: a 64-bit floating point value (there are also 8, 16, and 32 bit varieties of this)</li> -<li>a byte slice (<code>[]byte</code>), often used to hold (potentially) binary data</li> -<li>struct: an object with properties and methods</li> -<li>a slice (indexed list) of one of the previous types</li> -<li>a string-keyed map (<code>map[string]interface{}</code>) where the value is one of the previous types</li> -</ul> - -<p>There are many other types in Go, and sometimes you will have to convert between them in your templates. The easiest way to debug an object&rsquo;s type is to pass it through <code>printf &quot;%t&quot;</code> in a template, which will print the type. Also see the <code>typeOf</code> and <code>kindOf</code> functions.</p> - - - - - diff --git a/docs.helm.sh/rootfs/public/chart_tests/index.html b/docs.helm.sh/rootfs/public/chart_tests/index.html deleted file mode 100644 index 4adfe4d3d6..0000000000 --- a/docs.helm.sh/rootfs/public/chart_tests/index.html +++ /dev/null @@ -1,1412 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

Chart Tests

- -

A chart contains a number of Kubernetes resources and components that work together. As a chart author, you may want to write some tests that validate that your chart works as expected when it is installed. These tests also help the chart consumer understand what your chart is supposed to do.

- -

A test in a helm chart lives under the templates/ directory and is a pod definition that specifies a container with a given command to run. The container should exit successfully (exit 0) for a test to be considered a success. The pod definition must contain one of the helm test hook annotations: helm.sh/hooks: test-success or helm.sh/hooks: test-failure.

- -

Example tests: -- Validate that your configuration from the values.yaml file was properly injected. - - Make sure your username and password work correctly - - Make sure an incorrect username and password does not work -- Assert that your services are up and correctly load balancing -- etc.

- -

You can run the pre-defined tests in Helm on a release using the command helm test <RELEASE_NAME>. For a chart consumer, this is a great way to sanity check that their release of a chart (or application) works as expected.

- -

A Breakdown of the Helm Test Hooks

- -

In Helm, there are two test hooks: test-success and test-failure

- -

test-success indicates that test pod should complete successfully. In other words, the containers in the pod should exit 0. -test-failure is a way to assert that a test pod should not complete successfully. If the containers in the pod do not exit 0, that indicates success.

- -

Example Test

- -

Here is an example of a helm test pod definition in an example mariadb chart:

- -
mariadb/
-  Chart.yaml
-  README.md
-  values.yaml
-  charts/
-  templates/
-  templates/tests/test-mariadb-connection.yaml
-
- -

In wordpress/templates/tests/test-mariadb-connection.yaml:

- -
apiVersion: v1
-kind: Pod
-metadata:
-  name: "{{ .Release.Name }}-credentials-test"
-  annotations:
-    "helm.sh/hook": test-success
-spec:
-  containers:
-  - name: {{ .Release.Name }}-credentials-test
-    image: {{ .Values.image }}
-    env:
-      - name: MARIADB_HOST
-        value: {{ template "mariadb.fullname" . }}
-      - name: MARIADB_PORT
-        value: "3306"
-      - name: WORDPRESS_DATABASE_NAME
-        value: {{ default "" .Values.mariadb.mariadbDatabase | quote }}
-      - name: WORDPRESS_DATABASE_USER
-        value: {{ default "" .Values.mariadb.mariadbUser | quote }}
-      - name: WORDPRESS_DATABASE_PASSWORD
-        valueFrom:
-          secretKeyRef:
-            name: {{ template "mariadb.fullname" . }}
-            key: mariadb-password
-    command: ["sh", "-c", "mysql --host=$MARIADB_HOST --port=$MARIADB_PORT --user=$WORDPRESS_DATABASE_USER --password=$WORDPRESS_DATABASE_PASSWORD"]
-  restartPolicy: Never
-
- -

Steps to Run a Test Suite on a Release

- -
    -
  1. $ helm install mariadb

    - -
    NAME:   quirky-walrus
    -LAST DEPLOYED: Mon Feb 13 13:50:43 2017
    -NAMESPACE: default
    -STATUS: DEPLOYED
    -
  2. - -
  3. $ helm test quirky-walrus

    - -
    RUNNING: quirky-walrus-credentials-test
    -SUCCESS: quirky-walrus-credentials-test
    -
  4. -
- -

Notes

- -
    -
  • You can define as many tests as you would like in a single yaml file or spread across several yaml files in the templates/ directory
  • -
  • You are welcome to nest your test suite under a tests/ directory like <chart-name>/templates/tests/ for more isolation
  • -
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/charts/index.html b/docs.helm.sh/rootfs/public/charts/index.html deleted file mode 100644 index a4f0d68f74..0000000000 --- a/docs.helm.sh/rootfs/public/charts/index.html +++ /dev/null @@ -1,2177 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

Charts

- -

Helm uses a packaging format called charts. A chart is a collection of files -that describe a related set of Kubernetes resources. A single chart -might be used to deploy something simple, like a memcached pod, or -something complex, like a full web app stack with HTTP servers, -databases, caches, and so on.

- -

Charts are created as files laid out in a particular directory tree, -then they can be packaged into versioned archives to be deployed.

- -

This document explains the chart format, and provides basic guidance for -building charts with Helm.

- -

The Chart File Structure

- -

A chart is organized as a collection of files inside of a directory. The -directory name is the name of the chart (without versioning information). Thus, -a chart describing WordPress would be stored in the wordpress/ directory.

- -

Inside of this directory, Helm will expect a structure that matches this:

- -
wordpress/
-  Chart.yaml          # A YAML file containing information about the chart
-  LICENSE             # OPTIONAL: A plain text file containing the license for the chart
-  README.md           # OPTIONAL: A human-readable README file
-  requirements.yaml   # OPTIONAL: A YAML file listing dependencies for the chart
-  values.yaml         # The default configuration values for this chart
-  charts/             # OPTIONAL: A directory containing any charts upon which this chart depends.
-  templates/          # OPTIONAL: A directory of templates that, when combined with values,
-                      # will generate valid Kubernetes manifest files.
-  templates/NOTES.txt # OPTIONAL: A plain text file containing short usage notes
-
- -

Helm reserves use of the charts/ and templates/ directories, and of -the listed file names. Other files will be left as they are.

- -

While the charts and templates directories are optional there must be at least one chart dependency or template file for the chart to be valid.

- -

The Chart.yaml File

- -

The Chart.yaml file is required for a chart. It contains the following fields:

- -
name: The name of the chart (required)
-version: A SemVer 2 version (required)
-description: A single-sentence description of this project (optional)
-keywords:
-  - A list of keywords about this project (optional)
-home: The URL of this project's home page (optional)
-sources:
-  - A list of URLs to source code for this project (optional)
-maintainers: # (optional)
-  - name: The maintainer's name (required for each maintainer)
-    email: The maintainer's email (optional for each maintainer)
-    url: A URL for the maintainer (optional for each maintainer)
-engine: gotpl # The name of the template engine (optional, defaults to gotpl)
-icon: A URL to an SVG or PNG image to be used as an icon (optional).
-appVersion: The version of the app that this contains (optional). This needn't be SemVer.
-deprecated: Whether this chart is deprecated (optional, boolean)
-tillerVersion: The version of Tiller that this chart requires. This should be expressed as a SemVer range: ">2.0.0" (optional)
-
- -

If you are familiar with the Chart.yaml file format for Helm Classic, you will -notice that fields specifying dependencies have been removed. That is because -the new Chart format expresses dependencies using the charts/ directory.

- -

Other fields will be silently ignored.

- -

Charts and Versioning

- -

Every chart must have a version number. A version must follow the -SemVer 2 standard. Unlike Helm Classic, Kubernetes -Helm uses version numbers as release markers. Packages in repositories -are identified by name plus version.

- -

For example, an nginx chart whose version field is set to version: -1.2.3 will be named:

- -
nginx-1.2.3.tgz
-
- -

More complex SemVer 2 names are also supported, such as -version: 1.2.3-alpha.1+ef365. But non-SemVer names are explicitly -disallowed by the system.

- -

NOTE: Whereas Helm Classic and Deployment Manager were both -very GitHub oriented when it came to charts, Kubernetes Helm does not -rely upon or require GitHub or even Git. Consequently, it does not use -Git SHAs for versioning at all.

- -

The version field inside of the Chart.yaml is used by many of the -Helm tools, including the CLI and the Tiller server. When generating a -package, the helm package command will use the version that it finds -in the Chart.yaml as a token in the package name. The system assumes -that the version number in the chart package name matches the version number in -the Chart.yaml. Failure to meet this assumption will cause an error.

- -

The appVersion field

- -

Note that the appVersion field is not related to the version field. It is -a way of specifying the version of the application. For example, the drupal -chart may have an appVersion: 8.2.1, indicating that the version of Drupal -included in the chart (by default) is 8.2.1. This field is informational, and -has no impact on chart version calculations.

- -

Deprecating Charts

- -

When managing charts in a Chart Repository, it is sometimes necessary to -deprecate a chart. The optional deprecated field in Chart.yaml can be used -to mark a chart as deprecated. If the latest version of a chart in the -repository is marked as deprecated, then the chart as a whole is considered to -be deprecated. The chart name can later be reused by publishing a newer version -that is not marked as deprecated. The workflow for deprecating charts, as -followed by the kubernetes/charts -project is: - - Update chart’s Chart.yaml to mark the chart as deprecated, bumping the - version - - Release the new chart version in the Chart Repository - - Remove the chart from the source repository (e.g. git)

- -

Chart LICENSE, README and NOTES

- -

Charts can also contain files that describe the installation, configuration, usage and license of a -chart. A README for a chart should be formatted in Markdown (README.md), and should generally -contain:

- -
    -
  • A description of the application or service the chart provides
  • -
  • Any prerequisites or requirements to run the chart
  • -
  • Descriptions of options in values.yaml and default values
  • -
  • Any other information that may be relevant to the installation or configuration of the chart
  • -
- -

The chart can also contain a short plain text templates/NOTES.txt file that will be printed out -after installation, and when viewing the status of a release. This file is evaluated as a -template, and can be used to display usage notes, next steps, or any other -information relevant to a release of the chart. For example, instructions could be provided for -connecting to a database, or accessing a web UI. Since this file is printed to STDOUT when running -helm install or helm status, it is recommended to keep the content brief and point to the README -for greater detail.

- -

Chart Dependencies

- -

In Helm, one chart may depend on any number of other charts. -These dependencies can be dynamically linked through the requirements.yaml -file or brought in to the charts/ directory and managed manually.

- -

Although manually managing your dependencies has a few advantages some teams need, -the preferred method of declaring dependencies is by using a -requirements.yaml file inside of your chart.

- -

Note: The dependencies: section of the Chart.yaml from Helm -Classic has been completely removed.

- -

Managing Dependencies with requirements.yaml

- -

A requirements.yaml file is a simple file for listing your -dependencies.

- -
dependencies:
-  - name: apache
-    version: 1.2.3
-    repository: http://example.com/charts
-  - name: mysql
-    version: 3.2.1
-    repository: http://another.example.com/charts
-
- -
    -
  • The name field is the name of the chart you want.
  • -
  • The version field is the version of the chart you want.
  • -
  • The repository field is the full URL to the chart repository. Note -that you must also use helm repo add to add that repo locally.
  • -
- -

Once you have a dependencies file, you can run helm dependency update -and it will use your dependency file to download all the specified -charts into your charts/ directory for you.

- -
$ helm dep up foochart
-Hang tight while we grab the latest from your chart repositories...
-...Successfully got an update from the "local" chart repository
-...Successfully got an update from the "stable" chart repository
-...Successfully got an update from the "example" chart repository
-...Successfully got an update from the "another" chart repository
-Update Complete. Happy Helming!
-Saving 2 charts
-Downloading apache from repo http://example.com/charts
-Downloading mysql from repo http://another.example.com/charts
-
- -

When helm dependency update retrieves charts, it will store them as -chart archives in the charts/ directory. So for the example above, one -would expect to see the following files in the charts directory:

- -
charts/
-  apache-1.2.3.tgz
-  mysql-3.2.1.tgz
-
- -

Managing charts with requirements.yaml is a good way to easily keep -charts updated, and also share requirements information throughout a -team.

- -

Alias field in requirements.yaml

- -

In addition to the other fields above, each requirements entry may contain -the optional field alias.

- -

Adding an alias for a dependency chart would put -a chart in dependencies using alias as name of new dependency.

- -

One can use alias in cases where they need to access a chart -with other name(s).

- -
# parentchart/requirements.yaml
-dependencies:
-  - name: subchart
-    repository: http://localhost:10191
-    version: 0.1.0
-    alias: new-subchart-1
-  - name: subchart
-    repository: http://localhost:10191
-    version: 0.1.0
-    alias: new-subchart-2
-  - name: subchart
-    repository: http://localhost:10191
-    version: 0.1.0
-
- -

In the above example we will get 3 dependencies in all for parentchart

- -
subchart
-new-subchart-1
-new-subchart-2
-
- -

The manual way of achieving this is by copy/pasting the same chart in the -charts/ directory multiple times with different names.

- -

Tags and Condition fields in requirements.yaml

- -

In addition to the other fields above, each requirements entry may contain -the optional fields tags and condition.

- -

All charts are loaded by default. If tags or condition fields are present, -they will be evaluated and used to control loading for the chart(s) they are applied to.

- -

Condition - The condition field holds one or more YAML paths (delimited by commas). -If this path exists in the top parent’s values and resolves to a boolean value, -the chart will be enabled or disabled based on that boolean value. Only the first -valid path found in the list is evaluated and if no paths exist then the condition has no effect.

- -

Tags - The tags field is a YAML list of labels to associate with this chart. -In the top parent’s values, all charts with tags can be enabled or disabled by -specifying the tag and a boolean value.

- -
# parentchart/requirements.yaml
-dependencies:
-      - name: subchart1
-        repository: http://localhost:10191
-        version: 0.1.0
-        condition: subchart1.enabled, global.subchart1.enabled
-        tags:
-          - front-end
-          - subchart1
-
-      - name: subchart2
-        repository: http://localhost:10191
-        version: 0.1.0
-        condition: subchart2.enabled,global.subchart2.enabled
-        tags:
-          - back-end
-          - subchart2
-
-
- -
# parentchart/values.yaml
-
-subchart1:
-  enabled: true
-tags:
-  front-end: false
-  back-end: true
-
- -

In the above example all charts with the tag front-end would be disabled but since the -subchart1.enabled path evaluates to ‘true’ in the parent’s values, the condition will override the -front-end tag and subchart1 will be enabled.

- -

Since subchart2 is tagged with back-end and that tag evaluates to true, subchart2 will be -enabled. Also notes that although subchart2 has a condition specified in requirements.yaml, there -is no corresponding path and value in the parent’s values so that condition has no effect.

- -
Using the CLI with Tags and Conditions
- -

The --set parameter can be used as usual to alter tag and condition values.

- -
helm install --set tags.front-end=true --set subchart2.enabled=false
-
-
- -
Tags and Condition Resolution
- -
    -
  • Conditions (when set in values) always override tags. The first condition -path that exists wins and subsequent ones for that chart are ignored.
  • -
  • Tags are evaluated as ‘if any of the chart’s tags are true then enable the chart’.
  • -
  • Tags and conditions values must be set in the top parent’s values.
  • -
  • The tags: key in values must be a top level key. Globals and nested tags: tables -are not currently supported.
  • -
- -

Importing Child Values via requirements.yaml

- -

In some cases it is desirable to allow a child chart’s values to propagate to the parent chart and be -shared as common defaults. An additional benefit of using the exports format is that it will enable future -tooling to introspect user-settable values.

- -

The keys containing the values to be imported can be specified in the parent chart’s requirements.yaml file -using a YAML list. Each item in the list is a key which is imported from the child chart’s exports field.

- -

To import values not contained in the exports key, use the child-parent format. -Examples of both formats are described below.

- -
Using the exports format
- -

If a child chart’s values.yaml file contains an exports field at the root, its contents may be imported -directly into the parent’s values by specifying the keys to import as in the example below:

- -
# parent's requirements.yaml file
-    ...
-    import-values:
-      - data
-
- -
# child's values.yaml file
-...
-exports:
-  data:
-    myint: 99
-
- -

Since we are specifying the key data in our import list, Helm looks in the exports field of the child -chart for data key and imports its contents.

- -

The final parent values would contain our exported field:

- -
# parent's values file
-...
-myint: 99
-
-
- -

Please note the parent key data is not contained in the parent’s final values. If you need to specify the -parent key, use the ‘child-parent’ format.

- -
Using the child-parent format
- -

To access values that are not contained in the exports key of the child chart’s values, you will need to -specify the source key of the values to be imported (child) and the destination path in the parent chart’s -values (parent).

- -

The import-values in the example below instructs Helm to take any values found at child: path and copy them -to the parent’s values at the path specified in parent:

- -
# parent's requirements.yaml file
-dependencies:
-  - name: subchart1
-    repository: http://localhost:10191
-    version: 0.1.0
-    ...
-    import-values:
-      - child: default.data
-        parent: myimports
-
- -

In the above example, values found at default.data in the subchart1’s values will be imported -to the myimports key in the parent chart’s values as detailed below:

- -
# parent's values.yaml file
-
-myimports:
-  myint: 0
-  mybool: false
-  mystring: "helm rocks!"
-  
-
- -
# subchart1's values.yaml file
-
-default:
-  data:
-    myint: 999
-    mybool: true
-    
-
- -

The parent chart’s resulting values would be:

- -
# parent's final values
-
-myimports:
-  myint: 999
-  mybool: true
-  mystring: "helm rocks!"
-
-
- -

The parent’s final values now contains the myint and mybool fields imported from subchart1.

- -

Managing Dependencies manually via the charts/ directory

- -

If more control over dependencies is desired, these dependencies can -be expressed explicitly by copying the dependency charts into the -charts/ directory.

- -

A dependency can be either a chart archive (foo-1.2.3.tgz) or an -unpacked chart directory. But its name cannot start with _ or .. -Such files are ignored by the chart loader.

- -

For example, if the WordPress chart depends on the Apache chart, the -Apache chart (of the correct version) is supplied in the WordPress -chart’s charts/ directory:

- -
wordpress:
-  Chart.yaml
-  requirements.yaml
-  # ...
-  charts/
-    apache/
-      Chart.yaml
-      # ...
-    mysql/
-      Chart.yaml
-      # ...
-
- -

The example above shows how the WordPress chart expresses its dependency -on Apache and MySQL by including those charts inside of its charts/ -directory.

- -

TIP: To drop a dependency into your charts/ directory, use the -helm fetch command

- -

Operational aspects of using dependencies

- -

The above sections explain how to specify chart dependencies, but how does this affect -chart installation using helm install and helm upgrade?

- -

Suppose that a chart named “A” creates the following Kubernetes objects

- -
    -
  • namespace “A-Namespace”
  • -
  • statefulset “A-StatefulSet”
  • -
  • service “A-Service”
  • -
- -

Furthermore, A is dependent on chart B that creates objects

- -
    -
  • namespace “B-Namespace”
  • -
  • replicaset “B-ReplicaSet”
  • -
  • service “B-Service”
  • -
- -

After installation/upgrade of chart A a single Helm release is created/modified. The release will -create/update all of the above Kubernetes objects in the following order:

- -
    -
  • A-Namespace
  • -
  • B-Namespace
  • -
  • A-StatefulSet
  • -
  • B-ReplicaSet
  • -
  • A-Service
  • -
  • B-Service
  • -
- -

This is because when Helm installs/upgrades charts, -the Kubernetes objects from the charts and all its dependencies are

- -
    -
  • aggregrated into a single set; then
  • -
  • sorted by type followed by name; and then
  • -
  • created/updated in that order.
  • -
- -

Hence a single release is created with all the objects for the chart and its dependencies.

- -

The install order of Kubernetes types is given by the enumeration InstallOrder in kind_sorter.go -(see the Helm source file).

- -

Templates and Values

- -

Helm Chart templates are written in the -Go template language, with the -addition of 50 or so add-on template -functions from the Sprig library and a -few other specialized functions.

- -

All template files are stored in a chart’s templates/ folder. When -Helm renders the charts, it will pass every file in that directory -through the template engine.

- -

Values for the templates are supplied two ways:

- -
    -
  • Chart developers may supply a file called values.yaml inside of a -chart. This file can contain default values.
  • -
  • Chart users may supply a YAML file that contains values. This can be -provided on the command line with helm install.
  • -
- -

When a user supplies custom values, these values will override the -values in the chart’s values.yaml file.

- -

Template Files

- -

Template files follow the standard conventions for writing Go templates -(see the text/template Go package documentation -for details). -An example template file might look something like this:

- -
apiVersion: v1
-kind: ReplicationController
-metadata:
-  name: deis-database
-  namespace: deis
-  labels:
-    heritage: deis
-spec:
-  replicas: 1
-  selector:
-    app: deis-database
-  template:
-    metadata:
-      labels:
-        app: deis-database
-    spec:
-      serviceAccount: deis-database
-      containers:
-        - name: deis-database
-          image: {{.Values.imageRegistry}}/postgres:{{.Values.dockerTag}}
-          imagePullPolicy: {{.Values.pullPolicy}}
-          ports:
-            - containerPort: 5432
-          env:
-            - name: DATABASE_STORAGE
-              value: {{default "minio" .Values.storage}}
-
- -

The above example, based loosely on https://github.com/deis/charts, is a template for a Kubernetes replication controller. -It can use the following four template values (usually defined in a -values.yaml file):

- -
    -
  • imageRegistry: The source registry for the Docker image.
  • -
  • dockerTag: The tag for the docker image.
  • -
  • pullPolicy: The Kubernetes pull policy.
  • -
  • storage: The storage backend, whose default is set to "minio"
  • -
- -

All of these values are defined by the template author. Helm does not -require or dictate parameters.

- -

To see many working charts, check out the Kubernetes Charts -project

- -

Predefined Values

- -

Values that are supplied via a values.yaml file (or via the --set -flag) are accessible from the .Values object in a template. But there -are other pre-defined pieces of data you can access in your templates.

- -

The following values are pre-defined, are available to every template, and -cannot be overridden. As with all values, the names are case -sensitive.

- -
    -
  • Release.Name: The name of the release (not the chart)
  • -
  • Release.Time: The time the chart release was last updated. This will -match the Last Released time on a Release object.
  • -
  • Release.Namespace: The namespace the chart was released to.
  • -
  • Release.Service: The service that conducted the release. Usually -this is Tiller.
  • -
  • Release.IsUpgrade: This is set to true if the current operation is an upgrade or rollback.
  • -
  • Release.IsInstall: This is set to true if the current operation is an -install.
  • -
  • Release.Revision: The revision number. It begins at 1, and increments with -each helm upgrade.
  • -
  • Chart: The contents of the Chart.yaml. Thus, the chart version is -obtainable as Chart.Version and the maintainers are in -Chart.Maintainers.
  • -
  • Files: A map-like object containing all non-special files in the chart. This -will not give you access to templates, but will give you access to additional -files that are present (unless they are excluded using .helmignore). Files can be -accessed using {{index .Files "file.name"}} or using the {{.Files.Get name}} or -{{.Files.GetString name}} functions. You can also access the contents of the file -as []byte using {{.Files.GetBytes}}
  • -
  • Capabilities: A map-like object that contains information about the versions -of Kubernetes ({{.Capabilities.KubeVersion}}, Tiller -({{.Capabilities.TillerVersion}}, and the supported Kubernetes API versions -({{.Capabilities.APIVersions.Has "batch/v1")
  • -
- -

NOTE: Any unknown Chart.yaml fields will be dropped. They will not -be accessible inside of the Chart object. Thus, Chart.yaml cannot be -used to pass arbitrarily structured data into the template. The values -file can be used for that, though.

- -

Values files

- -

Considering the template in the previous section, a values.yaml file -that supplies the necessary values would look like this:

- -
imageRegistry: "quay.io/deis"
-dockerTag: "latest"
-pullPolicy: "Always"
-storage: "s3"
-
- -

A values file is formatted in YAML. A chart may include a default -values.yaml file. The Helm install command allows a user to override -values by supplying additional YAML values:

- -
$ helm install --values=myvals.yaml wordpress
-
- -

When values are passed in this way, they will be merged into the default -values file. For example, consider a myvals.yaml file that looks like -this:

- -
storage: "gcs"
-
- -

When this is merged with the values.yaml in the chart, the resulting -generated content will be:

- -
imageRegistry: "quay.io/deis"
-dockerTag: "latest"
-pullPolicy: "Always"
-storage: "gcs"
-
- -

Note that only the last field was overridden.

- -

NOTE: The default values file included inside of a chart must be named -values.yaml. But files specified on the command line can be named -anything.

- -

NOTE: If the --set flag is used on helm install or helm upgrade, those -values are simply converted to YAML on the client side.

- -

NOTE: If any required entries in the values file exist, they can be declared -as required in the chart template by using the ‘required’ function

- -

Any of these values are then accessible inside of templates using the -.Values object:

- -
apiVersion: v1
-kind: ReplicationController
-metadata:
-  name: deis-database
-  namespace: deis
-  labels:
-    heritage: deis
-spec:
-  replicas: 1
-  selector:
-    app: deis-database
-  template:
-    metadata:
-      labels:
-        app: deis-database
-    spec:
-      serviceAccount: deis-database
-      containers:
-        - name: deis-database
-          image: {{.Values.imageRegistry}}/postgres:{{.Values.dockerTag}}
-          imagePullPolicy: {{.Values.pullPolicy}}
-          ports:
-            - containerPort: 5432
-          env:
-            - name: DATABASE_STORAGE
-              value: {{default "minio" .Values.storage}}
-
-
- -

Scope, Dependencies, and Values

- -

Values files can declare values for the top-level chart, as well as for -any of the charts that are included in that chart’s charts/ directory. -Or, to phrase it differently, a values file can supply values to the -chart as well as to any of its dependencies. For example, the -demonstration WordPress chart above has both mysql and apache as -dependencies. The values file could supply values to all of these -components:

- -
title: "My WordPress Site" # Sent to the WordPress template
-
-mysql:
-  max_connections: 100 # Sent to MySQL
-  password: "secret"
-
-apache:
-  port: 8080 # Passed to Apache
-
- -

Charts at a higher level have access to all of the variables defined -beneath. So the WordPress chart can access the MySQL password as -.Values.mysql.password. But lower level charts cannot access things in -parent charts, so MySQL will not be able to access the title property. Nor, -for that matter, can it access apache.port.

- -

Values are namespaced, but namespaces are pruned. So for the WordPress -chart, it can access the MySQL password field as .Values.mysql.password. But -for the MySQL chart, the scope of the values has been reduced and the -namespace prefix removed, so it will see the password field simply as -.Values.password.

- -

Global Values

- -

As of 2.0.0-Alpha.2, Helm supports special “global” value. Consider -this modified version of the previous example:

- -
title: "My WordPress Site" # Sent to the WordPress template
-
-global:
-  app: MyWordPress
-
-mysql:
-  max_connections: 100 # Sent to MySQL
-  password: "secret"
-
-apache:
-  port: 8080 # Passed to Apache
-
- -

The above adds a global section with the value app: MyWordPress. -This value is available to all charts as .Values.global.app.

- -

For example, the mysql templates may access app as {{.Values.global.app}}, and -so can the apache chart. Effectively, the values file above is -regenerated like this:

- -
title: "My WordPress Site" # Sent to the WordPress template
-
-global:
-  app: MyWordPress
-
-mysql:
-  global:
-    app: MyWordPress
-  max_connections: 100 # Sent to MySQL
-  password: "secret"
-
-apache:
-  global:
-    app: MyWordPress
-  port: 8080 # Passed to Apache
-
- -

This provides a way of sharing one top-level variable with all -subcharts, which is useful for things like setting metadata properties -like labels.

- -

If a subchart declares a global variable, that global will be passed -downward (to the subchart’s subcharts), but not upward to the parent -chart. There is no way for a subchart to influence the values of the -parent chart.

- -

Also, global variables of parent charts take precedence over the global variables from subcharts.

- -

References

- -

When it comes to writing templates and values files, there are several -standard references that will help you out.

- - - -

Using Helm to Manage Charts

- -

The helm tool has several commands for working with charts.

- -

It can create a new chart for you:

- -
$ helm create mychart
-Created mychart/
-
- -

Once you have edited a chart, helm can package it into a chart archive -for you:

- -
$ helm package mychart
-Archived mychart-0.1.-.tgz
-
- -

You can also use helm to help you find issues with your chart’s -formatting or information:

- -
$ helm lint mychart
-No issues found
-
- -

Chart Repositories

- -

A chart repository is an HTTP server that houses one or more packaged -charts. While helm can be used to manage local chart directories, when -it comes to sharing charts, the preferred mechanism is a chart -repository.

- -

Any HTTP server that can serve YAML files and tar files and can answer -GET requests can be used as a repository server.

- -

Helm comes with built-in package server for developer testing (helm -serve). The Helm team has tested other servers, including Google Cloud -Storage with website mode enabled, and S3 with website mode enabled.

- -

A repository is characterized primarily by the presence of a special -file called index.yaml that has a list of all of the packages supplied -by the repository, together with metadata that allows retrieving and -verifying those packages.

- -

On the client side, repositories are managed with the helm repo -commands. However, Helm does not provide tools for uploading charts to -remote repository servers. This is because doing so would add -substantial requirements to an implementing server, and thus raise the -barrier for setting up a repository.

- -

Chart Starter Packs

- -

The helm create command takes an optional --starter option that lets you -specify a “starter chart”.

- -

Starters are just regular charts, but are located in $HELM_HOME/starters. -As a chart developer, you may author charts that are specifically designed -to be used as starters. Such charts should be designed with the following -considerations in mind:

- -
    -
  • The Chart.yaml will be overwritten by the generator.
  • -
  • Users will expect to modify such a chart’s contents, so documentation -should indicate how users can do so.
  • -
  • All occurances of <CHARTNAME> will be replaced with the specified chart -name so that starter charts can be used as templates.
  • -
- -

Currently the only way to add a chart to $HELM_HOME/starters is to manually -copy it there. In your chart’s documentation, you may want to explain that -process.

- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/charts_hooks/index.html b/docs.helm.sh/rootfs/public/charts_hooks/index.html deleted file mode 100644 index 60f45a1a90..0000000000 --- a/docs.helm.sh/rootfs/public/charts_hooks/index.html +++ /dev/null @@ -1,1508 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

Hooks

- -

Helm provides a hook mechanism to allow chart developers to intervene -at certain points in a release’s life cycle. For example, you can use -hooks to:

- -
    -
  • Load a ConfigMap or Secret during install before any other charts are -loaded.
  • -
  • Execute a Job to back up a database before installing a new chart, -and then execute a second job after the upgrade in order to restore -data.
  • -
  • Run a Job before deleting a release to gracefully take a service out -of rotation before removing it.
  • -
- -

Hooks work like regular templates, but they have special annotations -that cause Helm to utilize them differently. In this section, we cover -the basic usage pattern for hooks.

- -

The Available Hooks

- -

The following hooks are defined:

- -
    -
  • pre-install: Executes after templates are rendered, but before any -resources are created in Kubernetes.
  • -
  • post-install: Executes after all resources are loaded into Kubernetes
  • -
  • pre-delete: Executes on a deletion request before any resources are -deleted from Kubernetes.
  • -
  • post-delete: Executes on a deletion request after all of the release’s -resources have been deleted.
  • -
  • pre-upgrade: Executes on an upgrade request after templates are -rendered, but before any resources are loaded into Kubernetes (e.g. -before a Kubernetes apply operation).
  • -
  • post-upgrade: Executes on an upgrade after all resources have been -upgraded.
  • -
  • pre-rollback: Executes on a rollback request after templates are -rendered, but before any resources have been rolled back.
  • -
  • post-rollback: Executes on a rollback request after all resources -have been modified.
  • -
- -

Hooks and the Release Lifecycle

- -

Hooks allow you, the chart developer, an opportunity to perform -operations at strategic points in a release lifecycle. For example, -consider the lifecycle for a helm install. By default, the lifecycle -looks like this:

- -
    -
  1. User runs helm install foo
  2. -
  3. Chart is loaded into Tiller
  4. -
  5. After some verification, Tiller renders the foo templates
  6. -
  7. Tiller loads the resulting resources into Kubernetes
  8. -
  9. Tiller returns the release name (and other data) to the client
  10. -
  11. The client exits
  12. -
- -

Helm defines two hooks for the install lifecycle: pre-install and -post-install. If the developer of the foo chart implements both -hooks, the lifecycle is altered like this:

- -
    -
  1. User runs helm install foo
  2. -
  3. Chart is loaded into Tiller
  4. -
  5. After some verification, Tiller renders the foo templates
  6. -
  7. Tiller prepares to execute the pre-install hooks (loading hook resources into -Kubernetes)
  8. -
  9. Tiller sorts hooks by weight (assigning a weight of 0 by default) and by name for those hooks with the same weight in ascending order.
  10. -
  11. Tiller then loads the hook with the lowest weight first (negative to positive)
  12. -
  13. Tiller waits until the hook is “Ready”
  14. -
  15. Tiller loads the resulting resources into Kubernetes. Note that if the --wait -flag is set, Tiller will wait until all resources are in a ready state -and will not run the post-install hook until they are ready.
  16. -
  17. Tiller executes the post-install hook (loading hook resources)
  18. -
  19. Tiller waits until the hook is “Ready”
  20. -
  21. Tiller returns the release name (and other data) to the client
  22. -
  23. The client exits
  24. -
- -

What does it mean to wait until a hook is ready? This depends on the -resource declared in the hook. If the resources is a Job kind, Tiller -will wait until the job successfully runs to completion. And if the job -fails, the release will fail. This is a blocking operation, so the -Helm client will pause while the Job is run.

- -

For all other kinds, as soon as Kubernetes marks the resource as loaded -(added or updated), the resource is considered “Ready”. When many -resources are declared in a hook, the resources are executed serially. If they -have hook weights (see below), they are executed in weighted order. Otherwise, -ordering is not guaranteed. (In Helm 2.3.0 and after, they are sorted -alphabetically. That behavior, though, is not considered binding and could change -in the future.) It is considered good practice to add a hook weight, and set it -to 0 if weight is not important.

- -

Hook resources are not managed with corresponding releases

- -

The resources that a hook creates are not tracked or managed as part of the -release. Once Tiller verifies that the hook has reached its ready state, it -will leave the hook resource alone.

- -

Practically speaking, this means that if you create resources in a hook, you -cannot rely upon helm delete to remove the resources. To destroy such -resources, you need to either write code to perform this operation in a pre-delete -or post-delete hook or add "helm.sh/hook-delete-policy" annotation to the hook template file.

- -

Writing a Hook

- -

Hooks are just Kubernetes manifest files with special annotations in the -metadata section. Because they are template files, you can use all of -the normal template features, including reading .Values, .Release, -and .Template.

- -

For example, this template, stored in templates/post-install-job.yaml, -declares a job to be run on post-install:

- -
apiVersion: batch/v1
-kind: Job
-metadata:
-  name: "{{.Release.Name}}"
-  labels:
-    heritage: {{.Release.Service | quote }}
-    release: {{.Release.Name | quote }}
-    chart: "{{.Chart.Name}}-{{.Chart.Version}}"
-  annotations:
-    # This is what defines this resource as a hook. Without this line, the
-    # job is considered part of the release.
-    "helm.sh/hook": post-install
-    "helm.sh/hook-weight": "-5"
-    "helm.sh/hook-delete-policy": hook-succeeded
-spec:
-  template:
-    metadata:
-      name: "{{.Release.Name}}"
-      labels:
-        heritage: {{.Release.Service | quote }}
-        release: {{.Release.Name | quote }}
-        chart: "{{.Chart.Name}}-{{.Chart.Version}}"
-    spec:
-      restartPolicy: Never
-      containers:
-      - name: post-install-job
-        image: "alpine:3.3"
-        command: ["/bin/sleep","{{default "10" .Values.sleepyTime}}"]
-
-
- -

What makes this template a hook is the annotation:

- -
  annotations:
-    "helm.sh/hook": post-install
-
- -

One resource can implement multiple hooks:

- -
  annotations:
-    "helm.sh/hook": post-install,post-upgrade
-
- -

Similarly, there is no limit to the number of different resources that -may implement a given hook. For example, one could declare both a secret -and a config map as a pre-install hook.

- -

When subcharts declare hooks, those are also evaluated. There is no way -for a top-level chart to disable the hooks declared by subcharts.

- -

It is possible to define a weight for a hook which will help build a -deterministic executing order. Weights are defined using the following annotation:

- -
  annotations:
-    "helm.sh/hook-weight": "5"
-
- -

Hook weights can be positive or negative numbers but must be represented as -strings. When Tiller starts the execution cycle of hooks of a particular Kind it -will sort those hooks in ascending order.

- -

It is also possible to define policies that determine when to delete corresponding hook resources. Hook deletion policies are defined using the following annotation:

- -
  annotations:
-    "helm.sh/hook-delete-policy": hook-succeeded
-
- -

When using "helm.sh/hook-delete-policy" annotation, you can choose its value from "hook-succeeded" and "hook-failed". The value "hook-succeeded" specifies Tiller should delete the hook after the hook is successfully executed, while the value "hook-failed"specifies Tiller should delete the hook if the hook failed during execution.

- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/charts_tips_and_tricks/index.html b/docs.helm.sh/rootfs/public/charts_tips_and_tricks/index.html deleted file mode 100644 index 1d1c713715..0000000000 --- a/docs.helm.sh/rootfs/public/charts_tips_and_tricks/index.html +++ /dev/null @@ -1,1565 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

Chart Development Tips and Tricks

- -

This guide covers some of the tips and tricks Helm chart developers have -learned while building production-quality charts.

- -

Know Your Template Functions

- -

Helm uses Go templates for templating -your resource files. While Go ships several built-in functions, we have -added many others.

- -

First, we added almost all of the functions in the -Sprig library. We removed two -for security reasons: env and expandenv (which would have given chart authors -access to Tiller’s environment).

- -

We also added two special template functions: include and required. The include -function allows you to bring in another template, and then pass the results to other -template functions.

- -

For example, this template snippet includes a template called mytpl, then -lowercases the result, then wraps that in double quotes.

- -
value: {{include "mytpl" . | lower | quote}}
-
- -

The required function allows you to declare a particular -values entry as required for template rendering. If the value is empty, the template -rendering will fail with a user submitted error message.

- -

The following example of the required function declares an entry for .Values.who -is required, and will print an error message when that entry is missing:

- -
value: {{required "A valid .Values.who entry required!" .Values.who }}
-
- -

Quote Strings, Don’t Quote Integers

- -

When you are working with string data, you are always safer quoting the -strings than leaving them as bare words:

- -
name: {{.Values.MyName | quote }}
-
- -

But when working with integers do not quote the values. That can, in -many cases, cause parsing errors inside of Kubernetes.

- -
port: {{ .Values.Port }}
-
- -

This remark does not apply to env variables values which are expected to be string, even if they represent integers:

- -
env:
-  -name: HOST
-    value: "http://host"
-  -name: PORT
-    value: "1234"
-
- -

Using the ‘include’ Function

- -

Go provides a way of including one template in another using a built-in -template directive. However, the built-in function cannot be used in -Go template pipelines.

- -

To make it possible to include a template, and then perform an operation -on that template’s output, Helm has a special include function:

- -
{{ include "toYaml" $value | indent 2 }}
-
- -

The above includes a template called toYaml, passes it $value, and -then passes the output of that template to the indent function.

- -

Because YAML ascribes significance to indentation levels and whitespace, -this is one great way to include snippets of code, but handle -indentation in a relevant context.

- -

Using the ‘required’ function

- -

Go provides a way for setting template options to control behavior -when a map is indexed with a key that’s not present in the map. This -is typically set with template.Options(“missingkey=option”), where option -can be default, zero, or error. While setting this option to error will -stop execution with an error, this would apply to every missing key in the -map. There may be situations where a chart developer wants to enforce this -behavior for select values in the values.yml file.

- -

The required function gives developers the ability to declare a value entry -as required for template rendering. If the entry is empty in values.yml, the -template will not render and will return an error message supplied by the -developer.

- -

For example:

- -
{{ required "A valid foo is required!" .Values.foo }}
-
- -

The above will render the template when .Values.foo is defined, but will fail -to render and exit when .Values.foo is undefined.

- -

Creating Image Pull Secrets

- -

Image pull secrets are essentially a combination of registry, username, and password. You may need them in an application you are deploying, but to create them requires running base64 a couple of times. We can write a helper template to compose the Docker configuration file for use as the Secret’s payload. Here is an example:

- -

First, assume that the credentials are defined in the values.yaml file like so:

- -
imageCredentials:
-  registry: quay.io
-  username: someone
-  password: sillyness
-
- -

We then define our helper template as follows:

- -
{{- define "imagePullSecret" }}
-{{- printf "{\"auths\": {\"%s\": {\"auth\": \"%s\"}}}" .Values.imageCredentials.registry (printf "%s:%s" .Values.imageCredentials.username .Values.imageCredentials.password | b64enc) | b64enc }}
-{{- end }}
-
- -

Finally, we use the helper template in a larger template to create the Secret manifest:

- -
apiVersion: v1
-kind: Secret
-metadata:
-  name: myregistrykey
-type: kubernetes.io/dockerconfigjson
-data:
-  .dockerconfigjson: {{ template "imagePullSecret" . }}
-
- -

Automatically Roll Deployments When ConfigMaps or Secrets change

- -

Often times configmaps or secrets are injected as configuration -files in containers. -Depending on the application a restart may be required should those -be updated with a subsequent helm upgrade, but if the -deployment spec itself didn’t change the application keeps running -with the old configuration resulting in an inconsistent deployment.

- -

The sha256sum function can be used to ensure a deployment’s -annotation section is updated if another file changes:

- -
kind: Deployment
-spec:
-  template:
-    metadata:
-      annotations:
-        checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
-[...]
-
- -

See also the helm upgrade --recreate-pods flag for a slightly -different way of addressing this issue.

- -

Tell Tiller Not To Delete a Resource

- -

Sometimes there are resources that should not be deleted when Helm runs a -helm delete. Chart developers can add an annotation to a resource to prevent -it from being deleted.

- -
kind: Secret
-metadata:
-  annotations:
-    "helm.sh/resource-policy": keep
-[...]
-
- -

(Quotation marks are required)

- -

The annotation "helm.sh/resource-policy": keep instructs Tiller to skip this -resource during a helm delete operation. However, this resource becomes -orphaned. Helm will no longer manage it in any way. This can lead to problems -if using helm install --replace on a release that has already been deleted, but -has kept resources.

- -

Using “Partials” and Template Includes

- -

Sometimes you want to create some reusable parts in your chart, whether -they’re blocks or template partials. And often, it’s cleaner to keep -these in their own files.

- -

In the templates/ directory, any file that begins with an -underscore(_) is not expected to output a Kubernetes manifest file. So -by convention, helper templates and partials are placed in a -_helpers.tpl file.

- -

Complex Charts with Many Dependencies

- -

Many of the charts in the official charts repository -are “building blocks” for creating more advanced applications. But charts may be -used to create instances of large-scale applications. In such cases, a single -umbrella chart may have multiple subcharts, each of which functions as a piece -of the whole.

- -

The current best practice for composing a complex application from discrete parts -is to create a top-level umbrella chart that -exposes the global configurations, and then use the charts/ subdirectory to -embed each of the components.

- -

Two strong design patterns are illustrated by these projects:

- -

SAP’s OpenStack chart: This chart -installs a full OpenStack IaaS on Kubernetes. All of the charts are collected -together in one GitHub repository.

- -

Deis’s Workflow: -This chart exposes the entire Deis PaaS system with one chart. But it’s different -from the SAP chart in that this umbrella chart is built from each component, and -each component is tracked in a different Git repository. Check out the -requirements.yaml file to see how this chart is composed by their CI/CD -pipeline.

- -

Both of these charts illustrate proven techniques for standing up complex environments -using Helm.

- -

YAML is a Superset of JSON

- -

According to the YAML specification, YAML is a superset of JSON. That -means that any valid JSON structure ought to be valid in YAML.

- -

This has an advantage: Sometimes template developers may find it easier -to express a datastructure with a JSON-like syntax rather than deal with -YAML’s whitespace sensitivity.

- -

As a best practice, templates should follow a YAML-like syntax unless -the JSON syntax substantially reduces the risk of a formatting issue.

- -

Be Careful with Generating Random Values

- -

There are functions in Helm that allow you to generate random data, -cryptographic keys, and so on. These are fine to use. But be aware that -during upgrades, templates are re-executed. When a template run -generates data that differs from the last run, that will trigger an -update of that resource.

- -

Upgrade a release idempotently

- -

In order to use the same command when installing and upgrading a release, use the following command:

- -
helm upgrade --install <release name> --values <values file> <chart directory>
-
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/developers/index.html b/docs.helm.sh/rootfs/public/developers/index.html deleted file mode 100644 index 050ebe264a..0000000000 --- a/docs.helm.sh/rootfs/public/developers/index.html +++ /dev/null @@ -1,1570 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

Developers Guide

- -

This guide explains how to set up your environment for developing on -Helm and Tiller.

- -

Prerequisites

- -
    -
  • The latest version of Go
  • -
  • The latest version of Glide
  • -
  • A Kubernetes cluster w/ kubectl (optional)
  • -
  • The gRPC toolchain
  • -
  • Git
  • -
  • Mercurial
  • -
- -

Building Helm/Tiller

- -

We use Make to build our programs. The simplest way to get started is:

- -
$ make bootstrap build
-
- -

NOTE: This will fail if not running from the path $GOPATH/src/k8s.io/helm. The -directory k8s.io should not be a symlink or build will not find the relevant -packages.

- -

This will build both Helm and Tiller. make bootstrap will attempt to -install certain tools if they are missing.

- -

To run all the tests (without running the tests for vendor/), run -make test.

- -

To run Helm and Tiller locally, you can run bin/helm or bin/tiller.

- -
    -
  • Helm and Tiller are known to run on macOS and most Linuxes, including -Alpine.
  • -
  • Tiller must have access to a Kubernetes cluster. It learns about the -cluster by examining the Kube config files that kubectl uses.
  • -
- -

Man pages

- -

Man pages and Markdown documentation are already pre-built in docs/. You may -regenerate documentation using make docs.

- -

To expose the Helm man pages to your man client, you can put the files in your -$MANPATH:

- -
$ export MANPATH=$GOPATH/src/k8s.io/helm/docs/man:$MANPATH
-$ man helm
-
- -

gRPC and Protobuf

- -

Helm and Tiller communicate using gRPC. To get started with gRPC, you will need to…

- -
    -
  • Install protoc for compiling protobuf files. Releases are -here
  • -
  • Run Helm’s make bootstrap to generate the protoc-gen-go plugin and -place it in bin/.
  • -
- -

Note that you need to be on protobuf 3.2.0 (protoc --version). The -version of protoc-gen-go is tied to the version of gRPC used in -Kubernetes. So the plugin is maintained locally.

- -

While the gRPC and ProtoBuf specs remain silent on indentation, we -require that the indentation style matches the Go format specification. -Namely, protocol buffers should use tab-based indentation and rpc -declarations should follow the style of Go function declarations.

- -

The Helm API (HAPI)

- -

We use gRPC as an API layer. See pkg/proto/hapi for the generated Go code, -and _proto for the protocol buffer definitions.

- -

To regenerate the Go files from the protobuf source, make protoc.

- -

Docker Images

- -

To build Docker images, use make docker-build.

- -

Pre-build images are already available in the official Kubernetes Helm -GCR registry.

- -

Running a Local Cluster

- -

For development, we highly recommend using the -Kubernetes Minikube -developer-oriented distribution. Once this is installed, you can use -helm init to install into the cluster. Note that version of tiller you’re using for -development may not be available in Google Cloud Container Registry. If you’re getting -image pull errors, you can override the version of Tiller. Example:

- -
helm init --tiller-image=gcr.io/kubernetes-helm/tiller:2.7.2
-
- -

Or use the latest version:

- -
helm init --canary-image
-
- -

For developing on Tiller, it is sometimes more expedient to run Tiller locally -instead of packaging it into an image and running it in-cluster. You can do -this by telling the Helm client to us a local instance.

- -
$ make build
-$ bin/tiller
-
- -

And to configure the Helm client, use the --host flag or export the HELM_HOST -environment variable:

- -
$ export HELM_HOST=localhost:44134
-$ helm install foo
-
- -

(Note that you do not need to use helm init when you are running Tiller directly)

- -

Tiller should run on any >= 1.3 Kubernetes cluster.

- -

Contribution Guidelines

- -

We welcome contributions. This project has set up some guidelines in -order to ensure that (a) code quality remains high, (b) the project -remains consistent, and © contributions follow the open source legal -requirements. Our intent is not to burden contributors, but to build -elegant and high-quality open source code so that our users will benefit.

- -

Make sure you have read and understood the main CONTRIBUTING guide:

- -

https://github.com/kubernetes/helm/blob/master/CONTRIBUTING.md

- -

Structure of the Code

- -

The code for the Helm project is organized as follows:

- -
    -
  • The individual programs are located in cmd/. Code inside of cmd/ -is not designed for library re-use.
  • -
  • Shared libraries are stored in pkg/.
  • -
  • The raw ProtoBuf files are stored in _proto/hapi (where hapi stands for -the Helm Application Programming Interface).
  • -
  • The Go files generated from the proto definitions are stored in pkg/proto.
  • -
  • The scripts/ directory contains a number of utility scripts. Most of these -are used by the CI/CD pipeline.
  • -
  • The rootfs/ folder is used for Docker-specific files.
  • -
  • The docs/ folder is used for documentation and examples.
  • -
- -

Go dependencies are managed with -Glide and stored in the -vendor/ directory.

- -

Git Conventions

- -

We use Git for our version control system. The master branch is the -home of the current development candidate. Releases are tagged.

- -

We accept changes to the code via GitHub Pull Requests (PRs). One -workflow for doing this is as follows:

- -
    -
  1. Go to your $GOPATH/src/k8s.io directory and git clone the -github.com/kubernetes/helm repository.
  2. -
  3. Fork that repository into your GitHub account
  4. -
  5. Add your repository as a remote for $GOPATH/src/k8s.io/helm
  6. -
  7. Create a new working branch (git checkout -b feat/my-feature) and -do your work on that branch.
  8. -
  9. When you are ready for us to review, push your branch to GitHub, and -then open a new pull request with us.
  10. -
- -

For Git commit messages, we follow the Semantic Commit Messages:

- -
fix(helm): add --foo flag to 'helm install'
-
-When 'helm install --foo bar' is run, this will print "foo" in the
-output regardless of the outcome of the installation.
-
-Closes #1234
-
- -

Common commit types:

- -
    -
  • fix: Fix a bug or error
  • -
  • feat: Add a new feature
  • -
  • docs: Change documentation
  • -
  • test: Improve testing
  • -
  • ref: refactor existing code
  • -
- -

Common scopes:

- -
    -
  • helm: The Helm CLI
  • -
  • tiller: The Tiller server
  • -
  • proto: Protobuf definitions
  • -
  • pkg/lint: The lint package. Follow a similar convention for any -package
  • -
  • *: two or more scopes
  • -
- -

Read more: -- The Deis Guidelines - were the inspiration for this section. -- Karma Runner defines the semantic commit message idea.

- -

Go Conventions

- -

We follow the Go coding style standards very closely. Typically, running -go fmt will make your code beautiful for you.

- -

We also typically follow the conventions recommended by go lint and -gometalinter. Run make test-style to test the style conformance.

- -

Read more:

- - - -

Protobuf Conventions

- -

Because this project is largely Go code, we format our Protobuf files as -closely to Go as possible. There are currently no real formatting rules -or guidelines for Protobuf, but as they emerge, we may opt to follow -those instead.

- -

Standards: -- Tabs for indentation, not spaces. -- Spacing rules follow Go conventions (curly braces at line end, spaces - around operators).

- -

Conventions: -- Files should specify their package with option go_package = "..."; -- Comments should translate into good Go code comments (since protoc - copies comments into the destination source code file). -- RPC functions are defined in the same file as their request/response - messages. -- Deprecated RPCs, messages, and fields are marked deprecated in the comments (// UpdateFoo - DEPRECATED updates a foo.).

- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/developing_charts/index.html b/docs.helm.sh/rootfs/public/developing_charts/index.html deleted file mode 100644 index 76098a8532..0000000000 --- a/docs.helm.sh/rootfs/public/developing_charts/index.html +++ /dev/null @@ -1,3382 +0,0 @@ - - - - - - - - - Developing Charts - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
- -
-
- -

Charts

- -

Helm uses a packaging format called charts. A chart is a collection of files -that describe a related set of Kubernetes resources. A single chart -might be used to deploy something simple, like a memcached pod, or -something complex, like a full web app stack with HTTP servers, -databases, caches, and so on.

- -

Charts are created as files laid out in a particular directory tree, -then they can be packaged into versioned archives to be deployed.

- -

This document explains the chart format, and provides basic guidance for -building charts with Helm.

- -

The Chart File Structure

- -

A chart is organized as a collection of files inside of a directory. The -directory name is the name of the chart (without versioning information). Thus, -a chart describing WordPress would be stored in the wordpress/ directory.

- -

Inside of this directory, Helm will expect a structure that matches this:

- -
wordpress/
-  Chart.yaml          # A YAML file containing information about the chart
-  LICENSE             # OPTIONAL: A plain text file containing the license for the chart
-  README.md           # OPTIONAL: A human-readable README file
-  requirements.yaml   # OPTIONAL: A YAML file listing dependencies for the chart
-  values.yaml         # The default configuration values for this chart
-  charts/             # OPTIONAL: A directory containing any charts upon which this chart depends.
-  templates/          # OPTIONAL: A directory of templates that, when combined with values,
-                      # will generate valid Kubernetes manifest files.
-  templates/NOTES.txt # OPTIONAL: A plain text file containing short usage notes
-
- -

Helm reserves use of the charts/ and templates/ directories, and of -the listed file names. Other files will be left as they are.

- -

While the charts and templates directories are optional there must be at least one chart dependency or template file for the chart to be valid.

- -

The Chart.yaml File

- -

The Chart.yaml file is required for a chart. It contains the following fields:

- -
name: The name of the chart (required)
-version: A SemVer 2 version (required)
-description: A single-sentence description of this project (optional)
-keywords:
-  - A list of keywords about this project (optional)
-home: The URL of this project's home page (optional)
-sources:
-  - A list of URLs to source code for this project (optional)
-maintainers: # (optional)
-  - name: The maintainer's name (required for each maintainer)
-    email: The maintainer's email (optional for each maintainer)
-    url: A URL for the maintainer (optional for each maintainer)
-engine: gotpl # The name of the template engine (optional, defaults to gotpl)
-icon: A URL to an SVG or PNG image to be used as an icon (optional).
-appVersion: The version of the app that this contains (optional). This needn't be SemVer.
-deprecated: Whether this chart is deprecated (optional, boolean)
-tillerVersion: The version of Tiller that this chart requires. This should be expressed as a SemVer range: ">2.0.0" (optional)
-
- -

If you are familiar with the Chart.yaml file format for Helm Classic, you will -notice that fields specifying dependencies have been removed. That is because -the new Chart format expresses dependencies using the charts/ directory.

- -

Other fields will be silently ignored.

- -

Charts and Versioning

- -

Every chart must have a version number. A version must follow the -SemVer 2 standard. Unlike Helm Classic, Kubernetes -Helm uses version numbers as release markers. Packages in repositories -are identified by name plus version.

- -

For example, an nginx chart whose version field is set to version: -1.2.3 will be named:

- -
nginx-1.2.3.tgz
-
- -

More complex SemVer 2 names are also supported, such as -version: 1.2.3-alpha.1+ef365. But non-SemVer names are explicitly -disallowed by the system.

- -

NOTE: Whereas Helm Classic and Deployment Manager were both -very GitHub oriented when it came to charts, Kubernetes Helm does not -rely upon or require GitHub or even Git. Consequently, it does not use -Git SHAs for versioning at all.

- -

The version field inside of the Chart.yaml is used by many of the -Helm tools, including the CLI and the Tiller server. When generating a -package, the helm package command will use the version that it finds -in the Chart.yaml as a token in the package name. The system assumes -that the version number in the chart package name matches the version number in -the Chart.yaml. Failure to meet this assumption will cause an error.

- -

The appVersion field

- -

Note that the appVersion field is not related to the version field. It is -a way of specifying the version of the application. For example, the drupal -chart may have an appVersion: 8.2.1, indicating that the version of Drupal -included in the chart (by default) is 8.2.1. This field is informational, and -has no impact on chart version calculations.

- -

Deprecating Charts

- -

When managing charts in a Chart Repository, it is sometimes necessary to -deprecate a chart. The optional deprecated field in Chart.yaml can be used -to mark a chart as deprecated. If the latest version of a chart in the -repository is marked as deprecated, then the chart as a whole is considered to -be deprecated. The chart name can later be reused by publishing a newer version -that is not marked as deprecated. The workflow for deprecating charts, as -followed by the kubernetes/charts -project is: - - Update chart’s Chart.yaml to mark the chart as deprecated, bumping the - version - - Release the new chart version in the Chart Repository - - Remove the chart from the source repository (e.g. git)

- -

Chart LICENSE, README and NOTES

- -

Charts can also contain files that describe the installation, configuration, usage and license of a -chart. A README for a chart should be formatted in Markdown (README.md), and should generally -contain:

- -
    -
  • A description of the application or service the chart provides
  • -
  • Any prerequisites or requirements to run the chart
  • -
  • Descriptions of options in values.yaml and default values
  • -
  • Any other information that may be relevant to the installation or configuration of the chart
  • -
- -

The chart can also contain a short plain text templates/NOTES.txt file that will be printed out -after installation, and when viewing the status of a release. This file is evaluated as a -template, and can be used to display usage notes, next steps, or any other -information relevant to a release of the chart. For example, instructions could be provided for -connecting to a database, or accessing a web UI. Since this file is printed to STDOUT when running -helm install or helm status, it is recommended to keep the content brief and point to the README -for greater detail.

- -

Chart Dependencies

- -

In Helm, one chart may depend on any number of other charts. -These dependencies can be dynamically linked through the requirements.yaml -file or brought in to the charts/ directory and managed manually.

- -

Although manually managing your dependencies has a few advantages some teams need, -the preferred method of declaring dependencies is by using a -requirements.yaml file inside of your chart.

- -

Note: The dependencies: section of the Chart.yaml from Helm -Classic has been completely removed.

- -

Managing Dependencies with requirements.yaml

- -

A requirements.yaml file is a simple file for listing your -dependencies.

- -
dependencies:
-  - name: apache
-    version: 1.2.3
-    repository: http://example.com/charts
-  - name: mysql
-    version: 3.2.1
-    repository: http://another.example.com/charts
-
- -
    -
  • The name field is the name of the chart you want.
  • -
  • The version field is the version of the chart you want.
  • -
  • The repository field is the full URL to the chart repository. Note -that you must also use helm repo add to add that repo locally.
  • -
- -

Once you have a dependencies file, you can run helm dependency update -and it will use your dependency file to download all the specified -charts into your charts/ directory for you.

- -
$ helm dep up foochart
-Hang tight while we grab the latest from your chart repositories...
-...Successfully got an update from the "local" chart repository
-...Successfully got an update from the "stable" chart repository
-...Successfully got an update from the "example" chart repository
-...Successfully got an update from the "another" chart repository
-Update Complete. Happy Helming!
-Saving 2 charts
-Downloading apache from repo http://example.com/charts
-Downloading mysql from repo http://another.example.com/charts
-
- -

When helm dependency update retrieves charts, it will store them as -chart archives in the charts/ directory. So for the example above, one -would expect to see the following files in the charts directory:

- -
charts/
-  apache-1.2.3.tgz
-  mysql-3.2.1.tgz
-
- -

Managing charts with requirements.yaml is a good way to easily keep -charts updated, and also share requirements information throughout a -team.

- -

Alias field in requirements.yaml

- -

In addition to the other fields above, each requirements entry may contain -the optional field alias.

- -

Adding an alias for a dependency chart would put -a chart in dependencies using alias as name of new dependency.

- -

One can use alias in cases where they need to access a chart -with other name(s).

- -
# parentchart/requirements.yaml
-dependencies:
-  - name: subchart
-    repository: http://localhost:10191
-    version: 0.1.0
-    alias: new-subchart-1
-  - name: subchart
-    repository: http://localhost:10191
-    version: 0.1.0
-    alias: new-subchart-2
-  - name: subchart
-    repository: http://localhost:10191
-    version: 0.1.0
-
- -

In the above example we will get 3 dependencies in all for parentchart

- -
subchart
-new-subchart-1
-new-subchart-2
-
- -

The manual way of achieving this is by copy/pasting the same chart in the -charts/ directory multiple times with different names.

- -

Tags and Condition fields in requirements.yaml

- -

In addition to the other fields above, each requirements entry may contain -the optional fields tags and condition.

- -

All charts are loaded by default. If tags or condition fields are present, -they will be evaluated and used to control loading for the chart(s) they are applied to.

- -

Condition - The condition field holds one or more YAML paths (delimited by commas). -If this path exists in the top parent’s values and resolves to a boolean value, -the chart will be enabled or disabled based on that boolean value. Only the first -valid path found in the list is evaluated and if no paths exist then the condition has no effect.

- -

Tags - The tags field is a YAML list of labels to associate with this chart. -In the top parent’s values, all charts with tags can be enabled or disabled by -specifying the tag and a boolean value.

- -
# parentchart/requirements.yaml
-dependencies:
-      - name: subchart1
-        repository: http://localhost:10191
-        version: 0.1.0
-        condition: subchart1.enabled, global.subchart1.enabled
-        tags:
-          - front-end
-          - subchart1
-
-      - name: subchart2
-        repository: http://localhost:10191
-        version: 0.1.0
-        condition: subchart2.enabled,global.subchart2.enabled
-        tags:
-          - back-end
-          - subchart2
-
-
- -
# parentchart/values.yaml
-
-subchart1:
-  enabled: true
-tags:
-  front-end: false
-  back-end: true
-
- -

In the above example all charts with the tag front-end would be disabled but since the -subchart1.enabled path evaluates to ‘true’ in the parent’s values, the condition will override the -front-end tag and subchart1 will be enabled.

- -

Since subchart2 is tagged with back-end and that tag evaluates to true, subchart2 will be -enabled. Also notes that although subchart2 has a condition specified in requirements.yaml, there -is no corresponding path and value in the parent’s values so that condition has no effect.

- -
Using the CLI with Tags and Conditions
- -

The --set parameter can be used as usual to alter tag and condition values.

- -
helm install --set tags.front-end=true --set subchart2.enabled=false
-
-
- -
Tags and Condition Resolution
- -
    -
  • Conditions (when set in values) always override tags. The first condition -path that exists wins and subsequent ones for that chart are ignored.
  • -
  • Tags are evaluated as ‘if any of the chart’s tags are true then enable the chart’.
  • -
  • Tags and conditions values must be set in the top parent’s values.
  • -
  • The tags: key in values must be a top level key. Globals and nested tags: tables -are not currently supported.
  • -
- -

Importing Child Values via requirements.yaml

- -

In some cases it is desirable to allow a child chart’s values to propagate to the parent chart and be -shared as common defaults. An additional benefit of using the exports format is that it will enable future -tooling to introspect user-settable values.

- -

The keys containing the values to be imported can be specified in the parent chart’s requirements.yaml file -using a YAML list. Each item in the list is a key which is imported from the child chart’s exports field.

- -

To import values not contained in the exports key, use the child-parent format. -Examples of both formats are described below.

- -
Using the exports format
- -

If a child chart’s values.yaml file contains an exports field at the root, its contents may be imported -directly into the parent’s values by specifying the keys to import as in the example below:

- -
# parent's requirements.yaml file
-    ...
-    import-values:
-      - data
-
- -
# child's values.yaml file
-...
-exports:
-  data:
-    myint: 99
-
- -

Since we are specifying the key data in our import list, Helm looks in the exports field of the child -chart for data key and imports its contents.

- -

The final parent values would contain our exported field:

- -
# parent's values file
-...
-myint: 99
-
-
- -

Please note the parent key data is not contained in the parent’s final values. If you need to specify the -parent key, use the ‘child-parent’ format.

- -
Using the child-parent format
- -

To access values that are not contained in the exports key of the child chart’s values, you will need to -specify the source key of the values to be imported (child) and the destination path in the parent chart’s -values (parent).

- -

The import-values in the example below instructs Helm to take any values found at child: path and copy them -to the parent’s values at the path specified in parent:

- -
# parent's requirements.yaml file
-dependencies:
-  - name: subchart1
-    repository: http://localhost:10191
-    version: 0.1.0
-    ...
-    import-values:
-      - child: default.data
-        parent: myimports
-
- -

In the above example, values found at default.data in the subchart1’s values will be imported -to the myimports key in the parent chart’s values as detailed below:

- -
# parent's values.yaml file
-
-myimports:
-  myint: 0
-  mybool: false
-  mystring: "helm rocks!"
-  
-
- -
# subchart1's values.yaml file
-
-default:
-  data:
-    myint: 999
-    mybool: true
-    
-
- -

The parent chart’s resulting values would be:

- -
# parent's final values
-
-myimports:
-  myint: 999
-  mybool: true
-  mystring: "helm rocks!"
-
-
- -

The parent’s final values now contains the myint and mybool fields imported from subchart1.

- -

Managing Dependencies manually via the charts/ directory

- -

If more control over dependencies is desired, these dependencies can -be expressed explicitly by copying the dependency charts into the -charts/ directory.

- -

A dependency can be either a chart archive (foo-1.2.3.tgz) or an -unpacked chart directory. But its name cannot start with _ or .. -Such files are ignored by the chart loader.

- -

For example, if the WordPress chart depends on the Apache chart, the -Apache chart (of the correct version) is supplied in the WordPress -chart’s charts/ directory:

- -
wordpress:
-  Chart.yaml
-  requirements.yaml
-  # ...
-  charts/
-    apache/
-      Chart.yaml
-      # ...
-    mysql/
-      Chart.yaml
-      # ...
-
- -

The example above shows how the WordPress chart expresses its dependency -on Apache and MySQL by including those charts inside of its charts/ -directory.

- -

TIP: To drop a dependency into your charts/ directory, use the -helm fetch command

- -

Operational aspects of using dependencies

- -

The above sections explain how to specify chart dependencies, but how does this affect -chart installation using helm install and helm upgrade?

- -

Suppose that a chart named “A” creates the following Kubernetes objects

- -
    -
  • namespace “A-Namespace”
  • -
  • statefulset “A-StatefulSet”
  • -
  • service “A-Service”
  • -
- -

Furthermore, A is dependent on chart B that creates objects

- -
    -
  • namespace “B-Namespace”
  • -
  • replicaset “B-ReplicaSet”
  • -
  • service “B-Service”
  • -
- -

After installation/upgrade of chart A a single Helm release is created/modified. The release will -create/update all of the above Kubernetes objects in the following order:

- -
    -
  • A-Namespace
  • -
  • B-Namespace
  • -
  • A-StatefulSet
  • -
  • B-ReplicaSet
  • -
  • A-Service
  • -
  • B-Service
  • -
- -

This is because when Helm installs/upgrades charts, -the Kubernetes objects from the charts and all its dependencies are

- -
    -
  • aggregrated into a single set; then
  • -
  • sorted by type followed by name; and then
  • -
  • created/updated in that order.
  • -
- -

Hence a single release is created with all the objects for the chart and its dependencies.

- -

The install order of Kubernetes types is given by the enumeration InstallOrder in kind_sorter.go -(see the Helm source file).

- -

Templates and Values

- -

Helm Chart templates are written in the -Go template language, with the -addition of 50 or so add-on template -functions from the Sprig library and a -few other specialized functions.

- -

All template files are stored in a chart’s templates/ folder. When -Helm renders the charts, it will pass every file in that directory -through the template engine.

- -

Values for the templates are supplied two ways:

- -
    -
  • Chart developers may supply a file called values.yaml inside of a -chart. This file can contain default values.
  • -
  • Chart users may supply a YAML file that contains values. This can be -provided on the command line with helm install.
  • -
- -

When a user supplies custom values, these values will override the -values in the chart’s values.yaml file.

- -

Template Files

- -

Template files follow the standard conventions for writing Go templates -(see the text/template Go package documentation -for details). -An example template file might look something like this:

- -
apiVersion: v1
-kind: ReplicationController
-metadata:
-  name: deis-database
-  namespace: deis
-  labels:
-    heritage: deis
-spec:
-  replicas: 1
-  selector:
-    app: deis-database
-  template:
-    metadata:
-      labels:
-        app: deis-database
-    spec:
-      serviceAccount: deis-database
-      containers:
-        - name: deis-database
-          image: {{.Values.imageRegistry}}/postgres:{{.Values.dockerTag}}
-          imagePullPolicy: {{.Values.pullPolicy}}
-          ports:
-            - containerPort: 5432
-          env:
-            - name: DATABASE_STORAGE
-              value: {{default "minio" .Values.storage}}
-
- -

The above example, based loosely on https://github.com/deis/charts, is a template for a Kubernetes replication controller. -It can use the following four template values (usually defined in a -values.yaml file):

- -
    -
  • imageRegistry: The source registry for the Docker image.
  • -
  • dockerTag: The tag for the docker image.
  • -
  • pullPolicy: The Kubernetes pull policy.
  • -
  • storage: The storage backend, whose default is set to "minio"
  • -
- -

All of these values are defined by the template author. Helm does not -require or dictate parameters.

- -

To see many working charts, check out the Kubernetes Charts -project

- -

Predefined Values

- -

Values that are supplied via a values.yaml file (or via the --set -flag) are accessible from the .Values object in a template. But there -are other pre-defined pieces of data you can access in your templates.

- -

The following values are pre-defined, are available to every template, and -cannot be overridden. As with all values, the names are case -sensitive.

- -
    -
  • Release.Name: The name of the release (not the chart)
  • -
  • Release.Time: The time the chart release was last updated. This will -match the Last Released time on a Release object.
  • -
  • Release.Namespace: The namespace the chart was released to.
  • -
  • Release.Service: The service that conducted the release. Usually -this is Tiller.
  • -
  • Release.IsUpgrade: This is set to true if the current operation is an upgrade or rollback.
  • -
  • Release.IsInstall: This is set to true if the current operation is an -install.
  • -
  • Release.Revision: The revision number. It begins at 1, and increments with -each helm upgrade.
  • -
  • Chart: The contents of the Chart.yaml. Thus, the chart version is -obtainable as Chart.Version and the maintainers are in -Chart.Maintainers.
  • -
  • Files: A map-like object containing all non-special files in the chart. This -will not give you access to templates, but will give you access to additional -files that are present (unless they are excluded using .helmignore). Files can be -accessed using {{index .Files "file.name"}} or using the {{.Files.Get name}} or -{{.Files.GetString name}} functions. You can also access the contents of the file -as []byte using {{.Files.GetBytes}}
  • -
  • Capabilities: A map-like object that contains information about the versions -of Kubernetes ({{.Capabilities.KubeVersion}}, Tiller -({{.Capabilities.TillerVersion}}, and the supported Kubernetes API versions -({{.Capabilities.APIVersions.Has "batch/v1")
  • -
- -

NOTE: Any unknown Chart.yaml fields will be dropped. They will not -be accessible inside of the Chart object. Thus, Chart.yaml cannot be -used to pass arbitrarily structured data into the template. The values -file can be used for that, though.

- -

Values files

- -

Considering the template in the previous section, a values.yaml file -that supplies the necessary values would look like this:

- -
imageRegistry: "quay.io/deis"
-dockerTag: "latest"
-pullPolicy: "Always"
-storage: "s3"
-
- -

A values file is formatted in YAML. A chart may include a default -values.yaml file. The Helm install command allows a user to override -values by supplying additional YAML values:

- -
$ helm install --values=myvals.yaml wordpress
-
- -

When values are passed in this way, they will be merged into the default -values file. For example, consider a myvals.yaml file that looks like -this:

- -
storage: "gcs"
-
- -

When this is merged with the values.yaml in the chart, the resulting -generated content will be:

- -
imageRegistry: "quay.io/deis"
-dockerTag: "latest"
-pullPolicy: "Always"
-storage: "gcs"
-
- -

Note that only the last field was overridden.

- -

NOTE: The default values file included inside of a chart must be named -values.yaml. But files specified on the command line can be named -anything.

- -

NOTE: If the --set flag is used on helm install or helm upgrade, those -values are simply converted to YAML on the client side.

- -

NOTE: If any required entries in the values file exist, they can be declared -as required in the chart template by using the ‘required’ function

- -

Any of these values are then accessible inside of templates using the -.Values object:

- -
apiVersion: v1
-kind: ReplicationController
-metadata:
-  name: deis-database
-  namespace: deis
-  labels:
-    heritage: deis
-spec:
-  replicas: 1
-  selector:
-    app: deis-database
-  template:
-    metadata:
-      labels:
-        app: deis-database
-    spec:
-      serviceAccount: deis-database
-      containers:
-        - name: deis-database
-          image: {{.Values.imageRegistry}}/postgres:{{.Values.dockerTag}}
-          imagePullPolicy: {{.Values.pullPolicy}}
-          ports:
-            - containerPort: 5432
-          env:
-            - name: DATABASE_STORAGE
-              value: {{default "minio" .Values.storage}}
-
-
- -

Scope, Dependencies, and Values

- -

Values files can declare values for the top-level chart, as well as for -any of the charts that are included in that chart’s charts/ directory. -Or, to phrase it differently, a values file can supply values to the -chart as well as to any of its dependencies. For example, the -demonstration WordPress chart above has both mysql and apache as -dependencies. The values file could supply values to all of these -components:

- -
title: "My WordPress Site" # Sent to the WordPress template
-
-mysql:
-  max_connections: 100 # Sent to MySQL
-  password: "secret"
-
-apache:
-  port: 8080 # Passed to Apache
-
- -

Charts at a higher level have access to all of the variables defined -beneath. So the WordPress chart can access the MySQL password as -.Values.mysql.password. But lower level charts cannot access things in -parent charts, so MySQL will not be able to access the title property. Nor, -for that matter, can it access apache.port.

- -

Values are namespaced, but namespaces are pruned. So for the WordPress -chart, it can access the MySQL password field as .Values.mysql.password. But -for the MySQL chart, the scope of the values has been reduced and the -namespace prefix removed, so it will see the password field simply as -.Values.password.

- -

Global Values

- -

As of 2.0.0-Alpha.2, Helm supports special “global” value. Consider -this modified version of the previous example:

- -
title: "My WordPress Site" # Sent to the WordPress template
-
-global:
-  app: MyWordPress
-
-mysql:
-  max_connections: 100 # Sent to MySQL
-  password: "secret"
-
-apache:
-  port: 8080 # Passed to Apache
-
- -

The above adds a global section with the value app: MyWordPress. -This value is available to all charts as .Values.global.app.

- -

For example, the mysql templates may access app as {{.Values.global.app}}, and -so can the apache chart. Effectively, the values file above is -regenerated like this:

- -
title: "My WordPress Site" # Sent to the WordPress template
-
-global:
-  app: MyWordPress
-
-mysql:
-  global:
-    app: MyWordPress
-  max_connections: 100 # Sent to MySQL
-  password: "secret"
-
-apache:
-  global:
-    app: MyWordPress
-  port: 8080 # Passed to Apache
-
- -

This provides a way of sharing one top-level variable with all -subcharts, which is useful for things like setting metadata properties -like labels.

- -

If a subchart declares a global variable, that global will be passed -downward (to the subchart’s subcharts), but not upward to the parent -chart. There is no way for a subchart to influence the values of the -parent chart.

- -

Also, global variables of parent charts take precedence over the global variables from subcharts.

- -

References

- -

When it comes to writing templates and values files, there are several -standard references that will help you out.

- - - -

Using Helm to Manage Charts

- -

The helm tool has several commands for working with charts.

- -

It can create a new chart for you:

- -
$ helm create mychart
-Created mychart/
-
- -

Once you have edited a chart, helm can package it into a chart archive -for you:

- -
$ helm package mychart
-Archived mychart-0.1.-.tgz
-
- -

You can also use helm to help you find issues with your chart’s -formatting or information:

- -
$ helm lint mychart
-No issues found
-
- -

Chart Repositories

- -

A chart repository is an HTTP server that houses one or more packaged -charts. While helm can be used to manage local chart directories, when -it comes to sharing charts, the preferred mechanism is a chart -repository.

- -

Any HTTP server that can serve YAML files and tar files and can answer -GET requests can be used as a repository server.

- -

Helm comes with built-in package server for developer testing (helm -serve). The Helm team has tested other servers, including Google Cloud -Storage with website mode enabled, and S3 with website mode enabled.

- -

A repository is characterized primarily by the presence of a special -file called index.yaml that has a list of all of the packages supplied -by the repository, together with metadata that allows retrieving and -verifying those packages.

- -

On the client side, repositories are managed with the helm repo -commands. However, Helm does not provide tools for uploading charts to -remote repository servers. This is because doing so would add -substantial requirements to an implementing server, and thus raise the -barrier for setting up a repository.

- -

Chart Starter Packs

- -

The helm create command takes an optional --starter option that lets you -specify a “starter chart”.

- -

Starters are just regular charts, but are located in $HELM_HOME/starters. -As a chart developer, you may author charts that are specifically designed -to be used as starters. Such charts should be designed with the following -considerations in mind:

- -
    -
  • The Chart.yaml will be overwritten by the generator.
  • -
  • Users will expect to modify such a chart’s contents, so documentation -should indicate how users can do so.
  • -
  • All occurances of <CHARTNAME> will be replaced with the specified chart -name so that starter charts can be used as templates.
  • -
- -

Currently the only way to add a chart to $HELM_HOME/starters is to manually -copy it there. In your chart’s documentation, you may want to explain that -process.

- -

Hooks

- -

Helm provides a hook mechanism to allow chart developers to intervene -at certain points in a release’s life cycle. For example, you can use -hooks to:

- -
    -
  • Load a ConfigMap or Secret during install before any other charts are -loaded.
  • -
  • Execute a Job to back up a database before installing a new chart, -and then execute a second job after the upgrade in order to restore -data.
  • -
  • Run a Job before deleting a release to gracefully take a service out -of rotation before removing it.
  • -
- -

Hooks work like regular templates, but they have special annotations -that cause Helm to utilize them differently. In this section, we cover -the basic usage pattern for hooks.

- -

The Available Hooks

- -

The following hooks are defined:

- -
    -
  • pre-install: Executes after templates are rendered, but before any -resources are created in Kubernetes.
  • -
  • post-install: Executes after all resources are loaded into Kubernetes
  • -
  • pre-delete: Executes on a deletion request before any resources are -deleted from Kubernetes.
  • -
  • post-delete: Executes on a deletion request after all of the release’s -resources have been deleted.
  • -
  • pre-upgrade: Executes on an upgrade request after templates are -rendered, but before any resources are loaded into Kubernetes (e.g. -before a Kubernetes apply operation).
  • -
  • post-upgrade: Executes on an upgrade after all resources have been -upgraded.
  • -
  • pre-rollback: Executes on a rollback request after templates are -rendered, but before any resources have been rolled back.
  • -
  • post-rollback: Executes on a rollback request after all resources -have been modified.
  • -
- -

Hooks and the Release Lifecycle

- -

Hooks allow you, the chart developer, an opportunity to perform -operations at strategic points in a release lifecycle. For example, -consider the lifecycle for a helm install. By default, the lifecycle -looks like this:

- -
    -
  1. User runs helm install foo
  2. -
  3. Chart is loaded into Tiller
  4. -
  5. After some verification, Tiller renders the foo templates
  6. -
  7. Tiller loads the resulting resources into Kubernetes
  8. -
  9. Tiller returns the release name (and other data) to the client
  10. -
  11. The client exits
  12. -
- -

Helm defines two hooks for the install lifecycle: pre-install and -post-install. If the developer of the foo chart implements both -hooks, the lifecycle is altered like this:

- -
    -
  1. User runs helm install foo
  2. -
  3. Chart is loaded into Tiller
  4. -
  5. After some verification, Tiller renders the foo templates
  6. -
  7. Tiller prepares to execute the pre-install hooks (loading hook resources into -Kubernetes)
  8. -
  9. Tiller sorts hooks by weight (assigning a weight of 0 by default) and by name for those hooks with the same weight in ascending order.
  10. -
  11. Tiller then loads the hook with the lowest weight first (negative to positive)
  12. -
  13. Tiller waits until the hook is “Ready”
  14. -
  15. Tiller loads the resulting resources into Kubernetes. Note that if the --wait -flag is set, Tiller will wait until all resources are in a ready state -and will not run the post-install hook until they are ready.
  16. -
  17. Tiller executes the post-install hook (loading hook resources)
  18. -
  19. Tiller waits until the hook is “Ready”
  20. -
  21. Tiller returns the release name (and other data) to the client
  22. -
  23. The client exits
  24. -
- -

What does it mean to wait until a hook is ready? This depends on the -resource declared in the hook. If the resources is a Job kind, Tiller -will wait until the job successfully runs to completion. And if the job -fails, the release will fail. This is a blocking operation, so the -Helm client will pause while the Job is run.

- -

For all other kinds, as soon as Kubernetes marks the resource as loaded -(added or updated), the resource is considered “Ready”. When many -resources are declared in a hook, the resources are executed serially. If they -have hook weights (see below), they are executed in weighted order. Otherwise, -ordering is not guaranteed. (In Helm 2.3.0 and after, they are sorted -alphabetically. That behavior, though, is not considered binding and could change -in the future.) It is considered good practice to add a hook weight, and set it -to 0 if weight is not important.

- -

Hook resources are not managed with corresponding releases

- -

The resources that a hook creates are not tracked or managed as part of the -release. Once Tiller verifies that the hook has reached its ready state, it -will leave the hook resource alone.

- -

Practically speaking, this means that if you create resources in a hook, you -cannot rely upon helm delete to remove the resources. To destroy such -resources, you need to either write code to perform this operation in a pre-delete -or post-delete hook or add "helm.sh/hook-delete-policy" annotation to the hook template file.

- -

Writing a Hook

- -

Hooks are just Kubernetes manifest files with special annotations in the -metadata section. Because they are template files, you can use all of -the normal template features, including reading .Values, .Release, -and .Template.

- -

For example, this template, stored in templates/post-install-job.yaml, -declares a job to be run on post-install:

- -
apiVersion: batch/v1
-kind: Job
-metadata:
-  name: "{{.Release.Name}}"
-  labels:
-    heritage: {{.Release.Service | quote }}
-    release: {{.Release.Name | quote }}
-    chart: "{{.Chart.Name}}-{{.Chart.Version}}"
-  annotations:
-    # This is what defines this resource as a hook. Without this line, the
-    # job is considered part of the release.
-    "helm.sh/hook": post-install
-    "helm.sh/hook-weight": "-5"
-    "helm.sh/hook-delete-policy": hook-succeeded
-spec:
-  template:
-    metadata:
-      name: "{{.Release.Name}}"
-      labels:
-        heritage: {{.Release.Service | quote }}
-        release: {{.Release.Name | quote }}
-        chart: "{{.Chart.Name}}-{{.Chart.Version}}"
-    spec:
-      restartPolicy: Never
-      containers:
-      - name: post-install-job
-        image: "alpine:3.3"
-        command: ["/bin/sleep","{{default "10" .Values.sleepyTime}}"]
-
-
- -

What makes this template a hook is the annotation:

- -
  annotations:
-    "helm.sh/hook": post-install
-
- -

One resource can implement multiple hooks:

- -
  annotations:
-    "helm.sh/hook": post-install,post-upgrade
-
- -

Similarly, there is no limit to the number of different resources that -may implement a given hook. For example, one could declare both a secret -and a config map as a pre-install hook.

- -

When subcharts declare hooks, those are also evaluated. There is no way -for a top-level chart to disable the hooks declared by subcharts.

- -

It is possible to define a weight for a hook which will help build a -deterministic executing order. Weights are defined using the following annotation:

- -
  annotations:
-    "helm.sh/hook-weight": "5"
-
- -

Hook weights can be positive or negative numbers but must be represented as -strings. When Tiller starts the execution cycle of hooks of a particular Kind it -will sort those hooks in ascending order.

- -

It is also possible to define policies that determine when to delete corresponding hook resources. Hook deletion policies are defined using the following annotation:

- -
  annotations:
-    "helm.sh/hook-delete-policy": hook-succeeded
-
- -

When using "helm.sh/hook-delete-policy" annotation, you can choose its value from "hook-succeeded" and "hook-failed". The value "hook-succeeded" specifies Tiller should delete the hook after the hook is successfully executed, while the value "hook-failed"specifies Tiller should delete the hook if the hook failed during execution.

- -

Chart Development Tips and Tricks

- -

This guide covers some of the tips and tricks Helm chart developers have -learned while building production-quality charts.

- -

Know Your Template Functions

- -

Helm uses Go templates for templating -your resource files. While Go ships several built-in functions, we have -added many others.

- -

First, we added almost all of the functions in the -Sprig library. We removed two -for security reasons: env and expandenv (which would have given chart authors -access to Tiller’s environment).

- -

We also added two special template functions: include and required. The include -function allows you to bring in another template, and then pass the results to other -template functions.

- -

For example, this template snippet includes a template called mytpl, then -lowercases the result, then wraps that in double quotes.

- -
value: {{include "mytpl" . | lower | quote}}
-
- -

The required function allows you to declare a particular -values entry as required for template rendering. If the value is empty, the template -rendering will fail with a user submitted error message.

- -

The following example of the required function declares an entry for .Values.who -is required, and will print an error message when that entry is missing:

- -
value: {{required "A valid .Values.who entry required!" .Values.who }}
-
- -

Quote Strings, Don’t Quote Integers

- -

When you are working with string data, you are always safer quoting the -strings than leaving them as bare words:

- -
name: {{.Values.MyName | quote }}
-
- -

But when working with integers do not quote the values. That can, in -many cases, cause parsing errors inside of Kubernetes.

- -
port: {{ .Values.Port }}
-
- -

This remark does not apply to env variables values which are expected to be string, even if they represent integers:

- -
env:
-  -name: HOST
-    value: "http://host"
-  -name: PORT
-    value: "1234"
-
- -

Using the ‘include’ Function

- -

Go provides a way of including one template in another using a built-in -template directive. However, the built-in function cannot be used in -Go template pipelines.

- -

To make it possible to include a template, and then perform an operation -on that template’s output, Helm has a special include function:

- -
{{ include "toYaml" $value | indent 2 }}
-
- -

The above includes a template called toYaml, passes it $value, and -then passes the output of that template to the indent function.

- -

Because YAML ascribes significance to indentation levels and whitespace, -this is one great way to include snippets of code, but handle -indentation in a relevant context.

- -

Using the ‘required’ function

- -

Go provides a way for setting template options to control behavior -when a map is indexed with a key that’s not present in the map. This -is typically set with template.Options(“missingkey=option”), where option -can be default, zero, or error. While setting this option to error will -stop execution with an error, this would apply to every missing key in the -map. There may be situations where a chart developer wants to enforce this -behavior for select values in the values.yml file.

- -

The required function gives developers the ability to declare a value entry -as required for template rendering. If the entry is empty in values.yml, the -template will not render and will return an error message supplied by the -developer.

- -

For example:

- -
{{ required "A valid foo is required!" .Values.foo }}
-
- -

The above will render the template when .Values.foo is defined, but will fail -to render and exit when .Values.foo is undefined.

- -

Creating Image Pull Secrets

- -

Image pull secrets are essentially a combination of registry, username, and password. You may need them in an application you are deploying, but to create them requires running base64 a couple of times. We can write a helper template to compose the Docker configuration file for use as the Secret’s payload. Here is an example:

- -

First, assume that the credentials are defined in the values.yaml file like so:

- -
imageCredentials:
-  registry: quay.io
-  username: someone
-  password: sillyness
-
- -

We then define our helper template as follows:

- -
{{- define "imagePullSecret" }}
-{{- printf "{\"auths\": {\"%s\": {\"auth\": \"%s\"}}}" .Values.imageCredentials.registry (printf "%s:%s" .Values.imageCredentials.username .Values.imageCredentials.password | b64enc) | b64enc }}
-{{- end }}
-
- -

Finally, we use the helper template in a larger template to create the Secret manifest:

- -
apiVersion: v1
-kind: Secret
-metadata:
-  name: myregistrykey
-type: kubernetes.io/dockerconfigjson
-data:
-  .dockerconfigjson: {{ template "imagePullSecret" . }}
-
- -

Automatically Roll Deployments When ConfigMaps or Secrets change

- -

Often times configmaps or secrets are injected as configuration -files in containers. -Depending on the application a restart may be required should those -be updated with a subsequent helm upgrade, but if the -deployment spec itself didn’t change the application keeps running -with the old configuration resulting in an inconsistent deployment.

- -

The sha256sum function can be used to ensure a deployment’s -annotation section is updated if another file changes:

- -
kind: Deployment
-spec:
-  template:
-    metadata:
-      annotations:
-        checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
-[...]
-
- -

See also the helm upgrade --recreate-pods flag for a slightly -different way of addressing this issue.

- -

Tell Tiller Not To Delete a Resource

- -

Sometimes there are resources that should not be deleted when Helm runs a -helm delete. Chart developers can add an annotation to a resource to prevent -it from being deleted.

- -
kind: Secret
-metadata:
-  annotations:
-    "helm.sh/resource-policy": keep
-[...]
-
- -

(Quotation marks are required)

- -

The annotation "helm.sh/resource-policy": keep instructs Tiller to skip this -resource during a helm delete operation. However, this resource becomes -orphaned. Helm will no longer manage it in any way. This can lead to problems -if using helm install --replace on a release that has already been deleted, but -has kept resources.

- -

Using “Partials” and Template Includes

- -

Sometimes you want to create some reusable parts in your chart, whether -they’re blocks or template partials. And often, it’s cleaner to keep -these in their own files.

- -

In the templates/ directory, any file that begins with an -underscore(_) is not expected to output a Kubernetes manifest file. So -by convention, helper templates and partials are placed in a -_helpers.tpl file.

- -

Complex Charts with Many Dependencies

- -

Many of the charts in the official charts repository -are “building blocks” for creating more advanced applications. But charts may be -used to create instances of large-scale applications. In such cases, a single -umbrella chart may have multiple subcharts, each of which functions as a piece -of the whole.

- -

The current best practice for composing a complex application from discrete parts -is to create a top-level umbrella chart that -exposes the global configurations, and then use the charts/ subdirectory to -embed each of the components.

- -

Two strong design patterns are illustrated by these projects:

- -

SAP’s OpenStack chart: This chart -installs a full OpenStack IaaS on Kubernetes. All of the charts are collected -together in one GitHub repository.

- -

Deis’s Workflow: -This chart exposes the entire Deis PaaS system with one chart. But it’s different -from the SAP chart in that this umbrella chart is built from each component, and -each component is tracked in a different Git repository. Check out the -requirements.yaml file to see how this chart is composed by their CI/CD -pipeline.

- -

Both of these charts illustrate proven techniques for standing up complex environments -using Helm.

- -

YAML is a Superset of JSON

- -

According to the YAML specification, YAML is a superset of JSON. That -means that any valid JSON structure ought to be valid in YAML.

- -

This has an advantage: Sometimes template developers may find it easier -to express a datastructure with a JSON-like syntax rather than deal with -YAML’s whitespace sensitivity.

- -

As a best practice, templates should follow a YAML-like syntax unless -the JSON syntax substantially reduces the risk of a formatting issue.

- -

Be Careful with Generating Random Values

- -

There are functions in Helm that allow you to generate random data, -cryptographic keys, and so on. These are fine to use. But be aware that -during upgrades, templates are re-executed. When a template run -generates data that differs from the last run, that will trigger an -update of that resource.

- -

Upgrade a release idempotently

- -

In order to use the same command when installing and upgrading a release, use the following command:

- -
helm upgrade --install <release name> --values <values file> <chart directory>
-
- -

The Chart Repository Guide

- -

This section explains how to create and work with Helm chart repositories. At a -high level, a chart repository is a location where packaged charts can be -stored and shared.

- -

The official chart repository is maintained by the -Kubernetes Charts, and we welcome -participation. But Helm also makes it easy to create and run your own chart -repository. This guide explains how to do so.

- -

Prerequisites

- - - -

Create a chart repository

- -

A chart repository is an HTTP server that houses an index.yaml file and -optionally some packaged charts. When you’re ready to share your charts, the -preferred way to do so is by uploading them to a chart repository.

- -

Note: For Helm 2.0.0, chart repositories do not have any intrinsic -authentication. There is an issue tracking progress -in GitHub.

- -

Because a chart repository can be any HTTP server that can serve YAML and tar -files and can answer GET requests, you have a plethora of options when it comes -down to hosting your own chart repository. For example, you can use a Google -Cloud Storage (GCS) bucket, Amazon S3 bucket, Github Pages, or even create your -own web server.

- -

The chart repository structure

- -

A chart repository consists of packaged charts and a special file called -index.yaml which contains an index of all of the charts in the repository. -Frequently, the charts that index.yaml describes are also hosted on the same -server, as are the provenance files.

- -

For example, the layout of the repository https://example.com/charts might -look like this:

- -
charts/
-  |
-  |- index.yaml
-  |
-  |- alpine-0.1.2.tgz
-  |
-  |- alpine-0.1.2.tgz.prov
-
- -

In this case, the index file would contain information about one chart, the Alpine -chart, and provide the download URL https://example.com/charts/alpine-0.1.2.tgz -for that chart.

- -

It is not required that a chart package be located on the same server as the -index.yaml file. However, doing so is often the easiest.

- -

The index file

- -

The index file is a yaml file called index.yaml. It -contains some metadata about the package, including the contents of a -chart’s Chart.yaml file. A valid chart repository must have an index file. The -index file contains information about each chart in the chart repository. The -helm repo index command will generate an index file based on a given local -directory that contains packaged charts.

- -

This is an example of an index file:

- -
apiVersion: v1
-entries:
-  alpine:
-    - created: 2016-10-06T16:23:20.499814565-06:00
-      description: Deploy a basic Alpine Linux pod
-      digest: 99c76e403d752c84ead610644d4b1c2f2b453a74b921f422b9dcb8a7c8b559cd
-      home: https://k8s.io/helm
-      name: alpine
-      sources:
-      - https://github.com/kubernetes/helm
-      urls:
-      - https://technosophos.github.io/tscharts/alpine-0.2.0.tgz
-      version: 0.2.0
-    - created: 2016-10-06T16:23:20.499543808-06:00
-      description: Deploy a basic Alpine Linux pod
-      digest: 515c58e5f79d8b2913a10cb400ebb6fa9c77fe813287afbacf1a0b897cd78727
-      home: https://k8s.io/helm
-      name: alpine
-      sources:
-      - https://github.com/kubernetes/helm
-      urls:
-      - https://technosophos.github.io/tscharts/alpine-0.1.0.tgz
-      version: 0.1.0
-  nginx:
-    - created: 2016-10-06T16:23:20.499543808-06:00
-      description: Create a basic nginx HTTP server
-      digest: aaff4545f79d8b2913a10cb400ebb6fa9c77fe813287afbacf1a0b897cdffffff
-      home: https://k8s.io/helm
-      name: nginx
-      sources:
-      - https://github.com/kubernetes/charts
-      urls:
-      - https://technosophos.github.io/tscharts/nginx-1.1.0.tgz
-      version: 1.1.0
-generated: 2016-10-06T16:23:20.499029981-06:00
-
- -

A generated index and packages can be served from a basic webserver. You can test -things out locally with the helm serve command, which starts a local server.

- -
$ helm serve --repo-path ./charts
-Regenerating index. This may take a moment.
-Now serving you on 127.0.0.1:8879
-
- -

The above starts a local webserver, serving the charts it finds in ./charts. The -serve command will automatically generate an index.yaml file for you during -startup.

- -

Hosting Chart Repositories

- -

This part shows several ways to serve a chart repository.

- -

Google Cloud Storage

- -

The first step is to create your GCS bucket. We’ll call ours -fantastic-charts.

- -

Create a GCS Bucket

- -

Next, make your bucket public by editing the bucket permissions.

- -

Edit Permissions

- -

Insert this line item to make your bucket public:

- -

Make Bucket Public

- -

Congratulations, now you have an empty GCS bucket ready to serve charts!

- -

You may upload your chart repository using the Google Cloud Storage command line -tool, or using the GCS web UI. This is the technique the official Kubernetes -Charts repository hosts its charts, so you may want to take a -peek at that project if you get stuck.

- -

Note: A public GCS bucket can be accessed via simple HTTPS at this address -https://bucket-name.storage.googleapis.com/.

- -

Github Pages example

- -

In a similar way you can create charts repository using GitHub Pages.

- -

GitHub allows you to serve static web pages in two different ways:

- -
    -
  • By configuring a project to serve the contents of its docs/ directory
  • -
  • By configuring a project to serve a particular branch
  • -
- -

We’ll take the second approach, though the first is just as easy.

- -

The first step will be to create your gh-pages branch. You can do that -locally as.

- -
$ git checkout -b gh-pages
-
- -

Or via web browser using Branch button on your Github repository:

- -

Create Github Pages branch

- -

Next, you’ll want to make sure your gh-pages branch is set as Github Pages, -click on your repo Settings and scroll down to Github pages section and -set as per below:

- -

Create Github Pages branch

- -

By default Source usually gets set to gh-pages branch. If this is not set by default, then select it.

- -

You can use a custom domain there if you wish so.

- -

And check that Enforce HTTPS is ticked, so the HTTPS will be used when -charts are served.

- -

In such setup you can use master branch to store your charts code, and -gh-pages branch as charts repository, e.g.: -https://USERNAME.github.io/REPONAME. The demonstration TS Charts -repository is accessible at https://technosophos.github.io/tscharts/.

- -

Ordinary web servers

- -

To configure an ordinary web server to serve Helm charts, you merely need to do -the following:

- -
    -
  • Put your index and charts in a directory that the server can serve
  • -
  • Make sure the index.yaml file can be accessed with no authentication requirement
  • -
  • Make sure yaml files are served with the correct content type (text/yaml or -text/x-yaml)
  • -
- -

For example, if you want to serve your charts out of $WEBROOT/charts, make sure -there is a charts/ directory in your web root, and put the index file and -charts inside of that folder.

- -

Managing Chart Repositories

- -

Now that you have a chart repository, the last part of this guide explains how -to maintain charts in that repository.

- -

Store charts in your chart repository

- -

Now that you have a chart repository, let’s upload a chart and an index file to -the repository. Charts in a chart repository must be packaged -(helm package chart-name/) and versioned correctly (following -SemVer 2 guidelines).

- -

These next steps compose an example workflow, but you are welcome to use -whatever workflow you fancy for storing and updating charts in your chart -repository.

- -

Once you have a packaged chart ready, create a new directory, and move your -packaged chart to that directory.

- -
$ helm package docs/examples/alpine/
-$ mkdir fantastic-charts
-$ mv alpine-0.1.0.tgz fantastic-charts/
-$ helm repo index fantastic-charts --url https://fantastic-charts.storage.googleapis.com
-
- -

The last command takes the path of the local directory that you just created and -the URL of your remote chart repository and composes an index.yaml file inside the -given directory path.

- -

Now you can upload the chart and the index file to your chart repository using -a sync tool or manually. If you’re using Google Cloud Storage, check out this -example workflow using the gsutil client. For -GitHub, you can simply put the charts in the appropriate destination branch.

- -

Add new charts to an existing repository

- -

Each time you want to add a new chart to your repository, you must regenerate -the index. The helm repo index command will completely rebuild the index.yaml -file from scratch, including only the charts that it finds locally.

- -

However, you can use the --merge flag to incrementally add new charts to an -existing index.yaml file (a great option when working with a remote repository -like GCS). Run helm repo index --help to learn more,

- -

Make sure that you upload both the revised index.yaml file and the chart. And -if you generated a provenance file, upload that too.

- -

Share your charts with others

- -

When you’re ready to share your charts, simply let someone know what the URL of -your repository is.

- -

From there, they will add the repository to their helm client via the helm -repo add [NAME] [URL] command with any name they would like to use to -reference the repository.

- -
$ helm repo add fantastic-charts https://fantastic-charts.storage.googleapis.com
-$ helm repo list
-fantastic-charts    https://fantastic-charts.storage.googleapis.com
-
- -

If the charts are backed by HTTP basic authentication, you can also supply the -username and password here:

- -
$ helm repo add fantastic-charts https://username:password@fantastic-charts.storage.googleapis.com
-$ helm repo list
-fantastic-charts    https://username:password@fantastic-charts.storage.googleapis.com
-
- -

Note: A repository will not be added if it does not contain a valid -index.yaml.

- -

After that, your users will be able to search through your charts. After you’ve updated -the repository, they can use the helm repo update command to get the latest -chart information.

- -

Under the hood, the helm repo add and helm repo update commands are -fetching the index.yaml file and storing them in the -$HELM_HOME/repository/cache/ directory. This is where the helm search -function finds information about charts.

- -

Syncing Your Chart Repository

- -

Note: This example is specifically for a Google Cloud Storage (GCS) bucket which serves a chart repository.

- -

Prerequisites

- -
    -
  • Install the gsutil tool. We rely heavily on the gsutil rsync functionality
  • -
  • Be sure to have access to the helm binary
  • -
  • _Optional: We recommend you set object versioning on your GCS bucket in case you accidentally delete something._
  • -
- -

Set up a local chart repository directory

- -

Create a local directory like we did in the chart repository guide, and place your packaged charts in that directory.

- -

For example:

- -
$ mkdir fantastic-charts
-$ mv alpine-0.1.0.tgz fantastic-charts/
-
- -

Generate an updated index.yaml

- -

Use helm to generate an updated index.yaml file by passing in the directory path and the url of the remote repository to the helm repo index command like this:

- -
$ helm repo index fantastic-charts/ --url https://fantastic-charts.storage.googleapis.com
-
- -

This will generate an updated index.yaml file and place in the fantastic-charts/ directory.

- -

Sync your local and remote chart repositories

- -

Upload the contents of the directory to your GCS bucket by running scripts/sync-repo.sh and pass in the local directory name and the GCS bucket name.

- -

For example:

- -
$ pwd
-/Users/funuser/go/src/github.com/kubernetes/helm
-$ scripts/sync-repo.sh fantastic-charts/ fantastic-charts
-Getting ready to sync your local directory (fantastic-charts/) to a remote repository at gs://fantastic-charts
-Verifying Prerequisites....
-Thumbs up! Looks like you have gsutil. Let's continue.
-Building synchronization state...
-Starting synchronization
-Would copy file://fantastic-charts/alpine-0.1.0.tgz to gs://fantastic-charts/alpine-0.1.0.tgz
-Would copy file://fantastic-charts/index.yaml to gs://fantastic-charts/index.yaml
-Are you sure you would like to continue with these changes?? [y/N]} y
-Building synchronization state...
-Starting synchronization
-Copying file://fantastic-charts/alpine-0.1.0.tgz [Content-Type=application/x-tar]...
-Uploading   gs://fantastic-charts/alpine-0.1.0.tgz:              740 B/740 B
-Copying file://fantastic-charts/index.yaml [Content-Type=application/octet-stream]...
-Uploading   gs://fantastic-charts/index.yaml:                    347 B/347 B
-Congratulations your remote chart repository now matches the contents of fantastic-charts/
-
- -

Updating your chart repository

- -

You’ll want to keep a local copy of the contents of your chart repository or use gsutil rsync to copy the contents of your remote chart repository to a local directory.

- -

For example:

- -
$ gsutil rsync -d -n gs://bucket-name local-dir/    # the -n flag does a dry run
-Building synchronization state...
-Starting synchronization
-Would copy gs://bucket-name/alpine-0.1.0.tgz to file://local-dir/alpine-0.1.0.tgz
-Would copy gs://bucket-name/index.yaml to file://local-dir/index.yaml
-
-$ gsutil rsync -d gs://bucket-name local-dir/       # performs the copy actions
-Building synchronization state...
-Starting synchronization
-Copying gs://bucket-name/alpine-0.1.0.tgz...
-Downloading file://local-dir/alpine-0.1.0.tgz:                        740 B/740 B
-Copying gs://bucket-name/index.yaml...
-Downloading file://local-dir/index.yaml:                              346 B/346 B
-
- -

Helpful Links: -* Documentation on gsutil rsync -* The Chart Repository Guide -* Documentation on object versioning and concurrency control in Google Cloud Storage

- -

Helm Provenance and Integrity

- -

Helm has provenance tools which help chart users verify the integrity and origin -of a package. Using industry-standard tools based on PKI, GnuPG, and well-respected -package managers, Helm can generate and verify signature files.

- -

Note: -Version 2.0.0-alpha.4 introduced a system for verifying the authenticity of charts. -While we do not anticipate that any major changes will be made to the file formats -or provenancing algorithms, this portion of Helm is not considered frozen until -2.0.0-RC1 is released. The original plan for this feature can be found -at issue 983.

- -

Overview

- -

Integrity is established by comparing a chart to a provenance record. Provenance -records are stored in provenance files, which are stored alongside a packaged -chart. For example, if a chart is named myapp-1.2.3.tgz, its provenance file -will be myapp-1.2.3.tgz.prov.

- -

Provenance files are generated at packaging time (helm package --sign ...), and -can be checked by multiple commands, notable helm install --verify.

- -

The Workflow

- -

This section describes a potential workflow for using provenance data effectively.

- -

Prerequisites:

- -
    -
  • A valid PGP keypair in a binary (not ASCII-armored) format
  • -
  • The helm command line tool
  • -
  • GnuPG command line tools (optional)
  • -
  • Keybase command line tools (optional)
  • -
- -

NOTE: If your PGP private key has a passphrase, you will be prompted to enter -that passphrase for any commands that support the --sign option.

- -

Creating a new chart is the same as before:

- -
$ helm create mychart
-Creating mychart
-
- -

Once ready to package, add the --sign flag to helm package. Also, specify -the name under which the signing key is known and the keyring containing the corresponding private key:

- -
$ helm package --sign --key 'helm signing key' --keyring path/to/keyring.secret mychart
-
- -

TIP: for GnuPG users, your secret keyring is in ~/.gnupg/secring.gpg. You can -use gpg --list-secret-keys to list the keys you have.

- -

At this point, you should see both mychart-0.1.0.tgz and mychart-0.1.0.tgz.prov. -Both files should eventually be uploaded to your desired chart repository.

- -

You can verify a chart using helm verify:

- -
$ helm verify mychart-0.1.0.tgz
-
- -

A failed verification looks like this:

- -
$ helm verify topchart-0.1.0.tgz
-Error: sha256 sum does not match for topchart-0.1.0.tgz: "sha256:1939fbf7c1023d2f6b865d137bbb600e0c42061c3235528b1e8c82f4450c12a7" != "sha256:5a391a90de56778dd3274e47d789a2c84e0e106e1a37ef8cfa51fd60ac9e623a"
-
- -

To verify during an install, use the --verify flag.

- -
$ helm install --verify mychart-0.1.0.tgz
-
- -

If the keyring (containing the public key associated with the signed chart) is not in the default location, you may need to point to the -keyring with --keyring PATH as in the helm package example.

- -

If verification fails, the install will be aborted before the chart is even pushed -up to Tiller.

- -

Using Keybase.io credentials

- -

The Keybase.io service makes it easy to establish a chain of -trust for a cryptographic identity. Keybase credentials can be used to sign charts.

- -

Prerequisites:

- -
    -
  • A configured Keybase.io account
  • -
  • GnuPG installed locally
  • -
  • The keybase CLI installed locally
  • -
- -

Signing packages

- -

The first step is to import your keybase keys into your local GnuPG keyring:

- -
$ keybase pgp export -s | gpg --import
-
- -

This will convert your Keybase key into the OpenPGP format, and then import it -locally into your ~/.gnupg/secring.gpg file.

- -

You can double check by running gpg --list-secret-keys.

- -
$ gpg --list-secret-keys                                                                                                       1 ↵
-/Users/mattbutcher/.gnupg/secring.gpg
--------------------------------------
-sec   2048R/1FC18762 2016-07-25
-uid                  technosophos (keybase.io/technosophos) <technosophos@keybase.io>
-ssb   2048R/D125E546 2016-07-25
-
- -

Note that your secret key will have an identifier string:

- -
technosophos (keybase.io/technosophos) <technosophos@keybase.io>
-
- -

That is the full name of your key.

- -

Next, you can package and sign a chart with helm package. Make sure you use at -least part of that name string in --key.

- -
$ helm package --sign --key technosophos --keyring ~/.gnupg/secring.gpg mychart
-
- -

As a result, the package command should produce both a .tgz file and a .tgz.prov -file.

- -

Verifying packages

- -

You can also use a similar technique to verify a chart signed by someone else’s -Keybase key. Say you want to verify a package signed by keybase.io/technosophos. -To do this, use the keybase tool:

- -
$ keybase follow technosophos
-$ keybase pgp pull
-
- -

The first command above tracks the user technosophos. Next keybase pgp pull -downloads the OpenPGP keys of all of the accounts you follow, placing them in -your GnuPG keyring (~/.gnupg/pubring.gpg).

- -

At this point, you can now use helm verify or any of the commands with a --verify -flag:

- -
$ helm verify somechart-1.2.3.tgz
-
- -

Reasons a chart may not verify

- -

These are common reasons for failure.

- -
    -
  • The prov file is missing or corrupt. This indicates that something is misconfigured -or that the original maintainer did not create a provenance file.
  • -
  • The key used to sign the file is not in your keyring. This indicate that the -entity who signed the chart is not someone you’ve already signaled that you trust.
  • -
  • The verification of the prov file failed. This indicates that something is wrong -with either the chart or the provenance data.
  • -
  • The file hashes in the provenance file do not match the hash of the archive file. This -indicates that the archive has been tampered with.
  • -
- -

If a verification fails, there is reason to distrust the package.

- -

The Provenance File

- -

The provenance file contains a chart’s YAML file plus several pieces of -verification information. Provenance files are designed to be automatically -generated.

- -

The following pieces of provenance data are added:

- -
    -
  • The chart file (Chart.yaml) is included to give both humans and tools an easy -view into the contents of the chart.
  • -
  • The signature (SHA256, just like Docker) of the chart package (the .tgz file) -is included, and may be used to verify the integrity of the chart package.
  • -
  • The entire body is signed using the algorithm used by PGP (see -[http://keybase.io] for an emerging way of making crypto signing and -verification easy).
  • -
- -

The combination of this gives users the following assurances:

- -
    -
  • The package itself has not been tampered with (checksum package tgz).
  • -
  • The entity who released this package is known (via the GnuPG/PGP signature).
  • -
- -

The format of the file looks something like this:

- -
-----BEGIN PGP SIGNED MESSAGE-----
-name: nginx
-description: The nginx web server as a replication controller and service pair.
-version: 0.5.1
-keywords:
-  - https
-  - http
-  - web server
-  - proxy
-source:
-- https://github.com/foo/bar
-home: http://nginx.com
-
-...
-files:
-        nginx-0.5.1.tgz: “sha256:9f5270f50fc842cfcb717f817e95178f”
------BEGIN PGP SIGNATURE-----
-Version: GnuPG v1.4.9 (GNU/Linux)
-
-iEYEARECAAYFAkjilUEACgQkB01zfu119ZnHuQCdGCcg2YxF3XFscJLS4lzHlvte
-WkQAmQGHuuoLEJuKhRNo+Wy7mhE7u1YG
-=eifq
------END PGP SIGNATURE-----
-
- -

Note that the YAML section contains two documents (separated by ...\n). The -first is the Chart.yaml. The second is the checksums, a map of filenames to -SHA-256 digests (value shown is fake/truncated)

- -

The signature block is a standard PGP signature, which provides tamper -resistance.

- -

Chart Repositories

- -

Chart repositories serve as a centralized collection of Helm charts.

- -

Chart repositories must make it possible to serve provenance files over HTTP via -a specific request, and must make them available at the same URI path as the chart.

- -

For example, if the base URL for a package is https://example.com/charts/mychart-1.2.3.tgz, -the provenance file, if it exists, MUST be accessible at https://example.com/charts/mychart-1.2.3.tgz.prov.

- -

From the end user’s perspective, helm install --verify myrepo/mychart-1.2.3 -should result in the download of both the chart and the provenance file with no -additional user configuration or action.

- -

Establishing Authority and Authenticity

- -

When dealing with chain-of-trust systems, it is important to be able to -establish the authority of a signer. Or, to put this plainly, the system -above hinges on the fact that you trust the person who signed the chart. -That, in turn, means you need to trust the public key of the signer.

- -

One of the design decisions with Kubernetes Helm has been that the Helm -project would not insert itself into the chain of trust as a necessary -party. We don’t want to be “the certificate authority” for all chart -signers. Instead, we strongly favor a decentralized model, which is part -of the reason we chose OpenPGP as our foundational technology. -So when it comes to establishing authority, we have left this -step more-or-less undefined in Helm 2.0.0.

- -

However, we have some pointers and recommendations for those interested -in using the provenance system:

- -
    -
  • The Keybase platform provides a public -centralized repository for trust information. - -
      -
    • You can use Keybase to store your keys or to get the public keys of others.
    • -
    • Keybase also has fabulous documentation available
    • -
    • While we haven’t tested it, Keybase’s “secure website” feature could -be used to serve Helm charts.
    • -
  • -
  • The official Kubernetes Charts project -is trying to solve this problem for the official chart repository. - -
      -
    • There is a long issue there detailing the current thoughts.
    • -
    • The basic idea is that an official “chart reviewer” signs charts with -her or his key, and the resulting provenance file is then uploaded -to the chart repository.
    • -
    • There has been some work on the idea that a list of valid signing -keys may be included in the index.yaml file of a repository.
    • -
  • -
- -

Finally, chain-of-trust is an evolving feature of Helm, and some -community members have proposed adapting part of the OSI model for -signatures. This is an open line of inquiry in the Helm team. If you’re -interested, jump on in.

- -

Chart Tests

- -

A chart contains a number of Kubernetes resources and components that work together. As a chart author, you may want to write some tests that validate that your chart works as expected when it is installed. These tests also help the chart consumer understand what your chart is supposed to do.

- -

A test in a helm chart lives under the templates/ directory and is a pod definition that specifies a container with a given command to run. The container should exit successfully (exit 0) for a test to be considered a success. The pod definition must contain one of the helm test hook annotations: helm.sh/hooks: test-success or helm.sh/hooks: test-failure.

- -

Example tests: -- Validate that your configuration from the values.yaml file was properly injected. - - Make sure your username and password work correctly - - Make sure an incorrect username and password does not work -- Assert that your services are up and correctly load balancing -- etc.

- -

You can run the pre-defined tests in Helm on a release using the command helm test <RELEASE_NAME>. For a chart consumer, this is a great way to sanity check that their release of a chart (or application) works as expected.

- -

A Breakdown of the Helm Test Hooks

- -

In Helm, there are two test hooks: test-success and test-failure

- -

test-success indicates that test pod should complete successfully. In other words, the containers in the pod should exit 0. -test-failure is a way to assert that a test pod should not complete successfully. If the containers in the pod do not exit 0, that indicates success.

- -

Example Test

- -

Here is an example of a helm test pod definition in an example mariadb chart:

- -
mariadb/
-  Chart.yaml
-  README.md
-  values.yaml
-  charts/
-  templates/
-  templates/tests/test-mariadb-connection.yaml
-
- -

In wordpress/templates/tests/test-mariadb-connection.yaml:

- -
apiVersion: v1
-kind: Pod
-metadata:
-  name: "{{ .Release.Name }}-credentials-test"
-  annotations:
-    "helm.sh/hook": test-success
-spec:
-  containers:
-  - name: {{ .Release.Name }}-credentials-test
-    image: {{ .Values.image }}
-    env:
-      - name: MARIADB_HOST
-        value: {{ template "mariadb.fullname" . }}
-      - name: MARIADB_PORT
-        value: "3306"
-      - name: WORDPRESS_DATABASE_NAME
-        value: {{ default "" .Values.mariadb.mariadbDatabase | quote }}
-      - name: WORDPRESS_DATABASE_USER
-        value: {{ default "" .Values.mariadb.mariadbUser | quote }}
-      - name: WORDPRESS_DATABASE_PASSWORD
-        valueFrom:
-          secretKeyRef:
-            name: {{ template "mariadb.fullname" . }}
-            key: mariadb-password
-    command: ["sh", "-c", "mysql --host=$MARIADB_HOST --port=$MARIADB_PORT --user=$WORDPRESS_DATABASE_USER --password=$WORDPRESS_DATABASE_PASSWORD"]
-  restartPolicy: Never
-
- -

Steps to Run a Test Suite on a Release

- -
    -
  1. $ helm install mariadb

    - -
    NAME:   quirky-walrus
    -LAST DEPLOYED: Mon Feb 13 13:50:43 2017
    -NAMESPACE: default
    -STATUS: DEPLOYED
    -
  2. - -
  3. $ helm test quirky-walrus

    - -
    RUNNING: quirky-walrus-credentials-test
    -SUCCESS: quirky-walrus-credentials-test
    -
  4. -
- -

Notes

- -
    -
  • You can define as many tests as you would like in a single yaml file or spread across several yaml files in the templates/ directory
  • -
  • You are welcome to nest your test suite under a tests/ directory like <chart-name>/templates/tests/ for more isolation
  • -
- -

Chart Repositories: Frequently Asked Questions

- -

This section tracks some of the more frequently encountered issues with using chart repositories.

- -

We’d love your help making this document better. To add, correct, or remove -information, file an issue or -send us a pull request.

- -

Fetching

- -

Q: Why do I get a unsupported protocol scheme "" error when trying to fetch a chart from my custom repo?

- -

A: (Helm < 2.5.0) This is likely caused by you creating your chart repo index without specifying the --url flag. -Try recreating your index.yaml file with a command like helm repo index --url http://my-repo/charts ., -and then re-uploading it to your custom charts repo.

- -

This behavior was changed in Helm 2.5.0.

-
-
- -
-
 
-
- -
-
-

- Helm is supported by and built with a community of over 250 developers. -

-

- helm.sh and docs.helm.sh are maintained by Microsoft -

-
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/developing_charts/index.md/index.html b/docs.helm.sh/rootfs/public/developing_charts/index.md/index.html deleted file mode 100644 index 46ab06f877..0000000000 --- a/docs.helm.sh/rootfs/public/developing_charts/index.md/index.html +++ /dev/null @@ -1 +0,0 @@ -https://docs.helm.sh/chart_template_guide/ \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/developing_charts/index.xml b/docs.helm.sh/rootfs/public/developing_charts/index.xml deleted file mode 100644 index 0d612f6ab4..0000000000 --- a/docs.helm.sh/rootfs/public/developing_charts/index.xml +++ /dev/null @@ -1,2065 +0,0 @@ - - - - Developing_charts - https://docs.helm.sh/developing_charts/ - en-us - Mon, 01 Jan 0001 00:00:00 UTC - - - - https://docs.helm.sh/developing_charts/ - Mon, 01 Jan 0001 00:00:00 UTC - https://docs.helm.sh/developing_charts/ - - -<h1 id="charts">Charts</h1> - -<p>Helm uses a packaging format called <em>charts</em>. A chart is a collection of files -that describe a related set of Kubernetes resources. A single chart -might be used to deploy something simple, like a memcached pod, or -something complex, like a full web app stack with HTTP servers, -databases, caches, and so on.</p> - -<p>Charts are created as files laid out in a particular directory tree, -then they can be packaged into versioned archives to be deployed.</p> - -<p>This document explains the chart format, and provides basic guidance for -building charts with Helm.</p> - -<h2 id="the-chart-file-structure">The Chart File Structure</h2> - -<p>A chart is organized as a collection of files inside of a directory. The -directory name is the name of the chart (without versioning information). Thus, -a chart describing WordPress would be stored in the <code>wordpress/</code> directory.</p> - -<p>Inside of this directory, Helm will expect a structure that matches this:</p> - -<pre><code>wordpress/ - Chart.yaml # A YAML file containing information about the chart - LICENSE # OPTIONAL: A plain text file containing the license for the chart - README.md # OPTIONAL: A human-readable README file - requirements.yaml # OPTIONAL: A YAML file listing dependencies for the chart - values.yaml # The default configuration values for this chart - charts/ # OPTIONAL: A directory containing any charts upon which this chart depends. - templates/ # OPTIONAL: A directory of templates that, when combined with values, - # will generate valid Kubernetes manifest files. - templates/NOTES.txt # OPTIONAL: A plain text file containing short usage notes -</code></pre> - -<p>Helm reserves use of the <code>charts/</code> and <code>templates/</code> directories, and of -the listed file names. Other files will be left as they are.</p> - -<p>While the <code>charts</code> and <code>templates</code> directories are optional there must be at least one chart dependency or template file for the chart to be valid.</p> - -<h2 id="the-chart-yaml-file">The Chart.yaml File</h2> - -<p>The <code>Chart.yaml</code> file is required for a chart. It contains the following fields:</p> - -<pre><code class="language-yaml">name: The name of the chart (required) -version: A SemVer 2 version (required) -description: A single-sentence description of this project (optional) -keywords: - - A list of keywords about this project (optional) -home: The URL of this project's home page (optional) -sources: - - A list of URLs to source code for this project (optional) -maintainers: # (optional) - - name: The maintainer's name (required for each maintainer) - email: The maintainer's email (optional for each maintainer) - url: A URL for the maintainer (optional for each maintainer) -engine: gotpl # The name of the template engine (optional, defaults to gotpl) -icon: A URL to an SVG or PNG image to be used as an icon (optional). -appVersion: The version of the app that this contains (optional). This needn't be SemVer. -deprecated: Whether this chart is deprecated (optional, boolean) -tillerVersion: The version of Tiller that this chart requires. This should be expressed as a SemVer range: &quot;&gt;2.0.0&quot; (optional) -</code></pre> - -<p>If you are familiar with the <code>Chart.yaml</code> file format for Helm Classic, you will -notice that fields specifying dependencies have been removed. That is because -the new Chart format expresses dependencies using the <code>charts/</code> directory.</p> - -<p>Other fields will be silently ignored.</p> - -<h3 id="charts-and-versioning">Charts and Versioning</h3> - -<p>Every chart must have a version number. A version must follow the -<a href="http://semver.org/">SemVer 2</a> standard. Unlike Helm Classic, Kubernetes -Helm uses version numbers as release markers. Packages in repositories -are identified by name plus version.</p> - -<p>For example, an <code>nginx</code> chart whose version field is set to <code>version: -1.2.3</code> will be named:</p> - -<pre><code>nginx-1.2.3.tgz -</code></pre> - -<p>More complex SemVer 2 names are also supported, such as -<code>version: 1.2.3-alpha.1+ef365</code>. But non-SemVer names are explicitly -disallowed by the system.</p> - -<p><strong>NOTE:</strong> Whereas Helm Classic and Deployment Manager were both -very GitHub oriented when it came to charts, Kubernetes Helm does not -rely upon or require GitHub or even Git. Consequently, it does not use -Git SHAs for versioning at all.</p> - -<p>The <code>version</code> field inside of the <code>Chart.yaml</code> is used by many of the -Helm tools, including the CLI and the Tiller server. When generating a -package, the <code>helm package</code> command will use the version that it finds -in the <code>Chart.yaml</code> as a token in the package name. The system assumes -that the version number in the chart package name matches the version number in -the <code>Chart.yaml</code>. Failure to meet this assumption will cause an error.</p> - -<h3 id="the-appversion-field">The appVersion field</h3> - -<p>Note that the <code>appVersion</code> field is not related to the <code>version</code> field. It is -a way of specifying the version of the application. For example, the <code>drupal</code> -chart may have an <code>appVersion: 8.2.1</code>, indicating that the version of Drupal -included in the chart (by default) is <code>8.2.1</code>. This field is informational, and -has no impact on chart version calculations.</p> - -<h3 id="deprecating-charts">Deprecating Charts</h3> - -<p>When managing charts in a Chart Repository, it is sometimes necessary to -deprecate a chart. The optional <code>deprecated</code> field in <code>Chart.yaml</code> can be used -to mark a chart as deprecated. If the <strong>latest</strong> version of a chart in the -repository is marked as deprecated, then the chart as a whole is considered to -be deprecated. The chart name can later be reused by publishing a newer version -that is not marked as deprecated. The workflow for deprecating charts, as -followed by the <a href="https://github.com/kubernetes/charts">kubernetes/charts</a> -project is: - - Update chart&rsquo;s <code>Chart.yaml</code> to mark the chart as deprecated, bumping the - version - - Release the new chart version in the Chart Repository - - Remove the chart from the source repository (e.g. git)</p> - -<h2 id="chart-license-readme-and-notes">Chart LICENSE, README and NOTES</h2> - -<p>Charts can also contain files that describe the installation, configuration, usage and license of a -chart. A README for a chart should be formatted in Markdown (README.md), and should generally -contain:</p> - -<ul> -<li>A description of the application or service the chart provides</li> -<li>Any prerequisites or requirements to run the chart</li> -<li>Descriptions of options in <code>values.yaml</code> and default values</li> -<li>Any other information that may be relevant to the installation or configuration of the chart</li> -</ul> - -<p>The chart can also contain a short plain text <code>templates/NOTES.txt</code> file that will be printed out -after installation, and when viewing the status of a release. This file is evaluated as a -<a href="#templates-and-values">template</a>, and can be used to display usage notes, next steps, or any other -information relevant to a release of the chart. For example, instructions could be provided for -connecting to a database, or accessing a web UI. Since this file is printed to STDOUT when running -<code>helm install</code> or <code>helm status</code>, it is recommended to keep the content brief and point to the README -for greater detail.</p> - -<h2 id="chart-dependencies">Chart Dependencies</h2> - -<p>In Helm, one chart may depend on any number of other charts. -These dependencies can be dynamically linked through the <code>requirements.yaml</code> -file or brought in to the <code>charts/</code> directory and managed manually.</p> - -<p>Although manually managing your dependencies has a few advantages some teams need, -the preferred method of declaring dependencies is by using a -<code>requirements.yaml</code> file inside of your chart.</p> - -<p><strong>Note:</strong> The <code>dependencies:</code> section of the <code>Chart.yaml</code> from Helm -Classic has been completely removed.</p> - -<h3 id="managing-dependencies-with-requirements-yaml">Managing Dependencies with <code>requirements.yaml</code></h3> - -<p>A <code>requirements.yaml</code> file is a simple file for listing your -dependencies.</p> - -<pre><code class="language-yaml">dependencies: - - name: apache - version: 1.2.3 - repository: http://example.com/charts - - name: mysql - version: 3.2.1 - repository: http://another.example.com/charts -</code></pre> - -<ul> -<li>The <code>name</code> field is the name of the chart you want.</li> -<li>The <code>version</code> field is the version of the chart you want.</li> -<li>The <code>repository</code> field is the full URL to the chart repository. Note -that you must also use <code>helm repo add</code> to add that repo locally.</li> -</ul> - -<p>Once you have a dependencies file, you can run <code>helm dependency update</code> -and it will use your dependency file to download all the specified -charts into your <code>charts/</code> directory for you.</p> - -<pre><code class="language-console">$ helm dep up foochart -Hang tight while we grab the latest from your chart repositories... -...Successfully got an update from the &quot;local&quot; chart repository -...Successfully got an update from the &quot;stable&quot; chart repository -...Successfully got an update from the &quot;example&quot; chart repository -...Successfully got an update from the &quot;another&quot; chart repository -Update Complete. Happy Helming! -Saving 2 charts -Downloading apache from repo http://example.com/charts -Downloading mysql from repo http://another.example.com/charts -</code></pre> - -<p>When <code>helm dependency update</code> retrieves charts, it will store them as -chart archives in the <code>charts/</code> directory. So for the example above, one -would expect to see the following files in the charts directory:</p> - -<pre><code>charts/ - apache-1.2.3.tgz - mysql-3.2.1.tgz -</code></pre> - -<p>Managing charts with <code>requirements.yaml</code> is a good way to easily keep -charts updated, and also share requirements information throughout a -team.</p> - -<h4 id="alias-field-in-requirements-yaml">Alias field in requirements.yaml</h4> - -<p>In addition to the other fields above, each requirements entry may contain -the optional field <code>alias</code>.</p> - -<p>Adding an alias for a dependency chart would put -a chart in dependencies using alias as name of new dependency.</p> - -<p>One can use <code>alias</code> in cases where they need to access a chart -with other name(s).</p> - -<pre><code class="language-yaml"># parentchart/requirements.yaml -dependencies: - - name: subchart - repository: http://localhost:10191 - version: 0.1.0 - alias: new-subchart-1 - - name: subchart - repository: http://localhost:10191 - version: 0.1.0 - alias: new-subchart-2 - - name: subchart - repository: http://localhost:10191 - version: 0.1.0 -</code></pre> - -<p>In the above example we will get 3 dependencies in all for <code>parentchart</code></p> - -<pre><code>subchart -new-subchart-1 -new-subchart-2 -</code></pre> - -<p>The manual way of achieving this is by copy/pasting the same chart in the -<code>charts/</code> directory multiple times with different names.</p> - -<h4 id="tags-and-condition-fields-in-requirements-yaml">Tags and Condition fields in requirements.yaml</h4> - -<p>In addition to the other fields above, each requirements entry may contain -the optional fields <code>tags</code> and <code>condition</code>.</p> - -<p>All charts are loaded by default. If <code>tags</code> or <code>condition</code> fields are present, -they will be evaluated and used to control loading for the chart(s) they are applied to.</p> - -<p>Condition - The condition field holds one or more YAML paths (delimited by commas). -If this path exists in the top parent&rsquo;s values and resolves to a boolean value, -the chart will be enabled or disabled based on that boolean value. Only the first -valid path found in the list is evaluated and if no paths exist then the condition has no effect.</p> - -<p>Tags - The tags field is a YAML list of labels to associate with this chart. -In the top parent&rsquo;s values, all charts with tags can be enabled or disabled by -specifying the tag and a boolean value.</p> - -<pre><code># parentchart/requirements.yaml -dependencies: - - name: subchart1 - repository: http://localhost:10191 - version: 0.1.0 - condition: subchart1.enabled, global.subchart1.enabled - tags: - - front-end - - subchart1 - - - name: subchart2 - repository: http://localhost:10191 - version: 0.1.0 - condition: subchart2.enabled,global.subchart2.enabled - tags: - - back-end - - subchart2 - -</code></pre> - -<pre><code># parentchart/values.yaml - -subchart1: - enabled: true -tags: - front-end: false - back-end: true -</code></pre> - -<p>In the above example all charts with the tag <code>front-end</code> would be disabled but since the -<code>subchart1.enabled</code> path evaluates to &lsquo;true&rsquo; in the parent&rsquo;s values, the condition will override the -<code>front-end</code> tag and <code>subchart1</code> will be enabled.</p> - -<p>Since <code>subchart2</code> is tagged with <code>back-end</code> and that tag evaluates to <code>true</code>, <code>subchart2</code> will be -enabled. Also notes that although <code>subchart2</code> has a condition specified in <code>requirements.yaml</code>, there -is no corresponding path and value in the parent&rsquo;s values so that condition has no effect.</p> - -<h5 id="using-the-cli-with-tags-and-conditions">Using the CLI with Tags and Conditions</h5> - -<p>The <code>--set</code> parameter can be used as usual to alter tag and condition values.</p> - -<pre><code>helm install --set tags.front-end=true --set subchart2.enabled=false - -</code></pre> - -<h5 id="tags-and-condition-resolution">Tags and Condition Resolution</h5> - -<ul> -<li><strong>Conditions (when set in values) always override tags.</strong> The first condition -path that exists wins and subsequent ones for that chart are ignored.</li> -<li>Tags are evaluated as &lsquo;if any of the chart&rsquo;s tags are true then enable the chart&rsquo;.</li> -<li>Tags and conditions values must be set in the top parent&rsquo;s values.</li> -<li>The <code>tags:</code> key in values must be a top level key. Globals and nested <code>tags:</code> tables -are not currently supported.</li> -</ul> - -<h4 id="importing-child-values-via-requirements-yaml">Importing Child Values via requirements.yaml</h4> - -<p>In some cases it is desirable to allow a child chart&rsquo;s values to propagate to the parent chart and be -shared as common defaults. An additional benefit of using the <code>exports</code> format is that it will enable future -tooling to introspect user-settable values.</p> - -<p>The keys containing the values to be imported can be specified in the parent chart&rsquo;s <code>requirements.yaml</code> file -using a YAML list. Each item in the list is a key which is imported from the child chart&rsquo;s <code>exports</code> field.</p> - -<p>To import values not contained in the <code>exports</code> key, use the <a href="#using-the-child-parent-format">child-parent</a> format. -Examples of both formats are described below.</p> - -<h5 id="using-the-exports-format">Using the exports format</h5> - -<p>If a child chart&rsquo;s <code>values.yaml</code> file contains an <code>exports</code> field at the root, its contents may be imported -directly into the parent&rsquo;s values by specifying the keys to import as in the example below:</p> - -<pre><code class="language-yaml"># parent's requirements.yaml file - ... - import-values: - - data -</code></pre> - -<pre><code class="language-yaml"># child's values.yaml file -... -exports: - data: - myint: 99 -</code></pre> - -<p>Since we are specifying the key <code>data</code> in our import list, Helm looks in the <code>exports</code> field of the child -chart for <code>data</code> key and imports its contents.</p> - -<p>The final parent values would contain our exported field:</p> - -<pre><code class="language-yaml"># parent's values file -... -myint: 99 - -</code></pre> - -<p>Please note the parent key <code>data</code> is not contained in the parent&rsquo;s final values. If you need to specify the -parent key, use the &lsquo;child-parent&rsquo; format.</p> - -<h5 id="using-the-child-parent-format">Using the child-parent format</h5> - -<p>To access values that are not contained in the <code>exports</code> key of the child chart&rsquo;s values, you will need to -specify the source key of the values to be imported (<code>child</code>) and the destination path in the parent chart&rsquo;s -values (<code>parent</code>).</p> - -<p>The <code>import-values</code> in the example below instructs Helm to take any values found at <code>child:</code> path and copy them -to the parent&rsquo;s values at the path specified in <code>parent:</code></p> - -<pre><code class="language-yaml"># parent's requirements.yaml file -dependencies: - - name: subchart1 - repository: http://localhost:10191 - version: 0.1.0 - ... - import-values: - - child: default.data - parent: myimports -</code></pre> - -<p>In the above example, values found at <code>default.data</code> in the subchart1&rsquo;s values will be imported -to the <code>myimports</code> key in the parent chart&rsquo;s values as detailed below:</p> - -<pre><code class="language-yaml"># parent's values.yaml file - -myimports: - myint: 0 - mybool: false - mystring: &quot;helm rocks!&quot; - -</code></pre> - -<pre><code class="language-yaml"># subchart1's values.yaml file - -default: - data: - myint: 999 - mybool: true - -</code></pre> - -<p>The parent chart&rsquo;s resulting values would be:</p> - -<pre><code class="language-yaml"># parent's final values - -myimports: - myint: 999 - mybool: true - mystring: &quot;helm rocks!&quot; - -</code></pre> - -<p>The parent&rsquo;s final values now contains the <code>myint</code> and <code>mybool</code> fields imported from subchart1.</p> - -<h3 id="managing-dependencies-manually-via-the-charts-directory">Managing Dependencies manually via the <code>charts/</code> directory</h3> - -<p>If more control over dependencies is desired, these dependencies can -be expressed explicitly by copying the dependency charts into the -<code>charts/</code> directory.</p> - -<p>A dependency can be either a chart archive (<code>foo-1.2.3.tgz</code>) or an -unpacked chart directory. But its name cannot start with <code>_</code> or <code>.</code>. -Such files are ignored by the chart loader.</p> - -<p>For example, if the WordPress chart depends on the Apache chart, the -Apache chart (of the correct version) is supplied in the WordPress -chart&rsquo;s <code>charts/</code> directory:</p> - -<pre><code>wordpress: - Chart.yaml - requirements.yaml - # ... - charts/ - apache/ - Chart.yaml - # ... - mysql/ - Chart.yaml - # ... -</code></pre> - -<p>The example above shows how the WordPress chart expresses its dependency -on Apache and MySQL by including those charts inside of its <code>charts/</code> -directory.</p> - -<p><strong>TIP:</strong> <em>To drop a dependency into your <code>charts/</code> directory, use the -<code>helm fetch</code> command</em></p> - -<h3 id="operational-aspects-of-using-dependencies">Operational aspects of using dependencies</h3> - -<p>The above sections explain how to specify chart dependencies, but how does this affect -chart installation using <code>helm install</code> and <code>helm upgrade</code>?</p> - -<p>Suppose that a chart named &ldquo;A&rdquo; creates the following Kubernetes objects</p> - -<ul> -<li>namespace &ldquo;A-Namespace&rdquo;</li> -<li>statefulset &ldquo;A-StatefulSet&rdquo;</li> -<li>service &ldquo;A-Service&rdquo;</li> -</ul> - -<p>Furthermore, A is dependent on chart B that creates objects</p> - -<ul> -<li>namespace &ldquo;B-Namespace&rdquo;</li> -<li>replicaset &ldquo;B-ReplicaSet&rdquo;</li> -<li>service &ldquo;B-Service&rdquo;</li> -</ul> - -<p>After installation/upgrade of chart A a single Helm release is created/modified. The release will -create/update all of the above Kubernetes objects in the following order:</p> - -<ul> -<li>A-Namespace</li> -<li>B-Namespace</li> -<li>A-StatefulSet</li> -<li>B-ReplicaSet</li> -<li>A-Service</li> -<li>B-Service</li> -</ul> - -<p>This is because when Helm installs/upgrades charts, -the Kubernetes objects from the charts and all its dependencies are</p> - -<ul> -<li>aggregrated into a single set; then</li> -<li>sorted by type followed by name; and then</li> -<li>created/updated in that order.</li> -</ul> - -<p>Hence a single release is created with all the objects for the chart and its dependencies.</p> - -<p>The install order of Kubernetes types is given by the enumeration InstallOrder in kind_sorter.go -(see <a href="https://github.com/kubernetes/helm/blob/master/pkg/tiller/kind_sorter.go#L26">the Helm source file</a>).</p> - -<h2 id="templates-and-values">Templates and Values</h2> - -<p>Helm Chart templates are written in the -<a href="https://golang.org/pkg/text/template/">Go template language</a>, with the -addition of 50 or so add-on template -functions <a href="https://github.com/Masterminds/sprig">from the Sprig library</a> and a -few other <a href="./#chart-development-tips-and-tricks">specialized functions</a>.</p> - -<p>All template files are stored in a chart&rsquo;s <code>templates/</code> folder. When -Helm renders the charts, it will pass every file in that directory -through the template engine.</p> - -<p>Values for the templates are supplied two ways:</p> - -<ul> -<li>Chart developers may supply a file called <code>values.yaml</code> inside of a -chart. This file can contain default values.</li> -<li>Chart users may supply a YAML file that contains values. This can be -provided on the command line with <code>helm install</code>.</li> -</ul> - -<p>When a user supplies custom values, these values will override the -values in the chart&rsquo;s <code>values.yaml</code> file.</p> - -<h3 id="template-files">Template Files</h3> - -<p>Template files follow the standard conventions for writing Go templates -(see <a href="https://golang.org/pkg/text/template/">the text/template Go package documentation</a> -for details). -An example template file might look something like this:</p> - -<pre><code class="language-yaml">apiVersion: v1 -kind: ReplicationController -metadata: - name: deis-database - namespace: deis - labels: - heritage: deis -spec: - replicas: 1 - selector: - app: deis-database - template: - metadata: - labels: - app: deis-database - spec: - serviceAccount: deis-database - containers: - - name: deis-database - image: {{.Values.imageRegistry}}/postgres:{{.Values.dockerTag}} - imagePullPolicy: {{.Values.pullPolicy}} - ports: - - containerPort: 5432 - env: - - name: DATABASE_STORAGE - value: {{default &quot;minio&quot; .Values.storage}} -</code></pre> - -<p>The above example, based loosely on <a href="https://github.com/deis/charts">https://github.com/deis/charts</a>, is a template for a Kubernetes replication controller. -It can use the following four template values (usually defined in a -<code>values.yaml</code> file):</p> - -<ul> -<li><code>imageRegistry</code>: The source registry for the Docker image.</li> -<li><code>dockerTag</code>: The tag for the docker image.</li> -<li><code>pullPolicy</code>: The Kubernetes pull policy.</li> -<li><code>storage</code>: The storage backend, whose default is set to <code>&quot;minio&quot;</code></li> -</ul> - -<p>All of these values are defined by the template author. Helm does not -require or dictate parameters.</p> - -<p>To see many working charts, check out the <a href="https://github.com/kubernetes/charts">Kubernetes Charts -project</a></p> - -<h3 id="predefined-values">Predefined Values</h3> - -<p>Values that are supplied via a <code>values.yaml</code> file (or via the <code>--set</code> -flag) are accessible from the <code>.Values</code> object in a template. But there -are other pre-defined pieces of data you can access in your templates.</p> - -<p>The following values are pre-defined, are available to every template, and -cannot be overridden. As with all values, the names are <em>case -sensitive</em>.</p> - -<ul> -<li><code>Release.Name</code>: The name of the release (not the chart)</li> -<li><code>Release.Time</code>: The time the chart release was last updated. This will -match the <code>Last Released</code> time on a Release object.</li> -<li><code>Release.Namespace</code>: The namespace the chart was released to.</li> -<li><code>Release.Service</code>: The service that conducted the release. Usually -this is <code>Tiller</code>.</li> -<li><code>Release.IsUpgrade</code>: This is set to true if the current operation is an upgrade or rollback.</li> -<li><code>Release.IsInstall</code>: This is set to true if the current operation is an -install.</li> -<li><code>Release.Revision</code>: The revision number. It begins at 1, and increments with -each <code>helm upgrade</code>.</li> -<li><code>Chart</code>: The contents of the <code>Chart.yaml</code>. Thus, the chart version is -obtainable as <code>Chart.Version</code> and the maintainers are in -<code>Chart.Maintainers</code>.</li> -<li><code>Files</code>: A map-like object containing all non-special files in the chart. This -will not give you access to templates, but will give you access to additional -files that are present (unless they are excluded using <code>.helmignore</code>). Files can be -accessed using <code>{{index .Files &quot;file.name&quot;}}</code> or using the <code>{{.Files.Get name}}</code> or -<code>{{.Files.GetString name}}</code> functions. You can also access the contents of the file -as <code>[]byte</code> using <code>{{.Files.GetBytes}}</code></li> -<li><code>Capabilities</code>: A map-like object that contains information about the versions -of Kubernetes (<code>{{.Capabilities.KubeVersion}}</code>, Tiller -(<code>{{.Capabilities.TillerVersion}}</code>, and the supported Kubernetes API versions -(<code>{{.Capabilities.APIVersions.Has &quot;batch/v1&quot;</code>)</li> -</ul> - -<p><strong>NOTE:</strong> Any unknown Chart.yaml fields will be dropped. They will not -be accessible inside of the <code>Chart</code> object. Thus, Chart.yaml cannot be -used to pass arbitrarily structured data into the template. The values -file can be used for that, though.</p> - -<h3 id="values-files">Values files</h3> - -<p>Considering the template in the previous section, a <code>values.yaml</code> file -that supplies the necessary values would look like this:</p> - -<pre><code class="language-yaml">imageRegistry: &quot;quay.io/deis&quot; -dockerTag: &quot;latest&quot; -pullPolicy: &quot;Always&quot; -storage: &quot;s3&quot; -</code></pre> - -<p>A values file is formatted in YAML. A chart may include a default -<code>values.yaml</code> file. The Helm install command allows a user to override -values by supplying additional YAML values:</p> - -<pre><code class="language-console">$ helm install --values=myvals.yaml wordpress -</code></pre> - -<p>When values are passed in this way, they will be merged into the default -values file. For example, consider a <code>myvals.yaml</code> file that looks like -this:</p> - -<pre><code class="language-yaml">storage: &quot;gcs&quot; -</code></pre> - -<p>When this is merged with the <code>values.yaml</code> in the chart, the resulting -generated content will be:</p> - -<pre><code class="language-yaml">imageRegistry: &quot;quay.io/deis&quot; -dockerTag: &quot;latest&quot; -pullPolicy: &quot;Always&quot; -storage: &quot;gcs&quot; -</code></pre> - -<p>Note that only the last field was overridden.</p> - -<p><strong>NOTE:</strong> The default values file included inside of a chart <em>must</em> be named -<code>values.yaml</code>. But files specified on the command line can be named -anything.</p> - -<p><strong>NOTE:</strong> If the <code>--set</code> flag is used on <code>helm install</code> or <code>helm upgrade</code>, those -values are simply converted to YAML on the client side.</p> - -<p><strong>NOTE:</strong> If any required entries in the values file exist, they can be declared -as required in the chart template by using the <a href="./#chart-development-tips-and-tricks">&lsquo;required&rsquo; function</a></p> - -<p>Any of these values are then accessible inside of templates using the -<code>.Values</code> object:</p> - -<pre><code class="language-yaml">apiVersion: v1 -kind: ReplicationController -metadata: - name: deis-database - namespace: deis - labels: - heritage: deis -spec: - replicas: 1 - selector: - app: deis-database - template: - metadata: - labels: - app: deis-database - spec: - serviceAccount: deis-database - containers: - - name: deis-database - image: {{.Values.imageRegistry}}/postgres:{{.Values.dockerTag}} - imagePullPolicy: {{.Values.pullPolicy}} - ports: - - containerPort: 5432 - env: - - name: DATABASE_STORAGE - value: {{default &quot;minio&quot; .Values.storage}} - -</code></pre> - -<h3 id="scope-dependencies-and-values">Scope, Dependencies, and Values</h3> - -<p>Values files can declare values for the top-level chart, as well as for -any of the charts that are included in that chart&rsquo;s <code>charts/</code> directory. -Or, to phrase it differently, a values file can supply values to the -chart as well as to any of its dependencies. For example, the -demonstration WordPress chart above has both <code>mysql</code> and <code>apache</code> as -dependencies. The values file could supply values to all of these -components:</p> - -<pre><code class="language-yaml">title: &quot;My WordPress Site&quot; # Sent to the WordPress template - -mysql: - max_connections: 100 # Sent to MySQL - password: &quot;secret&quot; - -apache: - port: 8080 # Passed to Apache -</code></pre> - -<p>Charts at a higher level have access to all of the variables defined -beneath. So the WordPress chart can access the MySQL password as -<code>.Values.mysql.password</code>. But lower level charts cannot access things in -parent charts, so MySQL will not be able to access the <code>title</code> property. Nor, -for that matter, can it access <code>apache.port</code>.</p> - -<p>Values are namespaced, but namespaces are pruned. So for the WordPress -chart, it can access the MySQL password field as <code>.Values.mysql.password</code>. But -for the MySQL chart, the scope of the values has been reduced and the -namespace prefix removed, so it will see the password field simply as -<code>.Values.password</code>.</p> - -<h4 id="global-values">Global Values</h4> - -<p>As of 2.0.0-Alpha.2, Helm supports special &ldquo;global&rdquo; value. Consider -this modified version of the previous example:</p> - -<pre><code class="language-yaml">title: &quot;My WordPress Site&quot; # Sent to the WordPress template - -global: - app: MyWordPress - -mysql: - max_connections: 100 # Sent to MySQL - password: &quot;secret&quot; - -apache: - port: 8080 # Passed to Apache -</code></pre> - -<p>The above adds a <code>global</code> section with the value <code>app: MyWordPress</code>. -This value is available to <em>all</em> charts as <code>.Values.global.app</code>.</p> - -<p>For example, the <code>mysql</code> templates may access <code>app</code> as <code>{{.Values.global.app}}</code>, and -so can the <code>apache</code> chart. Effectively, the values file above is -regenerated like this:</p> - -<pre><code class="language-yaml">title: &quot;My WordPress Site&quot; # Sent to the WordPress template - -global: - app: MyWordPress - -mysql: - global: - app: MyWordPress - max_connections: 100 # Sent to MySQL - password: &quot;secret&quot; - -apache: - global: - app: MyWordPress - port: 8080 # Passed to Apache -</code></pre> - -<p>This provides a way of sharing one top-level variable with all -subcharts, which is useful for things like setting <code>metadata</code> properties -like labels.</p> - -<p>If a subchart declares a global variable, that global will be passed -<em>downward</em> (to the subchart&rsquo;s subcharts), but not <em>upward</em> to the parent -chart. There is no way for a subchart to influence the values of the -parent chart.</p> - -<p>Also, global variables of parent charts take precedence over the global variables from subcharts.</p> - -<h3 id="references">References</h3> - -<p>When it comes to writing templates and values files, there are several -standard references that will help you out.</p> - -<ul> -<li><a href="https://godoc.org/text/template">Go templates</a></li> -<li><a href="https://godoc.org/github.com/Masterminds/sprig">Extra template functions</a></li> -<li><a href="http://yaml.org/spec/">The YAML format</a></li> -</ul> - -<h2 id="using-helm-to-manage-charts">Using Helm to Manage Charts</h2> - -<p>The <code>helm</code> tool has several commands for working with charts.</p> - -<p>It can create a new chart for you:</p> - -<pre><code class="language-console">$ helm create mychart -Created mychart/ -</code></pre> - -<p>Once you have edited a chart, <code>helm</code> can package it into a chart archive -for you:</p> - -<pre><code class="language-console">$ helm package mychart -Archived mychart-0.1.-.tgz -</code></pre> - -<p>You can also use <code>helm</code> to help you find issues with your chart&rsquo;s -formatting or information:</p> - -<pre><code class="language-console">$ helm lint mychart -No issues found -</code></pre> - -<h2 id="chart-repositories">Chart Repositories</h2> - -<p>A <em>chart repository</em> is an HTTP server that houses one or more packaged -charts. While <code>helm</code> can be used to manage local chart directories, when -it comes to sharing charts, the preferred mechanism is a chart -repository.</p> - -<p>Any HTTP server that can serve YAML files and tar files and can answer -GET requests can be used as a repository server.</p> - -<p>Helm comes with built-in package server for developer testing (<code>helm -serve</code>). The Helm team has tested other servers, including Google Cloud -Storage with website mode enabled, and S3 with website mode enabled.</p> - -<p>A repository is characterized primarily by the presence of a special -file called <code>index.yaml</code> that has a list of all of the packages supplied -by the repository, together with metadata that allows retrieving and -verifying those packages.</p> - -<p>On the client side, repositories are managed with the <code>helm repo</code> -commands. However, Helm does not provide tools for uploading charts to -remote repository servers. This is because doing so would add -substantial requirements to an implementing server, and thus raise the -barrier for setting up a repository.</p> - -<h2 id="chart-starter-packs">Chart Starter Packs</h2> - -<p>The <code>helm create</code> command takes an optional <code>--starter</code> option that lets you -specify a &ldquo;starter chart&rdquo;.</p> - -<p>Starters are just regular charts, but are located in <code>$HELM_HOME/starters</code>. -As a chart developer, you may author charts that are specifically designed -to be used as starters. Such charts should be designed with the following -considerations in mind:</p> - -<ul> -<li>The <code>Chart.yaml</code> will be overwritten by the generator.</li> -<li>Users will expect to modify such a chart&rsquo;s contents, so documentation -should indicate how users can do so.</li> -<li>All occurances of <code>&lt;CHARTNAME&gt;</code> will be replaced with the specified chart -name so that starter charts can be used as templates.</li> -</ul> - -<p>Currently the only way to add a chart to <code>$HELM_HOME/starters</code> is to manually -copy it there. In your chart&rsquo;s documentation, you may want to explain that -process.</p> - -<h1 id="hooks">Hooks</h1> - -<p>Helm provides a <em>hook</em> mechanism to allow chart developers to intervene -at certain points in a release&rsquo;s life cycle. For example, you can use -hooks to:</p> - -<ul> -<li>Load a ConfigMap or Secret during install before any other charts are -loaded.</li> -<li>Execute a Job to back up a database before installing a new chart, -and then execute a second job after the upgrade in order to restore -data.</li> -<li>Run a Job before deleting a release to gracefully take a service out -of rotation before removing it.</li> -</ul> - -<p>Hooks work like regular templates, but they have special annotations -that cause Helm to utilize them differently. In this section, we cover -the basic usage pattern for hooks.</p> - -<h2 id="the-available-hooks">The Available Hooks</h2> - -<p>The following hooks are defined:</p> - -<ul> -<li>pre-install: Executes after templates are rendered, but before any -resources are created in Kubernetes.</li> -<li>post-install: Executes after all resources are loaded into Kubernetes</li> -<li>pre-delete: Executes on a deletion request before any resources are -deleted from Kubernetes.</li> -<li>post-delete: Executes on a deletion request after all of the release&rsquo;s -resources have been deleted.</li> -<li>pre-upgrade: Executes on an upgrade request after templates are -rendered, but before any resources are loaded into Kubernetes (e.g. -before a Kubernetes apply operation).</li> -<li>post-upgrade: Executes on an upgrade after all resources have been -upgraded.</li> -<li>pre-rollback: Executes on a rollback request after templates are -rendered, but before any resources have been rolled back.</li> -<li>post-rollback: Executes on a rollback request after all resources -have been modified.</li> -</ul> - -<h2 id="hooks-and-the-release-lifecycle">Hooks and the Release Lifecycle</h2> - -<p>Hooks allow you, the chart developer, an opportunity to perform -operations at strategic points in a release lifecycle. For example, -consider the lifecycle for a <code>helm install</code>. By default, the lifecycle -looks like this:</p> - -<ol> -<li>User runs <code>helm install foo</code></li> -<li>Chart is loaded into Tiller</li> -<li>After some verification, Tiller renders the <code>foo</code> templates</li> -<li>Tiller loads the resulting resources into Kubernetes</li> -<li>Tiller returns the release name (and other data) to the client</li> -<li>The client exits</li> -</ol> - -<p>Helm defines two hooks for the <code>install</code> lifecycle: <code>pre-install</code> and -<code>post-install</code>. If the developer of the <code>foo</code> chart implements both -hooks, the lifecycle is altered like this:</p> - -<ol> -<li>User runs <code>helm install foo</code></li> -<li>Chart is loaded into Tiller</li> -<li>After some verification, Tiller renders the <code>foo</code> templates</li> -<li>Tiller prepares to execute the <code>pre-install</code> hooks (loading hook resources into -Kubernetes)</li> -<li>Tiller sorts hooks by weight (assigning a weight of 0 by default) and by name for those hooks with the same weight in ascending order.</li> -<li>Tiller then loads the hook with the lowest weight first (negative to positive)</li> -<li>Tiller waits until the hook is &ldquo;Ready&rdquo;</li> -<li>Tiller loads the resulting resources into Kubernetes. Note that if the <code>--wait</code> -flag is set, Tiller will wait until all resources are in a ready state -and will not run the <code>post-install</code> hook until they are ready.</li> -<li>Tiller executes the <code>post-install</code> hook (loading hook resources)</li> -<li>Tiller waits until the hook is &ldquo;Ready&rdquo;</li> -<li>Tiller returns the release name (and other data) to the client</li> -<li>The client exits</li> -</ol> - -<p>What does it mean to wait until a hook is ready? This depends on the -resource declared in the hook. If the resources is a <code>Job</code> kind, Tiller -will wait until the job successfully runs to completion. And if the job -fails, the release will fail. This is a <em>blocking operation</em>, so the -Helm client will pause while the Job is run.</p> - -<p>For all other kinds, as soon as Kubernetes marks the resource as loaded -(added or updated), the resource is considered &ldquo;Ready&rdquo;. When many -resources are declared in a hook, the resources are executed serially. If they -have hook weights (see below), they are executed in weighted order. Otherwise, -ordering is not guaranteed. (In Helm 2.3.0 and after, they are sorted -alphabetically. That behavior, though, is not considered binding and could change -in the future.) It is considered good practice to add a hook weight, and set it -to <code>0</code> if weight is not important.</p> - -<h3 id="hook-resources-are-not-managed-with-corresponding-releases">Hook resources are not managed with corresponding releases</h3> - -<p>The resources that a hook creates are not tracked or managed as part of the -release. Once Tiller verifies that the hook has reached its ready state, it -will leave the hook resource alone.</p> - -<p>Practically speaking, this means that if you create resources in a hook, you -cannot rely upon <code>helm delete</code> to remove the resources. To destroy such -resources, you need to either write code to perform this operation in a <code>pre-delete</code> -or <code>post-delete</code> hook or add <code>&quot;helm.sh/hook-delete-policy&quot;</code> annotation to the hook template file.</p> - -<h2 id="writing-a-hook">Writing a Hook</h2> - -<p>Hooks are just Kubernetes manifest files with special annotations in the -<code>metadata</code> section. Because they are template files, you can use all of -the normal template features, including reading <code>.Values</code>, <code>.Release</code>, -and <code>.Template</code>.</p> - -<p>For example, this template, stored in <code>templates/post-install-job.yaml</code>, -declares a job to be run on <code>post-install</code>:</p> - -<pre><code class="language-yaml">apiVersion: batch/v1 -kind: Job -metadata: - name: &quot;{{.Release.Name}}&quot; - labels: - heritage: {{.Release.Service | quote }} - release: {{.Release.Name | quote }} - chart: &quot;{{.Chart.Name}}-{{.Chart.Version}}&quot; - annotations: - # This is what defines this resource as a hook. Without this line, the - # job is considered part of the release. - &quot;helm.sh/hook&quot;: post-install - &quot;helm.sh/hook-weight&quot;: &quot;-5&quot; - &quot;helm.sh/hook-delete-policy&quot;: hook-succeeded -spec: - template: - metadata: - name: &quot;{{.Release.Name}}&quot; - labels: - heritage: {{.Release.Service | quote }} - release: {{.Release.Name | quote }} - chart: &quot;{{.Chart.Name}}-{{.Chart.Version}}&quot; - spec: - restartPolicy: Never - containers: - - name: post-install-job - image: &quot;alpine:3.3&quot; - command: [&quot;/bin/sleep&quot;,&quot;{{default &quot;10&quot; .Values.sleepyTime}}&quot;] - -</code></pre> - -<p>What makes this template a hook is the annotation:</p> - -<pre><code> annotations: - &quot;helm.sh/hook&quot;: post-install -</code></pre> - -<p>One resource can implement multiple hooks:</p> - -<pre><code> annotations: - &quot;helm.sh/hook&quot;: post-install,post-upgrade -</code></pre> - -<p>Similarly, there is no limit to the number of different resources that -may implement a given hook. For example, one could declare both a secret -and a config map as a pre-install hook.</p> - -<p>When subcharts declare hooks, those are also evaluated. There is no way -for a top-level chart to disable the hooks declared by subcharts.</p> - -<p>It is possible to define a weight for a hook which will help build a -deterministic executing order. Weights are defined using the following annotation:</p> - -<pre><code> annotations: - &quot;helm.sh/hook-weight&quot;: &quot;5&quot; -</code></pre> - -<p>Hook weights can be positive or negative numbers but must be represented as -strings. When Tiller starts the execution cycle of hooks of a particular Kind it -will sort those hooks in ascending order.</p> - -<p>It is also possible to define policies that determine when to delete corresponding hook resources. Hook deletion policies are defined using the following annotation:</p> - -<pre><code> annotations: - &quot;helm.sh/hook-delete-policy&quot;: hook-succeeded -</code></pre> - -<p>When using <code>&quot;helm.sh/hook-delete-policy&quot;</code> annotation, you can choose its value from <code>&quot;hook-succeeded&quot;</code> and <code>&quot;hook-failed&quot;</code>. The value <code>&quot;hook-succeeded&quot;</code> specifies Tiller should delete the hook after the hook is successfully executed, while the value <code>&quot;hook-failed&quot;</code>specifies Tiller should delete the hook if the hook failed during execution.</p> - -<h1 id="chart-development-tips-and-tricks">Chart Development Tips and Tricks</h1> - -<p>This guide covers some of the tips and tricks Helm chart developers have -learned while building production-quality charts.</p> - -<h2 id="know-your-template-functions">Know Your Template Functions</h2> - -<p>Helm uses <a href="https://godoc.org/text/template">Go templates</a> for templating -your resource files. While Go ships several built-in functions, we have -added many others.</p> - -<p>First, we added almost all of the functions in the -<a href="https://godoc.org/github.com/Masterminds/sprig">Sprig library</a>. We removed two -for security reasons: <code>env</code> and <code>expandenv</code> (which would have given chart authors -access to Tiller&rsquo;s environment).</p> - -<p>We also added two special template functions: <code>include</code> and <code>required</code>. The <code>include</code> -function allows you to bring in another template, and then pass the results to other -template functions.</p> - -<p>For example, this template snippet includes a template called <code>mytpl</code>, then -lowercases the result, then wraps that in double quotes.</p> - -<pre><code class="language-yaml">value: {{include &quot;mytpl&quot; . | lower | quote}} -</code></pre> - -<p>The <code>required</code> function allows you to declare a particular -values entry as required for template rendering. If the value is empty, the template -rendering will fail with a user submitted error message.</p> - -<p>The following example of the <code>required</code> function declares an entry for .Values.who -is required, and will print an error message when that entry is missing:</p> - -<pre><code class="language-yaml">value: {{required &quot;A valid .Values.who entry required!&quot; .Values.who }} -</code></pre> - -<h2 id="quote-strings-don-t-quote-integers">Quote Strings, Don&rsquo;t Quote Integers</h2> - -<p>When you are working with string data, you are always safer quoting the -strings than leaving them as bare words:</p> - -<pre><code>name: {{.Values.MyName | quote }} -</code></pre> - -<p>But when working with integers <em>do not quote the values.</em> That can, in -many cases, cause parsing errors inside of Kubernetes.</p> - -<pre><code>port: {{ .Values.Port }} -</code></pre> - -<p>This remark does not apply to env variables values which are expected to be string, even if they represent integers:</p> - -<pre><code>env: - -name: HOST - value: &quot;http://host&quot; - -name: PORT - value: &quot;1234&quot; -</code></pre> - -<h2 id="using-the-include-function">Using the &lsquo;include&rsquo; Function</h2> - -<p>Go provides a way of including one template in another using a built-in -<code>template</code> directive. However, the built-in function cannot be used in -Go template pipelines.</p> - -<p>To make it possible to include a template, and then perform an operation -on that template&rsquo;s output, Helm has a special <code>include</code> function:</p> - -<pre><code>{{ include &quot;toYaml&quot; $value | indent 2 }} -</code></pre> - -<p>The above includes a template called <code>toYaml</code>, passes it <code>$value</code>, and -then passes the output of that template to the <code>indent</code> function.</p> - -<p>Because YAML ascribes significance to indentation levels and whitespace, -this is one great way to include snippets of code, but handle -indentation in a relevant context.</p> - -<h2 id="using-the-required-function">Using the &lsquo;required&rsquo; function</h2> - -<p>Go provides a way for setting template options to control behavior -when a map is indexed with a key that&rsquo;s not present in the map. This -is typically set with template.Options(&ldquo;missingkey=option&rdquo;), where option -can be default, zero, or error. While setting this option to error will -stop execution with an error, this would apply to every missing key in the -map. There may be situations where a chart developer wants to enforce this -behavior for select values in the values.yml file.</p> - -<p>The <code>required</code> function gives developers the ability to declare a value entry -as required for template rendering. If the entry is empty in values.yml, the -template will not render and will return an error message supplied by the -developer.</p> - -<p>For example:</p> - -<pre><code>{{ required &quot;A valid foo is required!&quot; .Values.foo }} -</code></pre> - -<p>The above will render the template when .Values.foo is defined, but will fail -to render and exit when .Values.foo is undefined.</p> - -<h2 id="creating-image-pull-secrets">Creating Image Pull Secrets</h2> - -<p>Image pull secrets are essentially a combination of <em>registry</em>, <em>username</em>, and <em>password</em>. You may need them in an application you are deploying, but to create them requires running <em>base64</em> a couple of times. We can write a helper template to compose the Docker configuration file for use as the Secret&rsquo;s payload. Here is an example:</p> - -<p>First, assume that the credentials are defined in the <code>values.yaml</code> file like so:</p> - -<pre><code>imageCredentials: - registry: quay.io - username: someone - password: sillyness -</code></pre> - -<p>We then define our helper template as follows:</p> - -<pre><code>{{- define &quot;imagePullSecret&quot; }} -{{- printf &quot;{\&quot;auths\&quot;: {\&quot;%s\&quot;: {\&quot;auth\&quot;: \&quot;%s\&quot;}}}&quot; .Values.imageCredentials.registry (printf &quot;%s:%s&quot; .Values.imageCredentials.username .Values.imageCredentials.password | b64enc) | b64enc }} -{{- end }} -</code></pre> - -<p>Finally, we use the helper template in a larger template to create the Secret manifest:</p> - -<pre><code>apiVersion: v1 -kind: Secret -metadata: - name: myregistrykey -type: kubernetes.io/dockerconfigjson -data: - .dockerconfigjson: {{ template &quot;imagePullSecret&quot; . }} -</code></pre> - -<h2 id="automatically-roll-deployments-when-configmaps-or-secrets-change">Automatically Roll Deployments When ConfigMaps or Secrets change</h2> - -<p>Often times configmaps or secrets are injected as configuration -files in containers. -Depending on the application a restart may be required should those -be updated with a subsequent <code>helm upgrade</code>, but if the -deployment spec itself didn&rsquo;t change the application keeps running -with the old configuration resulting in an inconsistent deployment.</p> - -<p>The <code>sha256sum</code> function can be used to ensure a deployment&rsquo;s -annotation section is updated if another file changes:</p> - -<pre><code class="language-yaml">kind: Deployment -spec: - template: - metadata: - annotations: - checksum/config: {{ include (print $.Template.BasePath &quot;/configmap.yaml&quot;) . | sha256sum }} -[...] -</code></pre> - -<p>See also the <code>helm upgrade --recreate-pods</code> flag for a slightly -different way of addressing this issue.</p> - -<h2 id="tell-tiller-not-to-delete-a-resource">Tell Tiller Not To Delete a Resource</h2> - -<p>Sometimes there are resources that should not be deleted when Helm runs a -<code>helm delete</code>. Chart developers can add an annotation to a resource to prevent -it from being deleted.</p> - -<pre><code class="language-yaml">kind: Secret -metadata: - annotations: - &quot;helm.sh/resource-policy&quot;: keep -[...] -</code></pre> - -<p>(Quotation marks are required)</p> - -<p>The annotation <code>&quot;helm.sh/resource-policy&quot;: keep</code> instructs Tiller to skip this -resource during a <code>helm delete</code> operation. <em>However</em>, this resource becomes -orphaned. Helm will no longer manage it in any way. This can lead to problems -if using <code>helm install --replace</code> on a release that has already been deleted, but -has kept resources.</p> - -<h2 id="using-partials-and-template-includes">Using &ldquo;Partials&rdquo; and Template Includes</h2> - -<p>Sometimes you want to create some reusable parts in your chart, whether -they&rsquo;re blocks or template partials. And often, it&rsquo;s cleaner to keep -these in their own files.</p> - -<p>In the <code>templates/</code> directory, any file that begins with an -underscore(<code>_</code>) is not expected to output a Kubernetes manifest file. So -by convention, helper templates and partials are placed in a -<code>_helpers.tpl</code> file.</p> - -<h2 id="complex-charts-with-many-dependencies">Complex Charts with Many Dependencies</h2> - -<p>Many of the charts in the <a href="https://github.com/kubernetes/charts">official charts repository</a> -are &ldquo;building blocks&rdquo; for creating more advanced applications. But charts may be -used to create instances of large-scale applications. In such cases, a single -umbrella chart may have multiple subcharts, each of which functions as a piece -of the whole.</p> - -<p>The current best practice for composing a complex application from discrete parts -is to create a top-level umbrella chart that -exposes the global configurations, and then use the <code>charts/</code> subdirectory to -embed each of the components.</p> - -<p>Two strong design patterns are illustrated by these projects:</p> - -<p><strong>SAP&rsquo;s <a href="https://github.com/sapcc/openstack-helm">OpenStack chart</a>:</strong> This chart -installs a full OpenStack IaaS on Kubernetes. All of the charts are collected -together in one GitHub repository.</p> - -<p><strong>Deis&rsquo;s <a href="https://github.com/deis/workflow/tree/master/charts/workflow">Workflow</a>:</strong> -This chart exposes the entire Deis PaaS system with one chart. But it&rsquo;s different -from the SAP chart in that this umbrella chart is built from each component, and -each component is tracked in a different Git repository. Check out the -<code>requirements.yaml</code> file to see how this chart is composed by their CI/CD -pipeline.</p> - -<p>Both of these charts illustrate proven techniques for standing up complex environments -using Helm.</p> - -<h2 id="yaml-is-a-superset-of-json">YAML is a Superset of JSON</h2> - -<p>According to the YAML specification, YAML is a superset of JSON. That -means that any valid JSON structure ought to be valid in YAML.</p> - -<p>This has an advantage: Sometimes template developers may find it easier -to express a datastructure with a JSON-like syntax rather than deal with -YAML&rsquo;s whitespace sensitivity.</p> - -<p>As a best practice, templates should follow a YAML-like syntax <em>unless</em> -the JSON syntax substantially reduces the risk of a formatting issue.</p> - -<h2 id="be-careful-with-generating-random-values">Be Careful with Generating Random Values</h2> - -<p>There are functions in Helm that allow you to generate random data, -cryptographic keys, and so on. These are fine to use. But be aware that -during upgrades, templates are re-executed. When a template run -generates data that differs from the last run, that will trigger an -update of that resource.</p> - -<h2 id="upgrade-a-release-idempotently">Upgrade a release idempotently</h2> - -<p>In order to use the same command when installing and upgrading a release, use the following command:</p> - -<pre><code class="language-shell">helm upgrade --install &lt;release name&gt; --values &lt;values file&gt; &lt;chart directory&gt; -</code></pre> - -<h1 id="the-chart-repository-guide">The Chart Repository Guide</h1> - -<p>This section explains how to create and work with Helm chart repositories. At a -high level, a chart repository is a location where packaged charts can be -stored and shared.</p> - -<p>The official chart repository is maintained by the -<a href="https://github.com/kubernetes/charts">Kubernetes Charts</a>, and we welcome -participation. But Helm also makes it easy to create and run your own chart -repository. This guide explains how to do so.</p> - -<h2 id="prerequisites">Prerequisites</h2> - -<ul> -<li>Go through the <a href="./#quickstart">Quickstart</a> Guide</li> -<li>Read through the <a href="./#charts">Charts</a> document</li> -</ul> - -<h2 id="create-a-chart-repository">Create a chart repository</h2> - -<p>A <em>chart repository</em> is an HTTP server that houses an <code>index.yaml</code> file and -optionally some packaged charts. When you&rsquo;re ready to share your charts, the -preferred way to do so is by uploading them to a chart repository.</p> - -<p><strong>Note:</strong> For Helm 2.0.0, chart repositories do not have any intrinsic -authentication. There is an <a href="https://github.com/kubernetes/helm/issues/1038">issue tracking progress</a> -in GitHub.</p> - -<p>Because a chart repository can be any HTTP server that can serve YAML and tar -files and can answer GET requests, you have a plethora of options when it comes -down to hosting your own chart repository. For example, you can use a Google -Cloud Storage (GCS) bucket, Amazon S3 bucket, Github Pages, or even create your -own web server.</p> - -<h3 id="the-chart-repository-structure">The chart repository structure</h3> - -<p>A chart repository consists of packaged charts and a special file called -<code>index.yaml</code> which contains an index of all of the charts in the repository. -Frequently, the charts that <code>index.yaml</code> describes are also hosted on the same -server, as are the <a href="./#helm-provenance-and-integrity">provenance files</a>.</p> - -<p>For example, the layout of the repository <code>https://example.com/charts</code> might -look like this:</p> - -<pre><code>charts/ - | - |- index.yaml - | - |- alpine-0.1.2.tgz - | - |- alpine-0.1.2.tgz.prov -</code></pre> - -<p>In this case, the index file would contain information about one chart, the Alpine -chart, and provide the download URL <code>https://example.com/charts/alpine-0.1.2.tgz</code> -for that chart.</p> - -<p>It is not required that a chart package be located on the same server as the -<code>index.yaml</code> file. However, doing so is often the easiest.</p> - -<h3 id="the-index-file">The index file</h3> - -<p>The index file is a yaml file called <code>index.yaml</code>. It -contains some metadata about the package, including the contents of a -chart&rsquo;s <code>Chart.yaml</code> file. A valid chart repository must have an index file. The -index file contains information about each chart in the chart repository. The -<code>helm repo index</code> command will generate an index file based on a given local -directory that contains packaged charts.</p> - -<p>This is an example of an index file:</p> - -<pre><code>apiVersion: v1 -entries: - alpine: - - created: 2016-10-06T16:23:20.499814565-06:00 - description: Deploy a basic Alpine Linux pod - digest: 99c76e403d752c84ead610644d4b1c2f2b453a74b921f422b9dcb8a7c8b559cd - home: https://k8s.io/helm - name: alpine - sources: - - https://github.com/kubernetes/helm - urls: - - https://technosophos.github.io/tscharts/alpine-0.2.0.tgz - version: 0.2.0 - - created: 2016-10-06T16:23:20.499543808-06:00 - description: Deploy a basic Alpine Linux pod - digest: 515c58e5f79d8b2913a10cb400ebb6fa9c77fe813287afbacf1a0b897cd78727 - home: https://k8s.io/helm - name: alpine - sources: - - https://github.com/kubernetes/helm - urls: - - https://technosophos.github.io/tscharts/alpine-0.1.0.tgz - version: 0.1.0 - nginx: - - created: 2016-10-06T16:23:20.499543808-06:00 - description: Create a basic nginx HTTP server - digest: aaff4545f79d8b2913a10cb400ebb6fa9c77fe813287afbacf1a0b897cdffffff - home: https://k8s.io/helm - name: nginx - sources: - - https://github.com/kubernetes/charts - urls: - - https://technosophos.github.io/tscharts/nginx-1.1.0.tgz - version: 1.1.0 -generated: 2016-10-06T16:23:20.499029981-06:00 -</code></pre> - -<p>A generated index and packages can be served from a basic webserver. You can test -things out locally with the <code>helm serve</code> command, which starts a local server.</p> - -<pre><code class="language-console">$ helm serve --repo-path ./charts -Regenerating index. This may take a moment. -Now serving you on 127.0.0.1:8879 -</code></pre> - -<p>The above starts a local webserver, serving the charts it finds in <code>./charts</code>. The -serve command will automatically generate an <code>index.yaml</code> file for you during -startup.</p> - -<h2 id="hosting-chart-repositories">Hosting Chart Repositories</h2> - -<p>This part shows several ways to serve a chart repository.</p> - -<h3 id="google-cloud-storage">Google Cloud Storage</h3> - -<p>The first step is to <strong>create your GCS bucket</strong>. We&rsquo;ll call ours -<code>fantastic-charts</code>.</p> - -<p><img src="https://raw.githubusercontent.com/kubernetes/helm/master/docs/images/create-a-bucket.png" alt="Create a GCS Bucket" /></p> - -<p>Next, make your bucket public by <strong>editing the bucket permissions</strong>.</p> - -<p><img src="https://raw.githubusercontent.com/kubernetes/helm/master/docs/images/edit-permissions.png" alt="Edit Permissions" /></p> - -<p>Insert this line item to <strong>make your bucket public</strong>:</p> - -<p><img src="https://raw.githubusercontent.com/kubernetes/helm/master/docs/images/make-bucket-public.png" alt="Make Bucket Public" /></p> - -<p>Congratulations, now you have an empty GCS bucket ready to serve charts!</p> - -<p>You may upload your chart repository using the Google Cloud Storage command line -tool, or using the GCS web UI. This is the technique the official Kubernetes -Charts repository hosts its charts, so you may want to take a -<a href="https://github.com/kubernetes/charts">peek at that project</a> if you get stuck.</p> - -<p><strong>Note:</strong> A public GCS bucket can be accessed via simple HTTPS at this address -<code>https://bucket-name.storage.googleapis.com/</code>.</p> - -<h3 id="github-pages-example">Github Pages example</h3> - -<p>In a similar way you can create charts repository using GitHub Pages.</p> - -<p>GitHub allows you to serve static web pages in two different ways:</p> - -<ul> -<li>By configuring a project to serve the contents of its <code>docs/</code> directory</li> -<li>By configuring a project to serve a particular branch</li> -</ul> - -<p>We&rsquo;ll take the second approach, though the first is just as easy.</p> - -<p>The first step will be to <strong>create your gh-pages branch</strong>. You can do that -locally as.</p> - -<pre><code class="language-console">$ git checkout -b gh-pages -</code></pre> - -<p>Or via web browser using <strong>Branch</strong> button on your Github repository:</p> - -<p><img src="https://raw.githubusercontent.com/kubernetes/helm/master/docs/images/create-a-gh-page-button.png" alt="Create Github Pages branch" /></p> - -<p>Next, you&rsquo;ll want to make sure your <strong>gh-pages branch</strong> is set as Github Pages, -click on your repo <strong>Settings</strong> and scroll down to <strong>Github pages</strong> section and -set as per below:</p> - -<p><img src="https://raw.githubusercontent.com/kubernetes/helm/master/docs/images/set-a-gh-page.png" alt="Create Github Pages branch" /></p> - -<p>By default <strong>Source</strong> usually gets set to <strong>gh-pages branch</strong>. If this is not set by default, then select it.</p> - -<p>You can use a <strong>custom domain</strong> there if you wish so.</p> - -<p>And check that <strong>Enforce HTTPS</strong> is ticked, so the <strong>HTTPS</strong> will be used when -charts are served.</p> - -<p>In such setup you can use <strong>master branch</strong> to store your charts code, and -<strong>gh-pages branch</strong> as charts repository, e.g.: -<code>https://USERNAME.github.io/REPONAME</code>. The demonstration <a href="https://github.com/technosophos/tscharts">TS Charts</a> -repository is accessible at <code>https://technosophos.github.io/tscharts/</code>.</p> - -<h3 id="ordinary-web-servers">Ordinary web servers</h3> - -<p>To configure an ordinary web server to serve Helm charts, you merely need to do -the following:</p> - -<ul> -<li>Put your index and charts in a directory that the server can serve</li> -<li>Make sure the <code>index.yaml</code> file can be accessed with no authentication requirement</li> -<li>Make sure <code>yaml</code> files are served with the correct content type (<code>text/yaml</code> or -<code>text/x-yaml</code>)</li> -</ul> - -<p>For example, if you want to serve your charts out of <code>$WEBROOT/charts</code>, make sure -there is a <code>charts/</code> directory in your web root, and put the index file and -charts inside of that folder.</p> - -<h2 id="managing-chart-repositories">Managing Chart Repositories</h2> - -<p>Now that you have a chart repository, the last part of this guide explains how -to maintain charts in that repository.</p> - -<h3 id="store-charts-in-your-chart-repository">Store charts in your chart repository</h3> - -<p>Now that you have a chart repository, let&rsquo;s upload a chart and an index file to -the repository. Charts in a chart repository must be packaged -(<code>helm package chart-name/</code>) and versioned correctly (following -<a href="https://semver.org/">SemVer 2</a> guidelines).</p> - -<p>These next steps compose an example workflow, but you are welcome to use -whatever workflow you fancy for storing and updating charts in your chart -repository.</p> - -<p>Once you have a packaged chart ready, create a new directory, and move your -packaged chart to that directory.</p> - -<pre><code class="language-console">$ helm package docs/examples/alpine/ -$ mkdir fantastic-charts -$ mv alpine-0.1.0.tgz fantastic-charts/ -$ helm repo index fantastic-charts --url https://fantastic-charts.storage.googleapis.com -</code></pre> - -<p>The last command takes the path of the local directory that you just created and -the URL of your remote chart repository and composes an <code>index.yaml</code> file inside the -given directory path.</p> - -<p>Now you can upload the chart and the index file to your chart repository using -a sync tool or manually. If you&rsquo;re using Google Cloud Storage, check out this -<a href="./#developing_charts_sync_example">example workflow</a> using the gsutil client. For -GitHub, you can simply put the charts in the appropriate destination branch.</p> - -<h3 id="add-new-charts-to-an-existing-repository">Add new charts to an existing repository</h3> - -<p>Each time you want to add a new chart to your repository, you must regenerate -the index. The <code>helm repo index</code> command will completely rebuild the <code>index.yaml</code> -file from scratch, including only the charts that it finds locally.</p> - -<p>However, you can use the <code>--merge</code> flag to incrementally add new charts to an -existing <code>index.yaml</code> file (a great option when working with a remote repository -like GCS). Run <code>helm repo index --help</code> to learn more,</p> - -<p>Make sure that you upload both the revised <code>index.yaml</code> file and the chart. And -if you generated a provenance file, upload that too.</p> - -<h3 id="share-your-charts-with-others">Share your charts with others</h3> - -<p>When you&rsquo;re ready to share your charts, simply let someone know what the URL of -your repository is.</p> - -<p>From there, they will add the repository to their helm client via the <code>helm -repo add [NAME] [URL]</code> command with any name they would like to use to -reference the repository.</p> - -<pre><code class="language-console">$ helm repo add fantastic-charts https://fantastic-charts.storage.googleapis.com -$ helm repo list -fantastic-charts https://fantastic-charts.storage.googleapis.com -</code></pre> - -<p>If the charts are backed by HTTP basic authentication, you can also supply the -username and password here:</p> - -<pre><code class="language-console">$ helm repo add fantastic-charts https://username:password@fantastic-charts.storage.googleapis.com -$ helm repo list -fantastic-charts https://username:password@fantastic-charts.storage.googleapis.com -</code></pre> - -<p><strong>Note:</strong> A repository will not be added if it does not contain a valid -<code>index.yaml</code>.</p> - -<p>After that, your users will be able to search through your charts. After you&rsquo;ve updated -the repository, they can use the <code>helm repo update</code> command to get the latest -chart information.</p> - -<p><em>Under the hood, the <code>helm repo add</code> and <code>helm repo update</code> commands are -fetching the index.yaml file and storing them in the -<code>$HELM_HOME/repository/cache/</code> directory. This is where the <code>helm search</code> -function finds information about charts.</em></p> - -<h1 id="syncing-your-chart-repository">Syncing Your Chart Repository</h1> - -<p><em>Note: This example is specifically for a Google Cloud Storage (GCS) bucket which serves a chart repository.</em></p> - -<h2 id="prerequisites-1">Prerequisites</h2> - -<ul> -<li>Install the <a href="https://cloud.google.com/storage/docs/gsutil">gsutil</a> tool. <em>We rely heavily on the gsutil rsync functionality</em></li> -<li>Be sure to have access to the helm binary</li> -<li>_Optional: We recommend you set <a href="https://cloud.google.com/storage/docs/gsutil/addlhelp/ObjectVersioningandConcurrencyControl#top_of_page">object versioning</a> on your GCS bucket in case you accidentally delete something._</li> -</ul> - -<h2 id="set-up-a-local-chart-repository-directory">Set up a local chart repository directory</h2> - -<p>Create a local directory like we did in <a href="./#developing_charts">the chart repository guide</a>, and place your packaged charts in that directory.</p> - -<p>For example:</p> - -<pre><code class="language-console">$ mkdir fantastic-charts -$ mv alpine-0.1.0.tgz fantastic-charts/ -</code></pre> - -<h2 id="generate-an-updated-index-yaml">Generate an updated index.yaml</h2> - -<p>Use helm to generate an updated index.yaml file by passing in the directory path and the url of the remote repository to the <code>helm repo index</code> command like this:</p> - -<pre><code class="language-console">$ helm repo index fantastic-charts/ --url https://fantastic-charts.storage.googleapis.com -</code></pre> - -<p>This will generate an updated index.yaml file and place in the <code>fantastic-charts/</code> directory.</p> - -<h2 id="sync-your-local-and-remote-chart-repositories">Sync your local and remote chart repositories</h2> - -<p>Upload the contents of the directory to your GCS bucket by running <code>scripts/sync-repo.sh</code> and pass in the local directory name and the GCS bucket name.</p> - -<p>For example:</p> - -<pre><code class="language-console">$ pwd -/Users/funuser/go/src/github.com/kubernetes/helm -$ scripts/sync-repo.sh fantastic-charts/ fantastic-charts -Getting ready to sync your local directory (fantastic-charts/) to a remote repository at gs://fantastic-charts -Verifying Prerequisites.... -Thumbs up! Looks like you have gsutil. Let's continue. -Building synchronization state... -Starting synchronization -Would copy file://fantastic-charts/alpine-0.1.0.tgz to gs://fantastic-charts/alpine-0.1.0.tgz -Would copy file://fantastic-charts/index.yaml to gs://fantastic-charts/index.yaml -Are you sure you would like to continue with these changes?? [y/N]} y -Building synchronization state... -Starting synchronization -Copying file://fantastic-charts/alpine-0.1.0.tgz [Content-Type=application/x-tar]... -Uploading gs://fantastic-charts/alpine-0.1.0.tgz: 740 B/740 B -Copying file://fantastic-charts/index.yaml [Content-Type=application/octet-stream]... -Uploading gs://fantastic-charts/index.yaml: 347 B/347 B -Congratulations your remote chart repository now matches the contents of fantastic-charts/ -</code></pre> - -<h2 id="updating-your-chart-repository">Updating your chart repository</h2> - -<p>You&rsquo;ll want to keep a local copy of the contents of your chart repository or use <code>gsutil rsync</code> to copy the contents of your remote chart repository to a local directory.</p> - -<p>For example:</p> - -<pre><code class="language-console">$ gsutil rsync -d -n gs://bucket-name local-dir/ # the -n flag does a dry run -Building synchronization state... -Starting synchronization -Would copy gs://bucket-name/alpine-0.1.0.tgz to file://local-dir/alpine-0.1.0.tgz -Would copy gs://bucket-name/index.yaml to file://local-dir/index.yaml - -$ gsutil rsync -d gs://bucket-name local-dir/ # performs the copy actions -Building synchronization state... -Starting synchronization -Copying gs://bucket-name/alpine-0.1.0.tgz... -Downloading file://local-dir/alpine-0.1.0.tgz: 740 B/740 B -Copying gs://bucket-name/index.yaml... -Downloading file://local-dir/index.yaml: 346 B/346 B -</code></pre> - -<p>Helpful Links: -* Documentation on <a href="https://cloud.google.com/storage/docs/gsutil/commands/rsync#description">gsutil rsync</a> -* <a href="./#developing_charts">The Chart Repository Guide</a> -* Documentation on <a href="https://cloud.google.com/storage/docs/gsutil/addlhelp/ObjectVersioningandConcurrencyControl#overview">object versioning and concurrency control</a> in Google Cloud Storage</p> - -<h1 id="helm-provenance-and-integrity">Helm Provenance and Integrity</h1> - -<p>Helm has provenance tools which help chart users verify the integrity and origin -of a package. Using industry-standard tools based on PKI, GnuPG, and well-respected -package managers, Helm can generate and verify signature files.</p> - -<p><strong>Note:</strong> -Version 2.0.0-alpha.4 introduced a system for verifying the authenticity of charts. -While we do not anticipate that any major changes will be made to the file formats -or provenancing algorithms, this portion of Helm is not considered <em>frozen</em> until -2.0.0-RC1 is released. The original plan for this feature can be found -<a href="https://github.com/kubernetes/helm/issues/983">at issue 983</a>.</p> - -<h2 id="overview">Overview</h2> - -<p>Integrity is established by comparing a chart to a provenance record. Provenance -records are stored in <em>provenance files</em>, which are stored alongside a packaged -chart. For example, if a chart is named <code>myapp-1.2.3.tgz</code>, its provenance file -will be <code>myapp-1.2.3.tgz.prov</code>.</p> - -<p>Provenance files are generated at packaging time (<code>helm package --sign ...</code>), and -can be checked by multiple commands, notable <code>helm install --verify</code>.</p> - -<h2 id="the-workflow">The Workflow</h2> - -<p>This section describes a potential workflow for using provenance data effectively.</p> - -<p>Prerequisites:</p> - -<ul> -<li>A valid PGP keypair in a binary (not ASCII-armored) format</li> -<li>The <code>helm</code> command line tool</li> -<li>GnuPG command line tools (optional)</li> -<li>Keybase command line tools (optional)</li> -</ul> - -<p><strong>NOTE:</strong> If your PGP private key has a passphrase, you will be prompted to enter -that passphrase for any commands that support the <code>--sign</code> option.</p> - -<p>Creating a new chart is the same as before:</p> - -<pre><code>$ helm create mychart -Creating mychart -</code></pre> - -<p>Once ready to package, add the <code>--sign</code> flag to <code>helm package</code>. Also, specify -the name under which the signing key is known and the keyring containing the corresponding private key:</p> - -<pre><code>$ helm package --sign --key 'helm signing key' --keyring path/to/keyring.secret mychart -</code></pre> - -<p><strong>TIP:</strong> for GnuPG users, your secret keyring is in <code>~/.gnupg/secring.gpg</code>. You can -use <code>gpg --list-secret-keys</code> to list the keys you have.</p> - -<p>At this point, you should see both <code>mychart-0.1.0.tgz</code> and <code>mychart-0.1.0.tgz.prov</code>. -Both files should eventually be uploaded to your desired chart repository.</p> - -<p>You can verify a chart using <code>helm verify</code>:</p> - -<pre><code>$ helm verify mychart-0.1.0.tgz -</code></pre> - -<p>A failed verification looks like this:</p> - -<pre><code>$ helm verify topchart-0.1.0.tgz -Error: sha256 sum does not match for topchart-0.1.0.tgz: &quot;sha256:1939fbf7c1023d2f6b865d137bbb600e0c42061c3235528b1e8c82f4450c12a7&quot; != &quot;sha256:5a391a90de56778dd3274e47d789a2c84e0e106e1a37ef8cfa51fd60ac9e623a&quot; -</code></pre> - -<p>To verify during an install, use the <code>--verify</code> flag.</p> - -<pre><code>$ helm install --verify mychart-0.1.0.tgz -</code></pre> - -<p>If the keyring (containing the public key associated with the signed chart) is not in the default location, you may need to point to the -keyring with <code>--keyring PATH</code> as in the <code>helm package</code> example.</p> - -<p>If verification fails, the install will be aborted before the chart is even pushed -up to Tiller.</p> - -<h3 id="using-keybase-io-credentials">Using Keybase.io credentials</h3> - -<p>The <a href="https://keybase.io">Keybase.io</a> service makes it easy to establish a chain of -trust for a cryptographic identity. Keybase credentials can be used to sign charts.</p> - -<p>Prerequisites:</p> - -<ul> -<li>A configured Keybase.io account</li> -<li>GnuPG installed locally</li> -<li>The <code>keybase</code> CLI installed locally</li> -</ul> - -<h4 id="signing-packages">Signing packages</h4> - -<p>The first step is to import your keybase keys into your local GnuPG keyring:</p> - -<pre><code>$ keybase pgp export -s | gpg --import -</code></pre> - -<p>This will convert your Keybase key into the OpenPGP format, and then import it -locally into your <code>~/.gnupg/secring.gpg</code> file.</p> - -<p>You can double check by running <code>gpg --list-secret-keys</code>.</p> - -<pre><code>$ gpg --list-secret-keys 1 ↵ -/Users/mattbutcher/.gnupg/secring.gpg -------------------------------------- -sec 2048R/1FC18762 2016-07-25 -uid technosophos (keybase.io/technosophos) &lt;technosophos@keybase.io&gt; -ssb 2048R/D125E546 2016-07-25 -</code></pre> - -<p>Note that your secret key will have an identifier string:</p> - -<pre><code>technosophos (keybase.io/technosophos) &lt;technosophos@keybase.io&gt; -</code></pre> - -<p>That is the full name of your key.</p> - -<p>Next, you can package and sign a chart with <code>helm package</code>. Make sure you use at -least part of that name string in <code>--key</code>.</p> - -<pre><code>$ helm package --sign --key technosophos --keyring ~/.gnupg/secring.gpg mychart -</code></pre> - -<p>As a result, the <code>package</code> command should produce both a <code>.tgz</code> file and a <code>.tgz.prov</code> -file.</p> - -<h4 id="verifying-packages">Verifying packages</h4> - -<p>You can also use a similar technique to verify a chart signed by someone else&rsquo;s -Keybase key. Say you want to verify a package signed by <code>keybase.io/technosophos</code>. -To do this, use the <code>keybase</code> tool:</p> - -<pre><code>$ keybase follow technosophos -$ keybase pgp pull -</code></pre> - -<p>The first command above tracks the user <code>technosophos</code>. Next <code>keybase pgp pull</code> -downloads the OpenPGP keys of all of the accounts you follow, placing them in -your GnuPG keyring (<code>~/.gnupg/pubring.gpg</code>).</p> - -<p>At this point, you can now use <code>helm verify</code> or any of the commands with a <code>--verify</code> -flag:</p> - -<pre><code>$ helm verify somechart-1.2.3.tgz -</code></pre> - -<h3 id="reasons-a-chart-may-not-verify">Reasons a chart may not verify</h3> - -<p>These are common reasons for failure.</p> - -<ul> -<li>The prov file is missing or corrupt. This indicates that something is misconfigured -or that the original maintainer did not create a provenance file.</li> -<li>The key used to sign the file is not in your keyring. This indicate that the -entity who signed the chart is not someone you&rsquo;ve already signaled that you trust.</li> -<li>The verification of the prov file failed. This indicates that something is wrong -with either the chart or the provenance data.</li> -<li>The file hashes in the provenance file do not match the hash of the archive file. This -indicates that the archive has been tampered with.</li> -</ul> - -<p>If a verification fails, there is reason to distrust the package.</p> - -<h2 id="the-provenance-file">The Provenance File</h2> - -<p>The provenance file contains a chart’s YAML file plus several pieces of -verification information. Provenance files are designed to be automatically -generated.</p> - -<p>The following pieces of provenance data are added:</p> - -<ul> -<li>The chart file (Chart.yaml) is included to give both humans and tools an easy -view into the contents of the chart.</li> -<li>The signature (SHA256, just like Docker) of the chart package (the .tgz file) -is included, and may be used to verify the integrity of the chart package.</li> -<li>The entire body is signed using the algorithm used by PGP (see -[<a href="http://keybase.io">http://keybase.io</a>] for an emerging way of making crypto signing and -verification easy).</li> -</ul> - -<p>The combination of this gives users the following assurances:</p> - -<ul> -<li>The package itself has not been tampered with (checksum package tgz).</li> -<li>The entity who released this package is known (via the GnuPG/PGP signature).</li> -</ul> - -<p>The format of the file looks something like this:</p> - -<pre><code>-----BEGIN PGP SIGNED MESSAGE----- -name: nginx -description: The nginx web server as a replication controller and service pair. -version: 0.5.1 -keywords: - - https - - http - - web server - - proxy -source: -- https://github.com/foo/bar -home: http://nginx.com - -... -files: - nginx-0.5.1.tgz: “sha256:9f5270f50fc842cfcb717f817e95178f” ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1.4.9 (GNU/Linux) - -iEYEARECAAYFAkjilUEACgQkB01zfu119ZnHuQCdGCcg2YxF3XFscJLS4lzHlvte -WkQAmQGHuuoLEJuKhRNo+Wy7mhE7u1YG -=eifq ------END PGP SIGNATURE----- -</code></pre> - -<p>Note that the YAML section contains two documents (separated by <code>...\n</code>). The -first is the Chart.yaml. The second is the checksums, a map of filenames to -SHA-256 digests (value shown is fake/truncated)</p> - -<p>The signature block is a standard PGP signature, which provides <a href="http://www.rossde.com/PGP/pgp_signatures.html">tamper -resistance</a>.</p> - -<h2 id="chart-repositories-1">Chart Repositories</h2> - -<p>Chart repositories serve as a centralized collection of Helm charts.</p> - -<p>Chart repositories must make it possible to serve provenance files over HTTP via -a specific request, and must make them available at the same URI path as the chart.</p> - -<p>For example, if the base URL for a package is <code>https://example.com/charts/mychart-1.2.3.tgz</code>, -the provenance file, if it exists, MUST be accessible at <code>https://example.com/charts/mychart-1.2.3.tgz.prov</code>.</p> - -<p>From the end user&rsquo;s perspective, <code>helm install --verify myrepo/mychart-1.2.3</code> -should result in the download of both the chart and the provenance file with no -additional user configuration or action.</p> - -<h2 id="establishing-authority-and-authenticity">Establishing Authority and Authenticity</h2> - -<p>When dealing with chain-of-trust systems, it is important to be able to -establish the authority of a signer. Or, to put this plainly, the system -above hinges on the fact that you trust the person who signed the chart. -That, in turn, means you need to trust the public key of the signer.</p> - -<p>One of the design decisions with Kubernetes Helm has been that the Helm -project would not insert itself into the chain of trust as a necessary -party. We don&rsquo;t want to be &ldquo;the certificate authority&rdquo; for all chart -signers. Instead, we strongly favor a decentralized model, which is part -of the reason we chose OpenPGP as our foundational technology. -So when it comes to establishing authority, we have left this -step more-or-less undefined in Helm 2.0.0.</p> - -<p>However, we have some pointers and recommendations for those interested -in using the provenance system:</p> - -<ul> -<li>The <a href="https://keybase.io">Keybase</a> platform provides a public -centralized repository for trust information. - -<ul> -<li>You can use Keybase to store your keys or to get the public keys of others.</li> -<li>Keybase also has fabulous documentation available</li> -<li>While we haven&rsquo;t tested it, Keybase&rsquo;s &ldquo;secure website&rdquo; feature could -be used to serve Helm charts.</li> -</ul></li> -<li>The <a href="https://github.com/kubernetes/charts">official Kubernetes Charts project</a> -is trying to solve this problem for the official chart repository. - -<ul> -<li>There is a long issue there <a href="https://github.com/kubernetes/charts/issues/23">detailing the current thoughts</a>.</li> -<li>The basic idea is that an official &ldquo;chart reviewer&rdquo; signs charts with -her or his key, and the resulting provenance file is then uploaded -to the chart repository.</li> -<li>There has been some work on the idea that a list of valid signing -keys may be included in the <code>index.yaml</code> file of a repository.</li> -</ul></li> -</ul> - -<p>Finally, chain-of-trust is an evolving feature of Helm, and some -community members have proposed adapting part of the OSI model for -signatures. This is an open line of inquiry in the Helm team. If you&rsquo;re -interested, jump on in.</p> - -<h1 id="chart-tests">Chart Tests</h1> - -<p>A chart contains a number of Kubernetes resources and components that work together. As a chart author, you may want to write some tests that validate that your chart works as expected when it is installed. These tests also help the chart consumer understand what your chart is supposed to do.</p> - -<p>A <strong>test</strong> in a helm chart lives under the <code>templates/</code> directory and is a pod definition that specifies a container with a given command to run. The container should exit successfully (exit 0) for a test to be considered a success. The pod definition must contain one of the helm test hook annotations: <code>helm.sh/hooks: test-success</code> or <code>helm.sh/hooks: test-failure</code>.</p> - -<p>Example tests: -- Validate that your configuration from the values.yaml file was properly injected. - - Make sure your username and password work correctly - - Make sure an incorrect username and password does not work -- Assert that your services are up and correctly load balancing -- etc.</p> - -<p>You can run the pre-defined tests in Helm on a release using the command <code>helm test &lt;RELEASE_NAME&gt;</code>. For a chart consumer, this is a great way to sanity check that their release of a chart (or application) works as expected.</p> - -<h2 id="a-breakdown-of-the-helm-test-hooks">A Breakdown of the Helm Test Hooks</h2> - -<p>In Helm, there are two test hooks: <code>test-success</code> and <code>test-failure</code></p> - -<p><code>test-success</code> indicates that test pod should complete successfully. In other words, the containers in the pod should exit 0. -<code>test-failure</code> is a way to assert that a test pod should not complete successfully. If the containers in the pod do not exit 0, that indicates success.</p> - -<h2 id="example-test">Example Test</h2> - -<p>Here is an example of a helm test pod definition in an example mariadb chart:</p> - -<pre><code>mariadb/ - Chart.yaml - README.md - values.yaml - charts/ - templates/ - templates/tests/test-mariadb-connection.yaml -</code></pre> - -<p>In <code>wordpress/templates/tests/test-mariadb-connection.yaml</code>:</p> - -<pre><code>apiVersion: v1 -kind: Pod -metadata: - name: &quot;{{ .Release.Name }}-credentials-test&quot; - annotations: - &quot;helm.sh/hook&quot;: test-success -spec: - containers: - - name: {{ .Release.Name }}-credentials-test - image: {{ .Values.image }} - env: - - name: MARIADB_HOST - value: {{ template &quot;mariadb.fullname&quot; . }} - - name: MARIADB_PORT - value: &quot;3306&quot; - - name: WORDPRESS_DATABASE_NAME - value: {{ default &quot;&quot; .Values.mariadb.mariadbDatabase | quote }} - - name: WORDPRESS_DATABASE_USER - value: {{ default &quot;&quot; .Values.mariadb.mariadbUser | quote }} - - name: WORDPRESS_DATABASE_PASSWORD - valueFrom: - secretKeyRef: - name: {{ template &quot;mariadb.fullname&quot; . }} - key: mariadb-password - command: [&quot;sh&quot;, &quot;-c&quot;, &quot;mysql --host=$MARIADB_HOST --port=$MARIADB_PORT --user=$WORDPRESS_DATABASE_USER --password=$WORDPRESS_DATABASE_PASSWORD&quot;] - restartPolicy: Never -</code></pre> - -<h2 id="steps-to-run-a-test-suite-on-a-release">Steps to Run a Test Suite on a Release</h2> - -<ol> -<li><p><code>$ helm install mariadb</code></p> - -<pre><code>NAME: quirky-walrus -LAST DEPLOYED: Mon Feb 13 13:50:43 2017 -NAMESPACE: default -STATUS: DEPLOYED -</code></pre></li> - -<li><p><code>$ helm test quirky-walrus</code></p> - -<pre><code>RUNNING: quirky-walrus-credentials-test -SUCCESS: quirky-walrus-credentials-test -</code></pre></li> -</ol> - -<h2 id="notes">Notes</h2> - -<ul> -<li>You can define as many tests as you would like in a single yaml file or spread across several yaml files in the <code>templates/</code> directory</li> -<li>You are welcome to nest your test suite under a <code>tests/</code> directory like <code>&lt;chart-name&gt;/templates/tests/</code> for more isolation</li> -</ul> - -<h1 id="chart-repositories-frequently-asked-questions">Chart Repositories: Frequently Asked Questions</h1> - -<p>This section tracks some of the more frequently encountered issues with using chart repositories.</p> - -<p><strong>We&rsquo;d love your help</strong> making this document better. To add, correct, or remove -information, <a href="https://github.com/kubernetes/helm/issues">file an issue</a> or -send us a pull request.</p> - -<h2 id="fetching">Fetching</h2> - -<p><strong>Q: Why do I get a <code>unsupported protocol scheme &quot;&quot;</code> error when trying to fetch a chart from my custom repo?</strong></p> - -<p>A: (Helm &lt; 2.5.0) This is likely caused by you creating your chart repo index without specifying the <code>--url</code> flag. -Try recreating your <code>index.yaml</code> file with a command like <code>helm repo index --url http://my-repo/charts .</code>, -and then re-uploading it to your custom charts repo.</p> - -<p>This behavior was changed in Helm 2.5.0.</p> - - - - - diff --git a/docs.helm.sh/rootfs/public/examples/alpine/Chart.yaml b/docs.helm.sh/rootfs/public/examples/alpine/Chart.yaml deleted file mode 100644 index f4b660d4f8..0000000000 --- a/docs.helm.sh/rootfs/public/examples/alpine/Chart.yaml +++ /dev/null @@ -1,7 +0,0 @@ -name: alpine -description: Deploy a basic Alpine Linux pod -version: 0.1.0 -home: https://github.com/kubernetes/helm -sources: - - https://github.com/kubernetes/helm -appVersion: 3.3 diff --git a/docs.helm.sh/rootfs/public/examples/alpine/readme/index.html b/docs.helm.sh/rootfs/public/examples/alpine/readme/index.html deleted file mode 100644 index c298b59480..0000000000 --- a/docs.helm.sh/rootfs/public/examples/alpine/readme/index.html +++ /dev/null @@ -1,1334 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

Alpine: A simple Helm chart

- -

Run a single pod of Alpine Linux.

- -

The templates/ directory contains a very simple pod resource with a -couple of parameters.

- -

The values.yaml file contains the default values for the -alpine-pod.yaml template.

- -

You can install this example using helm install docs/examples/alpine.

- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/examples/alpine/templates/_helpers.tpl b/docs.helm.sh/rootfs/public/examples/alpine/templates/_helpers.tpl deleted file mode 100644 index 3e9c25bed0..0000000000 --- a/docs.helm.sh/rootfs/public/examples/alpine/templates/_helpers.tpl +++ /dev/null @@ -1,16 +0,0 @@ -{{/* vim: set filetype=mustache: */}} -{{/* -Expand the name of the chart. -*/}} -{{- define "alpine.name" -}} -{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} -{{- end -}} - -{{/* -Create a default fully qualified app name. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -*/}} -{{- define "alpine.fullname" -}} -{{- $name := default .Chart.Name .Values.nameOverride -}} -{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} -{{- end -}} diff --git a/docs.helm.sh/rootfs/public/examples/alpine/templates/alpine-pod.yaml b/docs.helm.sh/rootfs/public/examples/alpine/templates/alpine-pod.yaml deleted file mode 100644 index da9caef781..0000000000 --- a/docs.helm.sh/rootfs/public/examples/alpine/templates/alpine-pod.yaml +++ /dev/null @@ -1,23 +0,0 @@ -apiVersion: v1 -kind: Pod -metadata: - name: {{ template "alpine.fullname" . }} - labels: - # The "heritage" label is used to track which tool deployed a given chart. - # It is useful for admins who want to see what releases a particular tool - # is responsible for. - heritage: {{ .Release.Service }} - # The "release" convention makes it easy to tie a release to all of the - # Kubernetes resources that were created as part of that release. - release: {{ .Release.Name }} - # This makes it easy to audit chart usage. - chart: {{ .Chart.Name }}-{{ .Chart.Version }} - app: {{ template "alpine.name" . }} -spec: - # This shows how to use a simple value. This will look for a passed-in value called restartPolicy. - restartPolicy: {{ .Values.restartPolicy }} - containers: - - name: waiter - image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" - imagePullPolicy: {{ .Values.image.pullPolicy }} - command: ["/bin/sleep", "9000"] diff --git a/docs.helm.sh/rootfs/public/examples/alpine/values.yaml b/docs.helm.sh/rootfs/public/examples/alpine/values.yaml deleted file mode 100644 index afe8cc6c0f..0000000000 --- a/docs.helm.sh/rootfs/public/examples/alpine/values.yaml +++ /dev/null @@ -1,6 +0,0 @@ -image: - repository: alpine - tag: 3.3 - pullPolicy: IfNotPresent - -restartPolicy: Never diff --git a/docs.helm.sh/rootfs/public/examples/index.html b/docs.helm.sh/rootfs/public/examples/index.html deleted file mode 100644 index 4f8d901d1c..0000000000 --- a/docs.helm.sh/rootfs/public/examples/index.html +++ /dev/null @@ -1,1414 +0,0 @@ - - - - - - - - - Examples - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
- -
-
- -

Helm Examples

- -

This directory contains example charts to help you get started with -chart development.

- -

Alpine

- -

The alpine chart is very simple, and is a good starting point.

- -

It simply deploys a single pod running Alpine Linux.

- -

Nginx

- -

The nginx chart shows how to compose several resources into one chart, -and it illustrates more complex template usage.

- -

It deploys a deployment (which creates a replica set), a config -map, and a service. The replica set starts an nginx pod. The config -map stores the files that the nginx server can serve.

-
-
- -
-
- -

Alpine: A simple Helm chart

- -

Run a single pod of Alpine Linux.

- -

The templates/ directory contains a very simple pod resource with a -couple of parameters.

- -

The values.yaml file contains the default values for the -alpine-pod.yaml template.

- -

You can install this example using helm install docs/examples/alpine.

-
-
- -
-
- -

nginx: An advanced example chart

- -

This Helm chart provides examples of some of Helm’s more powerful -features.

- -

This is not a production-grade chart. It is an example.

- -

The chart installs a simple nginx server according to the following -pattern:

- - - -

The values.yaml exposes a few of the configuration options in the -charts, though there are some that are not exposed there (like -.image).

- -

The templates/_helpers.tpl file contains helper templates. The leading -underscore (_) on the filename is semantic. It tells the template renderer -that this file does not contain a manifest. That file declares some -templates that are used elsewhere in the chart.

- -

Helpers (usually called “partials” in template languages) are an -advanced way for developers to structure their templates for optimal -reuse.

- -

You can deploy this chart with helm install docs/examples/nginx. Or -you can see how this chart would render with helm install --dry-run ---debug docs/examples/nginx.

-
-
- -
-
 
-
- -
-
-

- Helm is supported by and built with a community of over 250 developers. -

-

- helm.sh and docs.helm.sh are maintained by Microsoft -

-
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/examples/index.xml b/docs.helm.sh/rootfs/public/examples/index.xml deleted file mode 100644 index 7e7810545c..0000000000 --- a/docs.helm.sh/rootfs/public/examples/index.xml +++ /dev/null @@ -1,105 +0,0 @@ - - - - Examples - https://docs.helm.sh/examples/ - en-us - Mon, 01 Jan 0001 00:00:00 UTC - - - - https://docs.helm.sh/examples/readme/ - Mon, 01 Jan 0001 00:00:00 UTC - https://docs.helm.sh/examples/readme/ - - -<h1 id="helm-examples">Helm Examples</h1> - -<p>This directory contains example charts to help you get started with -chart development.</p> - -<h2 id="alpine">Alpine</h2> - -<p>The <code>alpine</code> chart is very simple, and is a good starting point.</p> - -<p>It simply deploys a single pod running Alpine Linux.</p> - -<h2 id="nginx">Nginx</h2> - -<p>The <code>nginx</code> chart shows how to compose several resources into one chart, -and it illustrates more complex template usage.</p> - -<p>It deploys a <code>deployment</code> (which creates a <code>replica set</code>), a <code>config -map</code>, and a <code>service</code>. The replica set starts an nginx pod. The config -map stores the files that the nginx server can serve.</p> - - - - - - https://docs.helm.sh/examples/alpine/readme/ - Mon, 01 Jan 0001 00:00:00 UTC - https://docs.helm.sh/examples/alpine/readme/ - - -<h1 id="alpine-a-simple-helm-chart">Alpine: A simple Helm chart</h1> - -<p>Run a single pod of Alpine Linux.</p> - -<p>The <code>templates/</code> directory contains a very simple pod resource with a -couple of parameters.</p> - -<p>The <code>values.yaml</code> file contains the default values for the -<code>alpine-pod.yaml</code> template.</p> - -<p>You can install this example using <code>helm install docs/examples/alpine</code>.</p> - - - - - - https://docs.helm.sh/examples/nginx/readme/ - Mon, 01 Jan 0001 00:00:00 UTC - https://docs.helm.sh/examples/nginx/readme/ - - -<h1 id="nginx-an-advanced-example-chart">nginx: An advanced example chart</h1> - -<p>This Helm chart provides examples of some of Helm&rsquo;s more powerful -features.</p> - -<p><strong>This is not a production-grade chart. It is an example.</strong></p> - -<p>The chart installs a simple nginx server according to the following -pattern:</p> - -<ul> -<li>A <code>ConfigMap</code> is used to store the files the server will serve. -(<a href="templates/configmap.yaml">templates/configmap.yaml</a>)</li> -<li>A <code>Deployment</code> is used to create a Replica Set of nginx pods. -(<a href="templates/deployment.yaml">templates/deployment.yaml</a>)</li> -<li>A <code>Service</code> is used to create a gateway to the pods running in the -replica set (<a href="templates/service.yaml">templates/service.yaml</a>)</li> -</ul> - -<p>The <a href="values.yaml">values.yaml</a> exposes a few of the configuration options in the -charts, though there are some that are not exposed there (like -<code>.image</code>).</p> - -<p>The <a href="templates/_helpers.tpl">templates/_helpers.tpl</a> file contains helper templates. The leading -underscore (<code>_</code>) on the filename is semantic. It tells the template renderer -that this file does not contain a manifest. That file declares some -templates that are used elsewhere in the chart.</p> - -<p>Helpers (usually called &ldquo;partials&rdquo; in template languages) are an -advanced way for developers to structure their templates for optimal -reuse.</p> - -<p>You can deploy this chart with <code>helm install docs/examples/nginx</code>. Or -you can see how this chart would render with <code>helm install --dry-run ---debug docs/examples/nginx</code>.</p> - - - - - diff --git a/docs.helm.sh/rootfs/public/examples/nginx/Chart.yaml b/docs.helm.sh/rootfs/public/examples/nginx/Chart.yaml deleted file mode 100644 index 6ca92998d6..0000000000 --- a/docs.helm.sh/rootfs/public/examples/nginx/Chart.yaml +++ /dev/null @@ -1,14 +0,0 @@ -name: nginx -description: A basic NGINX HTTP server -version: 0.1.0 -keywords: - - http - - nginx - - www - - web -home: https://github.com/kubernetes/helm -sources: - - https://hub.docker.com/_/nginx/ -maintainers: - - name: technosophos - email: mbutcher@deis.com diff --git a/docs.helm.sh/rootfs/public/examples/nginx/readme/index.html b/docs.helm.sh/rootfs/public/examples/nginx/readme/index.html deleted file mode 100644 index 7c9d0b9ccb..0000000000 --- a/docs.helm.sh/rootfs/public/examples/nginx/readme/index.html +++ /dev/null @@ -1,1358 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

nginx: An advanced example chart

- -

This Helm chart provides examples of some of Helm’s more powerful -features.

- -

This is not a production-grade chart. It is an example.

- -

The chart installs a simple nginx server according to the following -pattern:

- - - -

The values.yaml exposes a few of the configuration options in the -charts, though there are some that are not exposed there (like -.image).

- -

The templates/_helpers.tpl file contains helper templates. The leading -underscore (_) on the filename is semantic. It tells the template renderer -that this file does not contain a manifest. That file declares some -templates that are used elsewhere in the chart.

- -

Helpers (usually called “partials” in template languages) are an -advanced way for developers to structure their templates for optimal -reuse.

- -

You can deploy this chart with helm install docs/examples/nginx. Or -you can see how this chart would render with helm install --dry-run ---debug docs/examples/nginx.

- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/examples/nginx/templates/_helpers.tpl b/docs.helm.sh/rootfs/public/examples/nginx/templates/_helpers.tpl deleted file mode 100644 index 2ec6ba7575..0000000000 --- a/docs.helm.sh/rootfs/public/examples/nginx/templates/_helpers.tpl +++ /dev/null @@ -1,16 +0,0 @@ -{{/* vim: set filetype=mustache: */}} -{{/* -Expand the name of the chart. -*/}} -{{- define "nginx.name" -}} -{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} -{{- end -}} - -{{/* -Create a default fully qualified app name. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -*/}} -{{- define "nginx.fullname" -}} -{{- $name := default .Chart.Name .Values.nameOverride -}} -{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} -{{- end -}} diff --git a/docs.helm.sh/rootfs/public/examples/nginx/templates/configmap.yaml b/docs.helm.sh/rootfs/public/examples/nginx/templates/configmap.yaml deleted file mode 100644 index b90d6c0c72..0000000000 --- a/docs.helm.sh/rootfs/public/examples/nginx/templates/configmap.yaml +++ /dev/null @@ -1,14 +0,0 @@ -# This is a simple example of using a config map to create a single page static site. -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ template "nginx.fullname" . }} - labels: - heritage: {{ .Release.Service }} - release: {{ .Release.Name }} - chart: {{ .Chart.Name }}-{{ .Chart.Version }} - app: {{ template "nginx.name" . }} -data: - # When the config map is mounted as a volume, these will be created as files. - index.html: {{ .Values.index | quote }} - test.txt: test diff --git a/docs.helm.sh/rootfs/public/examples/nginx/templates/deployment.yaml b/docs.helm.sh/rootfs/public/examples/nginx/templates/deployment.yaml deleted file mode 100644 index 5fa2633eab..0000000000 --- a/docs.helm.sh/rootfs/public/examples/nginx/templates/deployment.yaml +++ /dev/null @@ -1,57 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - # This uses a "fullname" template (see _helpers) - # Basing names on .Release.Name means that the same chart can be installed - # multiple times into the same namespace. - name: {{ template "nginx.fullname" . }} - labels: - # The "heritage" label is used to track which tool deployed a given chart. - # It is useful for admins who want to see what releases a particular tool - # is responsible for. - heritage: {{ .Release.Service }} - # The "release" convention makes it easy to tie a release to all of the - # Kubernetes resources that were created as part of that release. - release: {{ .Release.Name }} - # This makes it easy to audit chart usage. - chart: {{ .Chart.Name }}-{{ .Chart.Version }} - app: {{ template "nginx.name" . }} -spec: - replicas: {{ .Values.replicaCount }} - template: - metadata: -{{- if .Values.podAnnotations }} - # Allows custom annotations to be specified - annotations: -{{ toYaml .Values.podAnnotations | indent 8 }} -{{- end }} - labels: - app: {{ template "nginx.name" . }} - release: {{ .Release.Name }} - spec: - containers: - - name: {{ template "nginx.name" . }} - image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" - imagePullPolicy: {{ .Values.image.pullPolicy }} - ports: - - name: http - containerPort: 80 - protocol: TCP - # This (and the volumes section below) mount the config map as a volume. - volumeMounts: - - mountPath: /usr/share/nginx/html - name: wwwdata-volume - resources: -# Allow chart users to specify resources. Usually, no default should be set, so this is left to be a conscious -# choice to the chart users and avoids that charts don't run out of the box on, e. g., Minikube when high resource -# requests are specified by default. -{{ toYaml .Values.resources | indent 12 }} - {{- if .Values.nodeSelector }} - nodeSelector: - # Node selectors can be important on mixed Windows/Linux clusters. -{{ toYaml .Values.nodeSelector | indent 8 }} - {{- end }} - volumes: - - name: wwwdata-volume - configMap: - name: {{ template "nginx.fullname" . }} diff --git a/docs.helm.sh/rootfs/public/examples/nginx/templates/post-install-job.yaml b/docs.helm.sh/rootfs/public/examples/nginx/templates/post-install-job.yaml deleted file mode 100644 index 9ec90cd0aa..0000000000 --- a/docs.helm.sh/rootfs/public/examples/nginx/templates/post-install-job.yaml +++ /dev/null @@ -1,37 +0,0 @@ -apiVersion: batch/v1 -kind: Job -metadata: - name: {{ template "nginx.fullname" . }} - labels: - # The "heritage" label is used to track which tool deployed a given chart. - # It is useful for admins who want to see what releases a particular tool - # is responsible for. - heritage: {{ .Release.Service }} - # The "release" convention makes it easy to tie a release to all of the - # Kubernetes resources that were created as part of that release. - release: {{ .Release.Name }} - # This makes it easy to audit chart usage. - chart: {{ .Chart.Name }}-{{ .Chart.Version }} - app: {{ template "nginx.name" . }} - annotations: - # This is what defines this resource as a hook. Without this line, the - # job is considered part of the release. - "helm.sh/hook": post-install -spec: - template: - metadata: - name: {{ template "nginx.fullname" . }} - labels: - release: {{ .Release.Name }} - app: {{ template "nginx.name" . }} - spec: - # This shows how to use a simple value. This will look for a passed-in value - # called restartPolicy. If it is not found, it will use the default value. - # {{ default "Never" .restartPolicy }} is a slightly optimized version of the - # more conventional syntax: {{ .restartPolicy | default "Never" }} - restartPolicy: {{ .Values.restartPolicy }} - containers: - - name: post-install-job - image: "alpine:3.3" - # All we're going to do is sleep for a while, then exit. - command: ["/bin/sleep", "{{ .Values.sleepyTime }}"] diff --git a/docs.helm.sh/rootfs/public/examples/nginx/templates/pre-install-secret.yaml b/docs.helm.sh/rootfs/public/examples/nginx/templates/pre-install-secret.yaml deleted file mode 100644 index 6392f9684a..0000000000 --- a/docs.helm.sh/rootfs/public/examples/nginx/templates/pre-install-secret.yaml +++ /dev/null @@ -1,19 +0,0 @@ -# This shows a secret as a pre-install hook. -# A pre-install hook is run before the rest of the chart is loaded. -apiVersion: v1 -kind: Secret -metadata: - name: {{ template "nginx.fullname" . }} - labels: - heritage: {{ .Release.Service }} - release: {{ .Release.Name }} - chart: {{ .Chart.Name }}-{{ .Chart.Version }} - app: {{ template "nginx.name" . }} - # This declares the resource to be a hook. By convention, we also name the - # file "pre-install-XXX.yaml", but Helm itself doesn't care about file names. - annotations: - "helm.sh/hook": pre-install -type: Opaque -data: - password: {{ b64enc "secret" }} - username: {{ b64enc "user1" }} diff --git a/docs.helm.sh/rootfs/public/examples/nginx/templates/service-test.yaml b/docs.helm.sh/rootfs/public/examples/nginx/templates/service-test.yaml deleted file mode 100644 index 3913ead9cc..0000000000 --- a/docs.helm.sh/rootfs/public/examples/nginx/templates/service-test.yaml +++ /dev/null @@ -1,18 +0,0 @@ -apiVersion: v1 -kind: Pod -metadata: - name: "{{ template "nginx.fullname" . }}-service-test" - labels: - heritage: {{ .Release.Service }} - release: {{ .Release.Name }} - chart: {{ .Chart.Name }}-{{ .Chart.Version }} - app: {{ template "nginx.name" . }} - annotations: - "helm.sh/hook": test-success -spec: - containers: - - name: curl - image: radial/busyboxplus:curl - command: ['curl'] - args: ['{{ template "nginx.fullname" . }}:{{ .Values.service.port }}'] - restartPolicy: Never diff --git a/docs.helm.sh/rootfs/public/examples/nginx/templates/service.yaml b/docs.helm.sh/rootfs/public/examples/nginx/templates/service.yaml deleted file mode 100644 index 1481e34f01..0000000000 --- a/docs.helm.sh/rootfs/public/examples/nginx/templates/service.yaml +++ /dev/null @@ -1,39 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: -{{- if .Values.service.annotations }} - annotations: -{{ toYaml .Values.service.annotations | indent 4 }} -{{- end }} - labels: - app: {{ template "nginx.name" . }} - chart: {{ .Chart.Name }}-{{ .Chart.Version }} - heritage: {{ .Release.Service }} - release: {{ .Release.Name }} - name: {{ template "nginx.fullname" . }} -spec: -# Provides options for the service so chart users have the full choice - type: "{{ .Values.service.type }}" - clusterIP: "{{ .Values.service.clusterIP }}" -{{- if .Values.service.externalIPs }} - externalIPs: -{{ toYaml .Values.service.externalIPs | indent 4 }} -{{- end }} -{{- if .Values.service.loadBalancerIP }} - loadBalancerIP: "{{ .Values.service.loadBalancerIP }}" -{{- end }} -{{- if .Values.service.loadBalancerSourceRanges }} - loadBalancerSourceRanges: -{{ toYaml .Values.service.loadBalancerSourceRanges | indent 4 }} -{{- end }} - ports: - - name: http - port: {{ .Values.service.port }} - protocol: TCP - targetPort: http - {{- if (and (eq .Values.service.type "NodePort") (not (empty .Values.service.nodePort))) }} - nodePort: {{ .Values.service.nodePort }} - {{- end }} - selector: - app: {{ template "nginx.name" . }} - release: {{ .Release.Name }} diff --git a/docs.helm.sh/rootfs/public/examples/nginx/values.yaml b/docs.helm.sh/rootfs/public/examples/nginx/values.yaml deleted file mode 100644 index b40208ccec..0000000000 --- a/docs.helm.sh/rootfs/public/examples/nginx/values.yaml +++ /dev/null @@ -1,34 +0,0 @@ -# Default values for nginx. -# This is a YAML-formatted file. -# Declare name/value pairs to be passed into your templates. - -replicaCount: 1 -restartPolicy: Never - -# Evaluated by the post-install hook -sleepyTime: "10" - -index: >- -

Hello

-

This is a test

- -image: - repository: nginx - tag: 1.11.0 - pullPolicy: IfNotPresent - -service: - annotations: {} - clusterIP: "" - externalIPs: [] - loadBalancerIP: "" - loadBalancerSourceRanges: [] - type: ClusterIP - port: 8888 - nodePort: "" - -podAnnotations: {} - -resources: {} - -nodeSelector: {} diff --git a/docs.helm.sh/rootfs/public/examples/readme/index.html b/docs.helm.sh/rootfs/public/examples/readme/index.html deleted file mode 100644 index 4bc568c5b3..0000000000 --- a/docs.helm.sh/rootfs/public/examples/readme/index.html +++ /dev/null @@ -1,1342 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

Helm Examples

- -

This directory contains example charts to help you get started with -chart development.

- -

Alpine

- -

The alpine chart is very simple, and is a good starting point.

- -

It simply deploys a single pod running Alpine Linux.

- -

Nginx

- -

The nginx chart shows how to compose several resources into one chart, -and it illustrates more complex template usage.

- -

It deploys a deployment (which creates a replica set), a config -map, and a service. The replica set starts an nginx pod. The config -map stores the files that the nginx server can serve.

- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/glossary/index.html b/docs.helm.sh/rootfs/public/glossary/index.html deleted file mode 100644 index 7ef312586a..0000000000 --- a/docs.helm.sh/rootfs/public/glossary/index.html +++ /dev/null @@ -1,1519 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

Helm Glossary

- -

Helm uses a few special terms to describe components of the -architecture.

- -

Chart

- -

A Helm package that contains information sufficient for installing a set -of Kubernetes resources into a Kubernetes cluster.

- -

Charts contain a Chart.yaml file as well as templates, default values -(values.yaml), and dependencies.

- -

Charts are developed in a well-defined directory structure, and then -packaged into an archive format called a chart archive.

- -

Chart Archive

- -

A chart archive is a tarred and gzipped (and optionally signed) chart.

- -

Chart Dependency (Subcharts)

- -

Charts may depend upon other charts. There are two ways a dependency may -occur:

- -
    -
  • Soft dependency: A chart may simply not function without another chart -being installed in a cluster. Helm does not provide tooling for this -case. In this case, dependencies may be managed separately.
  • -
  • Hard dependency: A chart may contain (inside of its charts/ -directory) another chart upon which it depends. In this case, -installing the chart will install all of its dependencies. In this -case, a chart and its dependencies are managed as a collection.
  • -
- -

When a chart is packaged (via helm package) all of its hard dependencies -are bundled with it.

- -

Chart Version

- -

Charts are versioned according to the SemVer 2 -spec. A version number is required on every chart.

- -

Chart.yaml

- -

Information about a chart is stored in a special file called -Chart.yaml. Every chart must have this file.

- -

Helm (and helm)

- -

Helm is the package manager for Kubernetes. As an operating system -package manager makes it easy to install tools on an OS, Helm makes it -easy to install applications and resources into Kubernetes clusters.

- -

While Helm is the name of the project, the command line client is also -named helm. By convention, when speaking of the project, Helm is -capitalized. When speaking of the client, helm is in lowercase.

- -

Helm Home (HELM_HOME)

- -

The Helm client stores information in a local directory referred to as -helm home. By default, this is in the $HOME/.helm directory.

- -

This directory contains configuration and cache data, and is created by -helm init.

- -

Kube Config (KUBECONFIG)

- -

The Helm client learns about Kubernetes clusters by using files in the Kube -config file format. By default, Helm attempts to find this file in the -place where kubectl creates it ($HOME/.kube/config).

- -

Lint (Linting)

- -

To lint a chart is to validate that it follows the conventions and -requirements of the Helm chart standard. Helm provides tools to do this, -notably the helm lint command.

- -

Provenance (Provenance file)

- -

Helm charts may be accompanied by a provenance file which provides -information about where the chart came from and what it contains.

- -

Provenance files are one part of the Helm security story. A provenance contains -a cryptographic hash of the chart archive file, the Chart.yaml data, and -a signature block (an OpenPGP “clearsign” block). When coupled with a -keychain, this provides chart users with the ability to:

- -
    -
  • Validate that a chart was signed by a trusted party
  • -
  • Validate that the chart file has not been tampered with
  • -
  • Validate the contents of a chart metadata (Chart.yaml)
  • -
  • Quickly match a chart to its provenance data
  • -
- -

Provenance files have the .prov extension, and can be served from a -chart repository server or any other HTTP server.

- -

Release

- -

When a chart is installed, Tiller (the Helm server) creates a release -to track that installation.

- -

A single chart may be installed many times into the same cluster, and -create many different releases. For example, one can install three -PostgreSQL databases by running helm install three times with a -different release name.

- -

(Prior to 2.0.0-Alpha.1, releases were called deployments. But this -caused confusion with the Kubernetes Deployment kind.)

- -

Release Number (Release Version)

- -

A single release can be updated multiple times. A sequential counter is -used to track releases as they change. After a first helm install, a -release will have release number 1. Each time a release is upgraded or -rolled back, the release number will be incremented.

- -

Rollback

- -

A release can be upgraded to a newer chart or configuration. But since -release history is stored, a release can also be rolled back to a -previous release number. This is done with the helm rollback command.

- -

Importantly, a rolled back release will receive a new release number.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OperationRelease Number
installrelease 1
upgraderelease 2
upgraderelease 3
rollback 1release 4 (but running the same config as release 1)
- -

The above table illustrates how release numbers increment across -install, upgrade, and rollback.

- -

Tiller

- -

Tiller is the in-cluster component of Helm. It interacts directly with -the Kubernetes API server to install, upgrade, query, and remove -Kubernetes resources. It also stores the objects that represent -releases.

- -

Repository (Repo, Chart Repository)

- -

Helm charts may be stored on dedicated HTTP servers called chart -repositories (repositories, or just repos).

- -

A chart repository server is a simple HTTP server that can serve an -index.yaml file that describes a batch of charts, and provides -information on where each chart can be downloaded from. (Many chart -repositories serve the charts as well as the index.yaml file.)

- -

A Helm client can point to zero or more chart repositories. By default, -Helm clients point to the stable official Kubernetes chart -repository.

- -

Values (Values Files, values.yaml)

- -

Values provide a way to override template defaults with your own -information.

- -

Helm Charts are “parameterized”, which means the chart developer may -expose configuration that can be overridden at installation time. For -example, a chart may expose a username field that allows setting a -user name for a service.

- -

These exposed variables are called values in Helm parlance.

- -

Values can be set during helm install and helm upgrade operations, -either by passing them in directly, or by uploading a values.yaml -file.

- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm/index.html b/docs.helm.sh/rootfs/public/helm/helm/index.html deleted file mode 100644 index c4f23bfa57..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm/index.html +++ /dev/null @@ -1,1396 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm

- -

The Helm package manager for Kubernetes.

- -

Synopsis

- -

The Kubernetes package manager

- -

To begin working with Helm, run the ‘helm init’ command:

- -
$ helm init
-
- -

This will install Tiller to your running Kubernetes cluster. -It will also set up any necessary local configuration.

- -

Common actions from this point include:

- -
    -
  • helm search: search for charts
  • -
  • helm fetch: download a chart to your local directory to view
  • -
  • helm install: upload the chart to Kubernetes
  • -
  • helm list: list releases of charts
  • -
- -

Environment: - $HELM_HOME set an alternative location for Helm files. By default, these are stored in ~/.helm - $HELM_HOST set an alternative Tiller host. The format is host:port - $HELM_NO_PLUGINS disable plugins. Set HELM_NO_PLUGINS=1 to disable plugins. - $TILLER_NAMESPACE set an alternative Tiller namespace (default “kube-system”) - $KUBECONFIG set an alternative Kubernetes configuration file (default “~/.kube/config”)

- -

Options

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- - - -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_completion/index.html b/docs.helm.sh/rootfs/public/helm/helm_completion/index.html deleted file mode 100644 index 8f735a7804..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_completion/index.html +++ /dev/null @@ -1,1360 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm completion

- -

Generate autocompletions script for the specified shell (bash or zsh)

- -

Synopsis

- -

Generate autocompletions script for Helm for the specified shell (bash or zsh).

- -

This command can generate shell autocompletions. e.g.

- -
$ helm completion bash
-
- -

Can be sourced as such

- -
$ source <(helm completion bash)
-
- -
helm completion SHELL
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm - The Helm package manager for Kubernetes.
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_create/index.html b/docs.helm.sh/rootfs/public/helm/helm_create/index.html deleted file mode 100644 index 9b42c02099..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_create/index.html +++ /dev/null @@ -1,1377 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm create

- -

create a new chart with the given name

- -

Synopsis

- -

This command creates a chart directory along with the common files and -directories used in a chart.

- -

For example, ‘helm create foo’ will create a directory structure that looks -something like this:

- -
foo/
-  |
-  |- .helmignore   # Contains patterns to ignore when packaging Helm charts.
-  |
-  |- Chart.yaml    # Information about your chart
-  |
-  |- values.yaml   # The default values for your templates
-  |
-  |- charts/       # Charts that this chart depends on
-  |
-  |- templates/    # The template files
-
- -

‘helm create’ takes a path for an argument. If directories in the given path -do not exist, Helm will attempt to create them as it goes. If the given -destination exists and there are files in that directory, conflicting files -will be overwritten, but other files will be left alone.

- -
helm create NAME
-
- -

Options

- -
  -p, --starter string   the named Helm starter scaffold
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm - The Helm package manager for Kubernetes.
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_delete/index.html b/docs.helm.sh/rootfs/public/helm/helm_delete/index.html deleted file mode 100644 index c1c13d1324..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_delete/index.html +++ /dev/null @@ -1,1367 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm delete

- -

given a release name, delete the release from Kubernetes

- -

Synopsis

- -

This command takes a release name, and then deletes the release from Kubernetes. -It removes all of the resources associated with the last release of the chart.

- -

Use the ‘–dry-run’ flag to see which releases will be deleted without actually -deleting them.

- -
helm delete [flags] RELEASE_NAME [...]
-
- -

Options

- -
      --dry-run              simulate a delete
-      --no-hooks             prevent hooks from running during deletion
-      --purge                remove the release from the store and make its name free for later use
-      --timeout int          time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks) (default 300)
-      --tls                  enable TLS for request
-      --tls-ca-cert string   path to TLS CA certificate file (default "$HELM_HOME/ca.pem")
-      --tls-cert string      path to TLS certificate file (default "$HELM_HOME/cert.pem")
-      --tls-key string       path to TLS key file (default "$HELM_HOME/key.pem")
-      --tls-verify           enable TLS for request and verify remote
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm - The Helm package manager for Kubernetes.
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_dependency/index.html b/docs.helm.sh/rootfs/public/helm/helm_dependency/index.html deleted file mode 100644 index 2c248a81e8..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_dependency/index.html +++ /dev/null @@ -1,1397 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm dependency

- -

manage a chart’s dependencies

- -

Synopsis

- -

Manage the dependencies of a chart.

- -

Helm charts store their dependencies in ‘charts/’. For chart developers, it is -often easier to manage a single dependency file (‘requirements.yaml’) -which declares all dependencies.

- -

The dependency commands operate on that file, making it easy to synchronize -between the desired dependencies and the actual dependencies stored in the -‘charts/’ directory.

- -

A ‘requirements.yaml’ file is a YAML file in which developers can declare chart -dependencies, along with the location of the chart and the desired version. -For example, this requirements file declares two dependencies:

- -
# requirements.yaml
-dependencies:
-- name: nginx
-  version: "1.2.3"
-  repository: "https://example.com/charts"
-- name: memcached
-  version: "3.2.1"
-  repository: "https://another.example.com/charts"
-
- -

The ‘name’ should be the name of a chart, where that name must match the name -in that chart’s ‘Chart.yaml’ file.

- -

The ‘version’ field should contain a semantic version or version range.

- -

The ‘repository’ URL should point to a Chart Repository. Helm expects that by -appending ‘/index.yaml’ to the URL, it should be able to retrieve the chart -repository’s index. Note: ‘repository’ can be an alias. The alias must start -with ‘alias:’ or ‘@’.

- -

Starting from 2.2.0, repository can be defined as the path to the directory of -the dependency charts stored locally. The path should start with a prefix of -“file://“. For example,

- -
# requirements.yaml
-dependencies:
-- name: nginx
-  version: "1.2.3"
-  repository: "file://../dependency_chart/nginx"
-
- -

If the dependency chart is retrieved locally, it is not required to have the -repository added to helm by “helm add repo”. Version matching is also supported -for this case.

- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- - - -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_dependency_build/index.html b/docs.helm.sh/rootfs/public/helm/helm_dependency_build/index.html deleted file mode 100644 index 35f34f481b..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_dependency_build/index.html +++ /dev/null @@ -1,1363 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm dependency build

- -

rebuild the charts/ directory based on the requirements.lock file

- -

Synopsis

- -

Build out the charts/ directory from the requirements.lock file.

- -

Build is used to reconstruct a chart’s dependencies to the state specified in -the lock file. This will not re-negotiate dependencies, as ‘helm dependency update’ -does.

- -

If no lock file is found, ‘helm dependency build’ will mirror the behavior -of ‘helm dependency update’.

- -
helm dependency build [flags] CHART
-
- -

Options

- -
      --keyring string   keyring containing public keys (default "~/.gnupg/pubring.gpg")
-      --verify           verify the packages against signatures
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- - - -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_dependency_list/index.html b/docs.helm.sh/rootfs/public/helm/helm_dependency_list/index.html deleted file mode 100644 index 0d2bbcb5fe..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_dependency_list/index.html +++ /dev/null @@ -1,1356 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm dependency list

- -

list the dependencies for the given chart

- -

Synopsis

- -

List all of the dependencies declared in a chart.

- -

This can take chart archives and chart directories as input. It will not alter -the contents of a chart.

- -

This will produce an error if the chart cannot be loaded. It will emit a warning -if it cannot find a requirements.yaml.

- -
helm dependency list [flags] CHART
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- - - -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_dependency_update/index.html b/docs.helm.sh/rootfs/public/helm/helm_dependency_update/index.html deleted file mode 100644 index 97dd879e04..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_dependency_update/index.html +++ /dev/null @@ -1,1368 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm dependency update

- -

update charts/ based on the contents of requirements.yaml

- -

Synopsis

- -

Update the on-disk dependencies to mirror the requirements.yaml file.

- -

This command verifies that the required charts, as expressed in ‘requirements.yaml’, -are present in ‘charts/’ and are at an acceptable version. It will pull down -the latest charts that satisfy the dependencies, and clean up old dependencies.

- -

On successful update, this will generate a lock file that can be used to -rebuild the requirements to an exact version.

- -

Dependencies are not required to be represented in ‘requirements.yaml’. For that -reason, an update command will not remove charts unless they are (a) present -in the requirements.yaml file, but (b) at the wrong version.

- -
helm dependency update [flags] CHART
-
- -

Options

- -
      --keyring string   keyring containing public keys (default "~/.gnupg/pubring.gpg")
-      --skip-refresh     do not refresh the local repository cache
-      --verify           verify the packages against signatures
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- - - -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_fetch/index.html b/docs.helm.sh/rootfs/public/helm/helm_fetch/index.html deleted file mode 100644 index c617e622ff..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_fetch/index.html +++ /dev/null @@ -1,1377 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm fetch

- -

download a chart from a repository and (optionally) unpack it in local directory

- -

Synopsis

- -

Retrieve a package from a package repository, and download it locally.

- -

This is useful for fetching packages to inspect, modify, or repackage. It can -also be used to perform cryptographic verification of a chart without installing -the chart.

- -

There are options for unpacking the chart after download. This will create a -directory for the chart and uncompress into that directory.

- -

If the –verify flag is specified, the requested chart MUST have a provenance -file, and MUST pass the verification process. Failure in any part of this will -result in an error, and the chart will not be saved locally.

- -
helm fetch [flags] [chart URL | repo/chartname] [...]
-
- -

Options

- -
      --ca-file string       verify certificates of HTTPS-enabled servers using this CA bundle
-      --cert-file string     identify HTTPS client using this SSL certificate file
-  -d, --destination string   location to write the chart. If this and tardir are specified, tardir is appended to this (default ".")
-      --devel                use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored.
-      --key-file string      identify HTTPS client using this SSL key file
-      --keyring string       keyring containing public keys (default "~/.gnupg/pubring.gpg")
-      --prov                 fetch the provenance file, but don't perform verification
-      --repo string          chart repository url where to locate the requested chart
-      --untar                if set to true, will untar the chart after downloading it
-      --untardir string      if untar is specified, this flag specifies the name of the directory into which the chart is expanded (default ".")
-      --verify               verify the package against its signature
-      --version string       specific version of a chart. Without this, the latest version is fetched
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm - The Helm package manager for Kubernetes.
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_get/index.html b/docs.helm.sh/rootfs/public/helm/helm_get/index.html deleted file mode 100644 index 823ced66ca..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_get/index.html +++ /dev/null @@ -1,1374 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm get

- -

download a named release

- -

Synopsis

- -

This command shows the details of a named release.

- -

It can be used to get extended information about the release, including:

- -
    -
  • The values used to generate the release
  • -
  • The chart used to generate the release
  • -
  • The generated manifest file
  • -
- -

By default, this prints a human readable collection of information about the -chart, the supplied values, and the generated manifest file.

- -
helm get [flags] RELEASE_NAME
-
- -

Options

- -
      --revision int32       get the named release with revision
-      --tls                  enable TLS for request
-      --tls-ca-cert string   path to TLS CA certificate file (default "$HELM_HOME/ca.pem")
-      --tls-cert string      path to TLS certificate file (default "$HELM_HOME/cert.pem")
-      --tls-key string       path to TLS key file (default "$HELM_HOME/key.pem")
-      --tls-verify           enable TLS for request and verify remote
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- - - -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_get_hooks/index.html b/docs.helm.sh/rootfs/public/helm/helm_get_hooks/index.html deleted file mode 100644 index f353c7ce8b..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_get_hooks/index.html +++ /dev/null @@ -1,1362 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm get hooks

- -

download all hooks for a named release

- -

Synopsis

- -

This command downloads hooks for a given release.

- -

Hooks are formatted in YAML and separated by the YAML ‘—\n’ separator.

- -
helm get hooks [flags] RELEASE_NAME
-
- -

Options

- -
      --revision int32       get the named release with revision
-      --tls                  enable TLS for request
-      --tls-ca-cert string   path to TLS CA certificate file (default "$HELM_HOME/ca.pem")
-      --tls-cert string      path to TLS certificate file (default "$HELM_HOME/cert.pem")
-      --tls-key string       path to TLS key file (default "$HELM_HOME/key.pem")
-      --tls-verify           enable TLS for request and verify remote
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- - - -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_get_manifest/index.html b/docs.helm.sh/rootfs/public/helm/helm_get_manifest/index.html deleted file mode 100644 index c4cf274508..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_get_manifest/index.html +++ /dev/null @@ -1,1364 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm get manifest

- -

download the manifest for a named release

- -

Synopsis

- -

This command fetches the generated manifest for a given release.

- -

A manifest is a YAML-encoded representation of the Kubernetes resources that -were generated from this release’s chart(s). If a chart is dependent on other -charts, those resources will also be included in the manifest.

- -
helm get manifest [flags] RELEASE_NAME
-
- -

Options

- -
      --revision int32       get the named release with revision
-      --tls                  enable TLS for request
-      --tls-ca-cert string   path to TLS CA certificate file (default "$HELM_HOME/ca.pem")
-      --tls-cert string      path to TLS certificate file (default "$HELM_HOME/cert.pem")
-      --tls-key string       path to TLS key file (default "$HELM_HOME/key.pem")
-      --tls-verify           enable TLS for request and verify remote
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- - - -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_get_values/index.html b/docs.helm.sh/rootfs/public/helm/helm_get_values/index.html deleted file mode 100644 index ad5cf215e7..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_get_values/index.html +++ /dev/null @@ -1,1361 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm get values

- -

download the values file for a named release

- -

Synopsis

- -

This command downloads a values file for a given release.

- -
helm get values [flags] RELEASE_NAME
-
- -

Options

- -
  -a, --all                  dump all (computed) values
-      --revision int32       get the named release with revision
-      --tls                  enable TLS for request
-      --tls-ca-cert string   path to TLS CA certificate file (default "$HELM_HOME/ca.pem")
-      --tls-cert string      path to TLS certificate file (default "$HELM_HOME/cert.pem")
-      --tls-key string       path to TLS key file (default "$HELM_HOME/key.pem")
-      --tls-verify           enable TLS for request and verify remote
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- - - -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_history/index.html b/docs.helm.sh/rootfs/public/helm/helm_history/index.html deleted file mode 100644 index a3dff1dd5f..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_history/index.html +++ /dev/null @@ -1,1374 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm history

- -

fetch release history

- -

Synopsis

- -

History prints historical revisions for a given release.

- -

A default maximum of 256 revisions will be returned. Setting ‘–max’ -configures the maximum length of the revision list returned.

- -

The historical release set is printed as a formatted table, e.g:

- -
$ helm history angry-bird --max=4
-REVISION   UPDATED                      STATUS           CHART        DESCRIPTION
-1           Mon Oct 3 10:15:13 2016     SUPERSEDED      alpine-0.1.0  Initial install
-2           Mon Oct 3 10:15:13 2016     SUPERSEDED      alpine-0.1.0  Upgraded successfully
-3           Mon Oct 3 10:15:13 2016     SUPERSEDED      alpine-0.1.0  Rolled back to 2
-4           Mon Oct 3 10:15:13 2016     DEPLOYED        alpine-0.1.0  Upgraded successfully
-
- -
helm history [flags] RELEASE_NAME
-
- -

Options

- -
      --col-width uint       specifies the max column width of output (default 60)
-      --max int32            maximum number of revision to include in history (default 256)
-      --tls                  enable TLS for request
-      --tls-ca-cert string   path to TLS CA certificate file (default "$HELM_HOME/ca.pem")
-      --tls-cert string      path to TLS certificate file (default "$HELM_HOME/cert.pem")
-      --tls-key string       path to TLS key file (default "$HELM_HOME/key.pem")
-      --tls-verify           enable TLS for request and verify remote
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm - The Helm package manager for Kubernetes.
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_home/index.html b/docs.helm.sh/rootfs/public/helm/helm_home/index.html deleted file mode 100644 index ac0552448c..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_home/index.html +++ /dev/null @@ -1,1351 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm home

- -

displays the location of HELM_HOME

- -

Synopsis

- -

This command displays the location of HELM_HOME. This is where -any helm configuration files live.

- -
helm home
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm - The Helm package manager for Kubernetes.
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_init/index.html b/docs.helm.sh/rootfs/public/helm/helm_init/index.html deleted file mode 100644 index f2b8662141..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_init/index.html +++ /dev/null @@ -1,1392 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm init

- -

initialize Helm on both client and server

- -

Synopsis

- -

This command installs Tiller (the Helm server-side component) onto your -Kubernetes Cluster and sets up local configuration in $HELM_HOME (default ~/.helm/).

- -

As with the rest of the Helm commands, ‘helm init’ discovers Kubernetes clusters -by reading $KUBECONFIG (default ‘~/.kube/config’) and using the default context.

- -

To set up just a local environment, use ‘–client-only’. That will configure -$HELM_HOME, but not attempt to connect to a Kubernetes cluster and install the Tiller -deployment.

- -

When installing Tiller, ‘helm init’ will attempt to install the latest released -version. You can specify an alternative image with ‘–tiller-image’. For those -frequently working on the latest code, the flag ‘–canary-image’ will install -the latest pre-release version of Tiller (e.g. the HEAD commit in the GitHub -repository on the master branch).

- -

To dump a manifest containing the Tiller deployment YAML, combine the -‘–dry-run’ and ‘–debug’ flags.

- -
helm init
-
- -

Options

- -
      --canary-image             use the canary Tiller image
-  -c, --client-only              if set does not install Tiller
-      --dry-run                  do not install local or remote
-      --force-upgrade            force upgrade of Tiller to the current helm version
-      --history-max int          limit the maximum number of revisions saved per release. Use 0 for no limit.
-      --local-repo-url string    URL for local repository (default "http://127.0.0.1:8879/charts")
-      --net-host                 install Tiller with net=host
-      --node-selectors string    labels to specify the node on which Tiller is installed (app=tiller,helm=rocks)
-  -o, --output OutputFormat      skip installation and output Tiller's manifest in specified format (json or yaml)
-      --override stringArray     override values for the Tiller Deployment manifest (can specify multiple or separate values with commas: key1=val1,key2=val2)
-      --service-account string   name of service account
-      --skip-refresh             do not refresh (download) the local repository cache
-      --stable-repo-url string   URL for stable repository (default "https://kubernetes-charts.storage.googleapis.com")
-  -i, --tiller-image string      override Tiller image
-      --tiller-tls               install Tiller with TLS enabled
-      --tiller-tls-cert string   path to TLS certificate file to install with Tiller
-      --tiller-tls-key string    path to TLS key file to install with Tiller
-      --tiller-tls-verify        install Tiller with TLS enabled and to verify remote certificates
-      --tls-ca-cert string       path to CA root certificate
-      --upgrade                  upgrade if Tiller is already installed
-      --wait                     block until Tiller is running and ready to receive requests
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm - The Helm package manager for Kubernetes.
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_inspect/index.html b/docs.helm.sh/rootfs/public/helm/helm_inspect/index.html deleted file mode 100644 index f449985ef8..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_inspect/index.html +++ /dev/null @@ -1,1366 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm inspect

- -

inspect a chart

- -

Synopsis

- -

This command inspects a chart and displays information. It takes a chart reference -(‘stable/drupal’), a full path to a directory or packaged chart, or a URL.

- -

Inspect prints the contents of the Chart.yaml file and the values.yaml file.

- -
helm inspect [CHART]
-
- -

Options

- -
      --ca-file string     chart repository url where to locate the requested chart
-      --cert-file string   verify certificates of HTTPS-enabled servers using this CA bundle
-      --key-file string    identify HTTPS client using this SSL key file
-      --keyring string     path to the keyring containing public verification keys (default "~/.gnupg/pubring.gpg")
-      --repo string        chart repository url where to locate the requested chart
-      --verify             verify the provenance data for this chart
-      --version string     version of the chart. By default, the newest chart is shown
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- - - -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_inspect_chart/index.html b/docs.helm.sh/rootfs/public/helm/helm_inspect_chart/index.html deleted file mode 100644 index 8188d77606..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_inspect_chart/index.html +++ /dev/null @@ -1,1362 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm inspect chart

- -

shows inspect chart

- -

Synopsis

- -

This command inspects a chart (directory, file, or URL) and displays the contents -of the Charts.yaml file

- -
helm inspect chart [CHART]
-
- -

Options

- -
      --ca-file string     chart repository url where to locate the requested chart
-      --cert-file string   verify certificates of HTTPS-enabled servers using this CA bundle
-      --key-file string    identify HTTPS client using this SSL key file
-      --keyring string     path to the keyring containing public verification keys (default "~/.gnupg/pubring.gpg")
-      --repo string        chart repository url where to locate the requested chart
-      --verify             verify the provenance data for this chart
-      --version string     version of the chart. By default, the newest chart is shown
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- - - -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_inspect_values/index.html b/docs.helm.sh/rootfs/public/helm/helm_inspect_values/index.html deleted file mode 100644 index c6f7f074a7..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_inspect_values/index.html +++ /dev/null @@ -1,1362 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm inspect values

- -

shows inspect values

- -

Synopsis

- -

This command inspects a chart (directory, file, or URL) and displays the contents -of the values.yaml file

- -
helm inspect values [CHART]
-
- -

Options

- -
      --ca-file string     chart repository url where to locate the requested chart
-      --cert-file string   verify certificates of HTTPS-enabled servers using this CA bundle
-      --key-file string    identify HTTPS client using this SSL key file
-      --keyring string     path to the keyring containing public verification keys (default "~/.gnupg/pubring.gpg")
-      --repo string        chart repository url where to locate the requested chart
-      --verify             verify the provenance data for this chart
-      --version string     version of the chart. By default, the newest chart is shown
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- - - -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_install/index.html b/docs.helm.sh/rootfs/public/helm/helm_install/index.html deleted file mode 100644 index bf1e6c0b5b..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_install/index.html +++ /dev/null @@ -1,1436 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm install

- -

install a chart archive

- -

Synopsis

- -

This command installs a chart archive.

- -

The install argument must be a chart reference, a path to a packaged chart, -a path to an unpacked chart directory or a URL.

- -

To override values in a chart, use either the ‘–values’ flag and pass in a file -or use the ‘–set’ flag and pass configuration from the command line.

- -
$ helm install -f myvalues.yaml ./redis
-
- -

or

- -
$ helm install --set name=prod ./redis
-
- -

You can specify the ‘–values’/‘-f’ flag multiple times. The priority will be given to the -last (right-most) file specified. For example, if both myvalues.yaml and override.yaml -contained a key called ‘Test’, the value set in override.yaml would take precedence:

- -
$ helm install -f myvalues.yaml -f override.yaml ./redis
-
- -

You can specify the ‘–set’ flag multiple times. The priority will be given to the -last (right-most) set specified. For example, if both ‘bar’ and ‘newbar’ values are -set for a key called ‘foo’, the ‘newbar’ value would take precedence:

- -
$ helm install --set foo=bar --set foo=newbar ./redis
-
- -

To check the generated manifests of a release without installing the chart, -the ‘–debug’ and ‘–dry-run’ flags can be combined. This will still require a -round-trip to the Tiller server.

- -

If –verify is set, the chart MUST have a provenance file, and the provenance -file MUST pass all verification steps.

- -

There are five different ways you can express the chart you want to install:

- -
    -
  1. By chart reference: helm install stable/mariadb
  2. -
  3. By path to a packaged chart: helm install ./nginx-1.2.3.tgz
  4. -
  5. By path to an unpacked chart directory: helm install ./nginx
  6. -
  7. By absolute URL: helm install https://example.com/charts/nginx-1.2.3.tgz
  8. -
  9. By chart reference and repo url: helm install –repo https://example.com/charts/ nginx
  10. -
- -

CHART REFERENCES

- -

A chart reference is a convenient way of reference a chart in a chart repository.

- -

When you use a chart reference with a repo prefix (‘stable/mariadb’), Helm will look in the local -configuration for a chart repository named ‘stable’, and will then look for a -chart in that repository whose name is ‘mariadb’. It will install the latest -version of that chart unless you also supply a version number with the -‘–version’ flag.

- -

To see the list of chart repositories, use ‘helm repo list’. To search for -charts in a repository, use ‘helm search’.

- -
helm install [CHART]
-
- -

Options

- -
      --ca-file string         verify certificates of HTTPS-enabled servers using this CA bundle
-      --cert-file string       identify HTTPS client using this SSL certificate file
-      --dep-up                 run helm dependency update before installing the chart
-      --devel                  use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored.
-      --dry-run                simulate an install
-      --key-file string        identify HTTPS client using this SSL key file
-      --keyring string         location of public keys used for verification (default "~/.gnupg/pubring.gpg")
-  -n, --name string            release name. If unspecified, it will autogenerate one for you
-      --name-template string   specify template used to name the release
-      --namespace string       namespace to install the release into. Defaults to the current kube config namespace.
-      --no-hooks               prevent hooks from running during install
-      --replace                re-use the given name, even if that name is already used. This is unsafe in production
-      --repo string            chart repository url where to locate the requested chart
-      --set stringArray        set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
-      --timeout int            time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks) (default 300)
-      --tls                    enable TLS for request
-      --tls-ca-cert string     path to TLS CA certificate file (default "$HELM_HOME/ca.pem")
-      --tls-cert string        path to TLS certificate file (default "$HELM_HOME/cert.pem")
-      --tls-key string         path to TLS key file (default "$HELM_HOME/key.pem")
-      --tls-verify             enable TLS for request and verify remote
-  -f, --values valueFiles      specify values in a YAML file or a URL(can specify multiple) (default [])
-      --verify                 verify the package before installing it
-      --version string         specify the exact chart version to install. If this is not specified, the latest version is installed
-      --wait                   if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment are in a ready state before marking the release as successful. It will wait for as long as --timeout
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm - The Helm package manager for Kubernetes.
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_lint/index.html b/docs.helm.sh/rootfs/public/helm/helm_lint/index.html deleted file mode 100644 index fdba8a0aa8..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_lint/index.html +++ /dev/null @@ -1,1363 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm lint

- -

examines a chart for possible issues

- -

Synopsis

- -

This command takes a path to a chart and runs a series of tests to verify that -the chart is well-formed.

- -

If the linter encounters things that will cause the chart to fail installation, -it will emit [ERROR] messages. If it encounters issues that break with convention -or recommendation, it will emit [WARNING] messages.

- -
helm lint [flags] PATH
-
- -

Options

- -
      --namespace string    namespace to install the release into (only used if --install is set) (default "default")
-      --set stringArray     set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
-      --strict              fail on lint warnings
-  -f, --values valueFiles   specify values in a YAML file (can specify multiple) (default [])
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm - The Helm package manager for Kubernetes.
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_list/index.html b/docs.helm.sh/rootfs/public/helm/helm_list/index.html deleted file mode 100644 index 69f08de0ea..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_list/index.html +++ /dev/null @@ -1,1396 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm list

- -

list releases

- -

Synopsis

- -

This command lists all of the releases.

- -

By default, it lists only releases that are deployed or failed. Flags like -‘–deleted’ and ‘–all’ will alter this behavior. Such flags can be combined: -‘–deleted –failed’.

- -

By default, items are sorted alphabetically. Use the ‘-d’ flag to sort by -release date.

- -

If an argument is provided, it will be treated as a filter. Filters are -regular expressions (Perl compatible) that are applied to the list of releases. -Only items that match the filter will be returned.

- -
$ helm list 'ara[a-z]+'
-NAME                UPDATED                     CHART
-maudlin-arachnid    Mon May  9 16:07:08 2016    alpine-0.1.0
-
- -

If no results are found, ‘helm list’ will exit 0, but with no output (or in -the case of no ‘-q’ flag, only headers).

- -

By default, up to 256 items may be returned. To limit this, use the ‘–max’ flag. -Setting ‘–max’ to 0 will not return all results. Rather, it will return the -server’s default, which may be much higher than 256. Pairing the ‘–max’ -flag with the ‘–offset’ flag allows you to page through results.

- -
helm list [flags] [FILTER]
-
- -

Options

- -
  -a, --all                  show all releases, not just the ones marked DEPLOYED
-      --col-width uint       specifies the max column width of output (default 60)
-  -d, --date                 sort by release date
-      --deleted              show deleted releases
-      --deleting             show releases that are currently being deleted
-      --deployed             show deployed releases. If no other is specified, this will be automatically enabled
-      --failed               show failed releases
-  -m, --max int              maximum number of releases to fetch (default 256)
-      --namespace string     show releases within a specific namespace
-  -o, --offset string        next release name in the list, used to offset from start value
-      --pending              show pending releases
-  -r, --reverse              reverse the sort order
-  -q, --short                output short (quiet) listing format
-      --tls                  enable TLS for request
-      --tls-ca-cert string   path to TLS CA certificate file (default "$HELM_HOME/ca.pem")
-      --tls-cert string      path to TLS certificate file (default "$HELM_HOME/cert.pem")
-      --tls-key string       path to TLS key file (default "$HELM_HOME/key.pem")
-      --tls-verify           enable TLS for request and verify remote
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm - The Helm package manager for Kubernetes.
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_package/index.html b/docs.helm.sh/rootfs/public/helm/helm_package/index.html deleted file mode 100644 index efd8dc2f9a..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_package/index.html +++ /dev/null @@ -1,1369 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm package

- -

package a chart directory into a chart archive

- -

Synopsis

- -

This command packages a chart into a versioned chart archive file. If a path -is given, this will look at that path for a chart (which must contain a -Chart.yaml file) and then package that directory.

- -

If no path is given, this will look in the present working directory for a -Chart.yaml file, and (if found) build the current directory into a chart.

- -

Versioned chart archives are used by Helm package repositories.

- -
helm package [flags] [CHART_PATH] [...]
-
- -

Options

- -
      --app-version string   set the appVersion on the chart to this version
-  -u, --dependency-update    update dependencies from "requirements.yaml" to dir "charts/" before packaging
-  -d, --destination string   location to write the chart. (default ".")
-      --key string           name of the key to use when signing. Used if --sign is true
-      --keyring string       location of a public keyring (default "~/.gnupg/pubring.gpg")
-      --save                 save packaged chart to local chart repository (default true)
-      --sign                 use a PGP private key to sign this package
-      --version string       set the version on the chart to this semver version
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm - The Helm package manager for Kubernetes.
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_plugin/index.html b/docs.helm.sh/rootfs/public/helm/helm_plugin/index.html deleted file mode 100644 index f2378a145b..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_plugin/index.html +++ /dev/null @@ -1,1351 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm plugin

- -

add, list, or remove Helm plugins

- -

Synopsis

- -

Manage client-side Helm plugins.

- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- - - -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_plugin_install/index.html b/docs.helm.sh/rootfs/public/helm/helm_plugin_install/index.html deleted file mode 100644 index 34fd1d2b5d..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_plugin_install/index.html +++ /dev/null @@ -1,1358 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm plugin install

- -

install one or more Helm plugins

- -

Synopsis

- -

This command allows you to install a plugin from a url to a VCS repo or a local path.

- -

Example usage: - $ helm plugin install https://github.com/technosophos/helm-template

- -
helm plugin install [options] <path|url>...
-
- -

Options

- -
      --version string   specify a version constraint. If this is not specified, the latest version is installed
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- - - -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_plugin_list/index.html b/docs.helm.sh/rootfs/public/helm/helm_plugin_list/index.html deleted file mode 100644 index ebfa6732b3..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_plugin_list/index.html +++ /dev/null @@ -1,1350 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm plugin list

- -

list installed Helm plugins

- -

Synopsis

- -

list installed Helm plugins

- -
helm plugin list
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- - - -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_plugin_remove/index.html b/docs.helm.sh/rootfs/public/helm/helm_plugin_remove/index.html deleted file mode 100644 index 24c2a62761..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_plugin_remove/index.html +++ /dev/null @@ -1,1350 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm plugin remove

- -

remove one or more Helm plugins

- -

Synopsis

- -

remove one or more Helm plugins

- -
helm plugin remove <plugin>...
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- - - -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_plugin_update/index.html b/docs.helm.sh/rootfs/public/helm/helm_plugin_update/index.html deleted file mode 100644 index 93a237e97b..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_plugin_update/index.html +++ /dev/null @@ -1,1350 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm plugin update

- -

update one or more Helm plugins

- -

Synopsis

- -

update one or more Helm plugins

- -
helm plugin update <plugin>...
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- - - -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_repo/index.html b/docs.helm.sh/rootfs/public/helm/helm_repo/index.html deleted file mode 100644 index c414ae707b..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_repo/index.html +++ /dev/null @@ -1,1356 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm repo

- -

add, list, remove, update, and index chart repositories

- -

Synopsis

- -

This command consists of multiple subcommands to interact with chart repositories.

- -

It can be used to add, remove, list, and index chart repositories. -Example usage: - $ helm repo add [NAME] [REPO_URL]

- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- - - -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_repo_add/index.html b/docs.helm.sh/rootfs/public/helm/helm_repo_add/index.html deleted file mode 100644 index 3f77d91245..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_repo_add/index.html +++ /dev/null @@ -1,1358 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm repo add

- -

add a chart repository

- -

Synopsis

- -

add a chart repository

- -
helm repo add [flags] [NAME] [URL]
-
- -

Options

- -
      --ca-file string     verify certificates of HTTPS-enabled servers using this CA bundle
-      --cert-file string   identify HTTPS client using this SSL certificate file
-      --key-file string    identify HTTPS client using this SSL key file
-      --no-update          raise error if repo is already registered
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm repo - add, list, remove, update, and index chart repositories
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_repo_index/index.html b/docs.helm.sh/rootfs/public/helm/helm_repo_index/index.html deleted file mode 100644 index c1ff257c47..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_repo_index/index.html +++ /dev/null @@ -1,1363 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm repo index

- -

generate an index file given a directory containing packaged charts

- -

Synopsis

- -

Read the current directory and generate an index file based on the charts found.

- -

This tool is used for creating an ‘index.yaml’ file for a chart repository. To -set an absolute URL to the charts, use ‘–url’ flag.

- -

To merge the generated index with an existing index file, use the ‘–merge’ -flag. In this case, the charts found in the current directory will be merged -into the existing index, with local charts taking priority over existing charts.

- -
helm repo index [flags] [DIR]
-
- -

Options

- -
      --merge string   merge the generated index into the given index
-      --url string     url of chart repository
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm repo - add, list, remove, update, and index chart repositories
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_repo_list/index.html b/docs.helm.sh/rootfs/public/helm/helm_repo_list/index.html deleted file mode 100644 index 669d3bb507..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_repo_list/index.html +++ /dev/null @@ -1,1350 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm repo list

- -

list chart repositories

- -

Synopsis

- -

list chart repositories

- -
helm repo list [flags]
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm repo - add, list, remove, update, and index chart repositories
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_repo_remove/index.html b/docs.helm.sh/rootfs/public/helm/helm_repo_remove/index.html deleted file mode 100644 index 0486fb9d73..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_repo_remove/index.html +++ /dev/null @@ -1,1350 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm repo remove

- -

remove a chart repository

- -

Synopsis

- -

remove a chart repository

- -
helm repo remove [flags] [NAME]
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm repo - add, list, remove, update, and index chart repositories
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_repo_update/index.html b/docs.helm.sh/rootfs/public/helm/helm_repo_update/index.html deleted file mode 100644 index 75e8903888..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_repo_update/index.html +++ /dev/null @@ -1,1354 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm repo update

- -

update information of available charts locally from chart repositories

- -

Synopsis

- -

Update gets the latest information about charts from the respective chart repositories. -Information is cached locally, where it is used by commands like ‘helm search’.

- -

‘helm update’ is the deprecated form of ‘helm repo update’. It will be removed in -future releases.

- -
helm repo update
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm repo - add, list, remove, update, and index chart repositories
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_reset/index.html b/docs.helm.sh/rootfs/public/helm/helm_reset/index.html deleted file mode 100644 index dbc382b555..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_reset/index.html +++ /dev/null @@ -1,1363 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm reset

- -

uninstalls Tiller from a cluster

- -

Synopsis

- -

This command uninstalls Tiller (the Helm server-side component) from your -Kubernetes Cluster and optionally deletes local configuration in -$HELM_HOME (default ~/.helm/)

- -
helm reset
-
- -

Options

- -
  -f, --force                forces Tiller uninstall even if there are releases installed, or if Tiller is not in ready state
-      --remove-helm-home     if set deletes $HELM_HOME
-      --tls                  enable TLS for request
-      --tls-ca-cert string   path to TLS CA certificate file (default "$HELM_HOME/ca.pem")
-      --tls-cert string      path to TLS certificate file (default "$HELM_HOME/cert.pem")
-      --tls-key string       path to TLS key file (default "$HELM_HOME/key.pem")
-      --tls-verify           enable TLS for request and verify remote
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm - The Helm package manager for Kubernetes.
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_rollback/index.html b/docs.helm.sh/rootfs/public/helm/helm_rollback/index.html deleted file mode 100644 index 91eb10c99c..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_rollback/index.html +++ /dev/null @@ -1,1369 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm rollback

- -

roll back a release to a previous revision

- -

Synopsis

- -

This command rolls back a release to a previous revision.

- -

The first argument of the rollback command is the name of a release, and the -second is a revision (version) number. To see revision numbers, run -‘helm history RELEASE’.

- -
helm rollback [flags] [RELEASE] [REVISION]
-
- -

Options

- -
      --dry-run              simulate a rollback
-      --force                force resource update through delete/recreate if needed
-      --no-hooks             prevent hooks from running during rollback
-      --recreate-pods        performs pods restart for the resource if applicable
-      --timeout int          time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks) (default 300)
-      --tls                  enable TLS for request
-      --tls-ca-cert string   path to TLS CA certificate file (default "$HELM_HOME/ca.pem")
-      --tls-cert string      path to TLS certificate file (default "$HELM_HOME/cert.pem")
-      --tls-key string       path to TLS key file (default "$HELM_HOME/key.pem")
-      --tls-verify           enable TLS for request and verify remote
-      --wait                 if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment are in a ready state before marking the release as successful. It will wait for as long as --timeout
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm - The Helm package manager for Kubernetes.
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_search/index.html b/docs.helm.sh/rootfs/public/helm/helm_search/index.html deleted file mode 100644 index ddb05c4eea..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_search/index.html +++ /dev/null @@ -1,1360 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - - - -

search for a keyword in charts

- -

Synopsis

- -

Search reads through all of the repositories configured on the system, and -looks for matches.

- -

Repositories are managed with ‘helm repo’ commands.

- -
helm search [keyword]
-
- -

Options

- -
  -r, --regexp           use regular expressions for searching
-  -v, --version string   search using semantic versioning constraints
-  -l, --versions         show the long listing, with each version of each chart on its own line
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm - The Helm package manager for Kubernetes.
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_serve/index.html b/docs.helm.sh/rootfs/public/helm/helm_serve/index.html deleted file mode 100644 index b34fe0888a..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_serve/index.html +++ /dev/null @@ -1,1368 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm serve

- -

start a local http web server

- -

Synopsis

- -

This command starts a local chart repository server that serves charts from a local directory.

- -

The new server will provide HTTP access to a repository. By default, it will -scan all of the charts in ‘$HELM_HOME/repository/local’ and serve those over -the local IPv4 TCP port (default ‘127.0.0.1:8879’).

- -

This command is intended to be used for educational and testing purposes only. -It is best to rely on a dedicated web server or a cloud-hosted solution like -Google Cloud Storage for production use.

- -

See https://github.com/kubernetes/helm/blob/master/docs/developing_charts.md#hosting-chart-repositories -for more information on hosting chart repositories in a production setting.

- -
helm serve
-
- -

Options

- -
      --address string     address to listen on (default "127.0.0.1:8879")
-      --repo-path string   local directory path from which to serve charts
-      --url string         external URL of chart repository
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm - The Helm package manager for Kubernetes.
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_status/index.html b/docs.helm.sh/rootfs/public/helm/helm_status/index.html deleted file mode 100644 index 14cdf79b3d..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_status/index.html +++ /dev/null @@ -1,1368 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm status

- -

displays the status of the named release

- -

Synopsis

- -

This command shows the status of a named release. -The status consists of: -- last deployment time -- k8s namespace in which the release lives -- state of the release (can be: UNKNOWN, DEPLOYED, DELETED, SUPERSEDED, FAILED or DELETING) -- list of resources that this release consists of, sorted by kind -- details on last test suite run, if applicable -- additional notes provided by the chart

- -
helm status [flags] RELEASE_NAME
-
- -

Options

- -
  -o, --output string        output the status in the specified format (json or yaml)
-      --revision int32       if set, display the status of the named release with revision
-      --tls                  enable TLS for request
-      --tls-ca-cert string   path to TLS CA certificate file (default "$HELM_HOME/ca.pem")
-      --tls-cert string      path to TLS certificate file (default "$HELM_HOME/cert.pem")
-      --tls-key string       path to TLS key file (default "$HELM_HOME/key.pem")
-      --tls-verify           enable TLS for request and verify remote
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm - The Helm package manager for Kubernetes.
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_template/index.html b/docs.helm.sh/rootfs/public/helm/helm_template/index.html deleted file mode 100644 index be53150263..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_template/index.html +++ /dev/null @@ -1,1373 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm template

- -

locally render templates

- -

Synopsis

- -

Render chart templates locally and display the output.

- -

This does not require Tiller. However, any values that would normally be -looked up or retrieved in-cluster will be faked locally. Additionally, none -of the server-side testing of chart validity (e.g. whether an API is supported) -is done.

- -

To render just one template in a chart, use ‘-x’:

- -
$ helm template mychart -x templates/deployment.yaml
-
- -
helm template [flags] CHART
-
- -

Options

- -
  -x, --execute stringArray    only execute the given templates
-      --kube-version string    kubernetes version used as Capabilities.KubeVersion.Major/Minor (default "1.9")
-  -n, --name string            release name (default "RELEASE-NAME")
-      --name-template string   specify template used to name the release
-      --namespace string       namespace to install the release into
-      --notes                  show the computed NOTES.txt file as well
-      --output-dir string      writes the executed templates to files in output-dir instead of stdout
-      --set stringArray        set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
-  -f, --values valueFiles      specify values in a YAML file (can specify multiple) (default [])
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm - The Helm package manager for Kubernetes.
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_test/index.html b/docs.helm.sh/rootfs/public/helm/helm_test/index.html deleted file mode 100644 index e01b09d2a7..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_test/index.html +++ /dev/null @@ -1,1364 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm test

- -

test a release

- -

Synopsis

- -

The test command runs the tests for a release.

- -

The argument this command takes is the name of a deployed release. -The tests to be run are defined in the chart that was installed.

- -
helm test [RELEASE]
-
- -

Options

- -
      --cleanup              delete test pods upon completion
-      --timeout int          time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks) (default 300)
-      --tls                  enable TLS for request
-      --tls-ca-cert string   path to TLS CA certificate file (default "$HELM_HOME/ca.pem")
-      --tls-cert string      path to TLS certificate file (default "$HELM_HOME/cert.pem")
-      --tls-key string       path to TLS key file (default "$HELM_HOME/key.pem")
-      --tls-verify           enable TLS for request and verify remote
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm - The Helm package manager for Kubernetes.
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_upgrade/index.html b/docs.helm.sh/rootfs/public/helm/helm_upgrade/index.html deleted file mode 100644 index 6ee6bd3711..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_upgrade/index.html +++ /dev/null @@ -1,1401 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm upgrade

- -

upgrade a release

- -

Synopsis

- -

This command upgrades a release to a new version of a chart.

- -

The upgrade arguments must be a release and chart. The chart -argument can be either: a chart reference(‘stable/mariadb’), a path to a chart directory, -a packaged chart, or a fully qualified URL. For chart references, the latest -version will be specified unless the ‘–version’ flag is set.

- -

To override values in a chart, use either the ‘–values’ flag and pass in a file -or use the ‘–set’ flag and pass configuration from the command line.

- -

You can specify the ‘–values’/‘-f’ flag multiple times. The priority will be given to the -last (right-most) file specified. For example, if both myvalues.yaml and override.yaml -contained a key called ‘Test’, the value set in override.yaml would take precedence:

- -
$ helm upgrade -f myvalues.yaml -f override.yaml redis ./redis
-
- -

You can specify the ‘–set’ flag multiple times. The priority will be given to the -last (right-most) set specified. For example, if both ‘bar’ and ‘newbar’ values are -set for a key called ‘foo’, the ‘newbar’ value would take precedence:

- -
$ helm upgrade --set foo=bar --set foo=newbar redis ./redis
-
- -
helm upgrade [RELEASE] [CHART]
-
- -

Options

- -
      --ca-file string       verify certificates of HTTPS-enabled servers using this CA bundle
-      --cert-file string     identify HTTPS client using this SSL certificate file
-      --devel                use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored.
-      --dry-run              simulate an upgrade
-      --force                force resource update through delete/recreate if needed
-  -i, --install              if a release by this name doesn't already exist, run an install
-      --key-file string      identify HTTPS client using this SSL key file
-      --keyring string       path to the keyring that contains public signing keys (default "~/.gnupg/pubring.gpg")
-      --namespace string     namespace to install the release into (only used if --install is set). Defaults to the current kube config namespace
-      --no-hooks             disable pre/post upgrade hooks
-      --recreate-pods        performs pods restart for the resource if applicable
-      --repo string          chart repository url where to locate the requested chart
-      --reset-values         when upgrading, reset the values to the ones built into the chart
-      --reuse-values         when upgrading, reuse the last release's values, and merge in any new values. If '--reset-values' is specified, this is ignored.
-      --set stringArray      set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
-      --timeout int          time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks) (default 300)
-      --tls                  enable TLS for request
-      --tls-ca-cert string   path to TLS CA certificate file (default "$HELM_HOME/ca.pem")
-      --tls-cert string      path to TLS certificate file (default "$HELM_HOME/cert.pem")
-      --tls-key string       path to TLS key file (default "$HELM_HOME/key.pem")
-      --tls-verify           enable TLS for request and verify remote
-  -f, --values valueFiles    specify values in a YAML file or a URL(can specify multiple) (default [])
-      --verify               verify the provenance of the chart before upgrading
-      --version string       specify the exact chart version to use. If this is not specified, the latest version is used
-      --wait                 if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment are in a ready state before marking the release as successful. It will wait for as long as --timeout
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm - The Helm package manager for Kubernetes.
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_verify/index.html b/docs.helm.sh/rootfs/public/helm/helm_verify/index.html deleted file mode 100644 index 50633f6854..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_verify/index.html +++ /dev/null @@ -1,1362 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm verify

- -

verify that a chart at the given path has been signed and is valid

- -

Synopsis

- -

Verify that the given chart has a valid provenance file.

- -

Provenance files provide crytographic verification that a chart has not been -tampered with, and was packaged by a trusted provider.

- -

This command can be used to verify a local chart. Several other commands provide -‘–verify’ flags that run the same validation. To generate a signed package, use -the ‘helm package –sign’ command.

- -
helm verify [flags] PATH
-
- -

Options

- -
      --keyring string   keyring containing public keys (default "~/.gnupg/pubring.gpg")
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm - The Helm package manager for Kubernetes.
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/helm_version/index.html b/docs.helm.sh/rootfs/public/helm/helm_version/index.html deleted file mode 100644 index b0c3e73ebb..0000000000 --- a/docs.helm.sh/rootfs/public/helm/helm_version/index.html +++ /dev/null @@ -1,1379 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

helm version

- -

print the client/server version information

- -

Synopsis

- -

Show the client and server versions for Helm and tiller.

- -

This will print a representation of the client and server versions of Helm and -Tiller. The output will look something like this:

- -

Client: &version.Version{SemVer:“v2.0.0”, GitCommit:“ff52399e51bb880526e9cd0ed8386f6433b74da1”, GitTreeState:“clean”} -Server: &version.Version{SemVer:“v2.0.0”, GitCommit:“b0c113dfb9f612a9add796549da66c0d294508a3”, GitTreeState:“clean”}

- -
    -
  • SemVer is the semantic version of the release.
  • -
  • GitCommit is the SHA for the commit that this version was built from.
  • -
  • GitTreeState is “clean” if there are no local code changes when this binary was -built, and “dirty” if the binary was built from locally modified code.
  • -
- -

To print just the client version, use ‘–client’. To print just the server version, -use ‘–server’.

- -
helm version
-
- -

Options

- -
  -c, --client               client version only
-  -s, --server               server version only
-      --short                print the version number
-      --template string      template for version string format
-      --tls                  enable TLS for request
-      --tls-ca-cert string   path to TLS CA certificate file (default "$HELM_HOME/ca.pem")
-      --tls-cert string      path to TLS certificate file (default "$HELM_HOME/cert.pem")
-      --tls-key string       path to TLS key file (default "$HELM_HOME/key.pem")
-      --tls-verify           enable TLS for request and verify remote
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm - The Helm package manager for Kubernetes.
  • -
- -
Auto generated by spf13/cobra on 11-Feb-2018
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/index.html b/docs.helm.sh/rootfs/public/helm/index.html deleted file mode 100644 index 051f59a13b..0000000000 --- a/docs.helm.sh/rootfs/public/helm/index.html +++ /dev/null @@ -1,3573 +0,0 @@ - - - - - - - - - Helm - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
- -
-
- -

helm

- -

The Helm package manager for Kubernetes.

- -

Synopsis

- -

The Kubernetes package manager

- -

To begin working with Helm, run the ‘helm init’ command:

- -
$ helm init
-
- -

This will install Tiller to your running Kubernetes cluster. -It will also set up any necessary local configuration.

- -

Common actions from this point include:

- -
    -
  • helm search: search for charts
  • -
  • helm fetch: download a chart to your local directory to view
  • -
  • helm install: upload the chart to Kubernetes
  • -
  • helm list: list releases of charts
  • -
- -

Environment: - $HELM_HOME set an alternative location for Helm files. By default, these are stored in ~/.helm - $HELM_HOST set an alternative Tiller host. The format is host:port - $HELM_NO_PLUGINS disable plugins. Set HELM_NO_PLUGINS=1 to disable plugins. - $TILLER_NAMESPACE set an alternative Tiller namespace (default “kube-system”) - $KUBECONFIG set an alternative Kubernetes configuration file (default “~/.kube/config”)

- -

Options

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- - - -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- -

helm completion

- -

Generate autocompletions script for the specified shell (bash or zsh)

- -

Synopsis

- -

Generate autocompletions script for Helm for the specified shell (bash or zsh).

- -

This command can generate shell autocompletions. e.g.

- -
$ helm completion bash
-
- -

Can be sourced as such

- -
$ source <(helm completion bash)
-
- -
helm completion SHELL
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm - The Helm package manager for Kubernetes.
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- -

helm create

- -

create a new chart with the given name

- -

Synopsis

- -

This command creates a chart directory along with the common files and -directories used in a chart.

- -

For example, ‘helm create foo’ will create a directory structure that looks -something like this:

- -
foo/
-  |
-  |- .helmignore   # Contains patterns to ignore when packaging Helm charts.
-  |
-  |- Chart.yaml    # Information about your chart
-  |
-  |- values.yaml   # The default values for your templates
-  |
-  |- charts/       # Charts that this chart depends on
-  |
-  |- templates/    # The template files
-
- -

‘helm create’ takes a path for an argument. If directories in the given path -do not exist, Helm will attempt to create them as it goes. If the given -destination exists and there are files in that directory, conflicting files -will be overwritten, but other files will be left alone.

- -
helm create NAME
-
- -

Options

- -
  -p, --starter string   the named Helm starter scaffold
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm - The Helm package manager for Kubernetes.
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- -

helm delete

- -

given a release name, delete the release from Kubernetes

- -

Synopsis

- -

This command takes a release name, and then deletes the release from Kubernetes. -It removes all of the resources associated with the last release of the chart.

- -

Use the ‘–dry-run’ flag to see which releases will be deleted without actually -deleting them.

- -
helm delete [flags] RELEASE_NAME [...]
-
- -

Options

- -
      --dry-run              simulate a delete
-      --no-hooks             prevent hooks from running during deletion
-      --purge                remove the release from the store and make its name free for later use
-      --timeout int          time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks) (default 300)
-      --tls                  enable TLS for request
-      --tls-ca-cert string   path to TLS CA certificate file (default "$HELM_HOME/ca.pem")
-      --tls-cert string      path to TLS certificate file (default "$HELM_HOME/cert.pem")
-      --tls-key string       path to TLS key file (default "$HELM_HOME/key.pem")
-      --tls-verify           enable TLS for request and verify remote
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm - The Helm package manager for Kubernetes.
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- -

helm dependency

- -

manage a chart’s dependencies

- -

Synopsis

- -

Manage the dependencies of a chart.

- -

Helm charts store their dependencies in ‘charts/’. For chart developers, it is -often easier to manage a single dependency file (‘requirements.yaml’) -which declares all dependencies.

- -

The dependency commands operate on that file, making it easy to synchronize -between the desired dependencies and the actual dependencies stored in the -‘charts/’ directory.

- -

A ‘requirements.yaml’ file is a YAML file in which developers can declare chart -dependencies, along with the location of the chart and the desired version. -For example, this requirements file declares two dependencies:

- -
# requirements.yaml
-dependencies:
-- name: nginx
-  version: "1.2.3"
-  repository: "https://example.com/charts"
-- name: memcached
-  version: "3.2.1"
-  repository: "https://another.example.com/charts"
-
- -

The ‘name’ should be the name of a chart, where that name must match the name -in that chart’s ‘Chart.yaml’ file.

- -

The ‘version’ field should contain a semantic version or version range.

- -

The ‘repository’ URL should point to a Chart Repository. Helm expects that by -appending ‘/index.yaml’ to the URL, it should be able to retrieve the chart -repository’s index. Note: ‘repository’ can be an alias. The alias must start -with ‘alias:’ or ‘@’.

- -

Starting from 2.2.0, repository can be defined as the path to the directory of -the dependency charts stored locally. The path should start with a prefix of -“file://“. For example,

- -
# requirements.yaml
-dependencies:
-- name: nginx
-  version: "1.2.3"
-  repository: "file://../dependency_chart/nginx"
-
- -

If the dependency chart is retrieved locally, it is not required to have the -repository added to helm by “helm add repo”. Version matching is also supported -for this case.

- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- - - -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- -

helm dependency build

- -

rebuild the charts/ directory based on the requirements.lock file

- -

Synopsis

- -

Build out the charts/ directory from the requirements.lock file.

- -

Build is used to reconstruct a chart’s dependencies to the state specified in -the lock file. This will not re-negotiate dependencies, as ‘helm dependency update’ -does.

- -

If no lock file is found, ‘helm dependency build’ will mirror the behavior -of ‘helm dependency update’.

- -
helm dependency build [flags] CHART
-
- -

Options

- -
      --keyring string   keyring containing public keys (default "~/.gnupg/pubring.gpg")
-      --verify           verify the packages against signatures
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- - - -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- -

helm dependency list

- -

list the dependencies for the given chart

- -

Synopsis

- -

List all of the dependencies declared in a chart.

- -

This can take chart archives and chart directories as input. It will not alter -the contents of a chart.

- -

This will produce an error if the chart cannot be loaded. It will emit a warning -if it cannot find a requirements.yaml.

- -
helm dependency list [flags] CHART
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- - - -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- -

helm dependency update

- -

update charts/ based on the contents of requirements.yaml

- -

Synopsis

- -

Update the on-disk dependencies to mirror the requirements.yaml file.

- -

This command verifies that the required charts, as expressed in ‘requirements.yaml’, -are present in ‘charts/’ and are at an acceptable version. It will pull down -the latest charts that satisfy the dependencies, and clean up old dependencies.

- -

On successful update, this will generate a lock file that can be used to -rebuild the requirements to an exact version.

- -

Dependencies are not required to be represented in ‘requirements.yaml’. For that -reason, an update command will not remove charts unless they are (a) present -in the requirements.yaml file, but (b) at the wrong version.

- -
helm dependency update [flags] CHART
-
- -

Options

- -
      --keyring string   keyring containing public keys (default "~/.gnupg/pubring.gpg")
-      --skip-refresh     do not refresh the local repository cache
-      --verify           verify the packages against signatures
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- - - -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- -

helm fetch

- -

download a chart from a repository and (optionally) unpack it in local directory

- -

Synopsis

- -

Retrieve a package from a package repository, and download it locally.

- -

This is useful for fetching packages to inspect, modify, or repackage. It can -also be used to perform cryptographic verification of a chart without installing -the chart.

- -

There are options for unpacking the chart after download. This will create a -directory for the chart and uncompress into that directory.

- -

If the –verify flag is specified, the requested chart MUST have a provenance -file, and MUST pass the verification process. Failure in any part of this will -result in an error, and the chart will not be saved locally.

- -
helm fetch [flags] [chart URL | repo/chartname] [...]
-
- -

Options

- -
      --ca-file string       verify certificates of HTTPS-enabled servers using this CA bundle
-      --cert-file string     identify HTTPS client using this SSL certificate file
-  -d, --destination string   location to write the chart. If this and tardir are specified, tardir is appended to this (default ".")
-      --devel                use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored.
-      --key-file string      identify HTTPS client using this SSL key file
-      --keyring string       keyring containing public keys (default "~/.gnupg/pubring.gpg")
-      --prov                 fetch the provenance file, but don't perform verification
-      --repo string          chart repository url where to locate the requested chart
-      --untar                if set to true, will untar the chart after downloading it
-      --untardir string      if untar is specified, this flag specifies the name of the directory into which the chart is expanded (default ".")
-      --verify               verify the package against its signature
-      --version string       specific version of a chart. Without this, the latest version is fetched
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm - The Helm package manager for Kubernetes.
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- -

helm get

- -

download a named release

- -

Synopsis

- -

This command shows the details of a named release.

- -

It can be used to get extended information about the release, including:

- -
    -
  • The values used to generate the release
  • -
  • The chart used to generate the release
  • -
  • The generated manifest file
  • -
- -

By default, this prints a human readable collection of information about the -chart, the supplied values, and the generated manifest file.

- -
helm get [flags] RELEASE_NAME
-
- -

Options

- -
      --revision int32       get the named release with revision
-      --tls                  enable TLS for request
-      --tls-ca-cert string   path to TLS CA certificate file (default "$HELM_HOME/ca.pem")
-      --tls-cert string      path to TLS certificate file (default "$HELM_HOME/cert.pem")
-      --tls-key string       path to TLS key file (default "$HELM_HOME/key.pem")
-      --tls-verify           enable TLS for request and verify remote
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- - - -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- -

helm get hooks

- -

download all hooks for a named release

- -

Synopsis

- -

This command downloads hooks for a given release.

- -

Hooks are formatted in YAML and separated by the YAML ‘—\n’ separator.

- -
helm get hooks [flags] RELEASE_NAME
-
- -

Options

- -
      --revision int32       get the named release with revision
-      --tls                  enable TLS for request
-      --tls-ca-cert string   path to TLS CA certificate file (default "$HELM_HOME/ca.pem")
-      --tls-cert string      path to TLS certificate file (default "$HELM_HOME/cert.pem")
-      --tls-key string       path to TLS key file (default "$HELM_HOME/key.pem")
-      --tls-verify           enable TLS for request and verify remote
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- - - -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- -

helm get manifest

- -

download the manifest for a named release

- -

Synopsis

- -

This command fetches the generated manifest for a given release.

- -

A manifest is a YAML-encoded representation of the Kubernetes resources that -were generated from this release’s chart(s). If a chart is dependent on other -charts, those resources will also be included in the manifest.

- -
helm get manifest [flags] RELEASE_NAME
-
- -

Options

- -
      --revision int32       get the named release with revision
-      --tls                  enable TLS for request
-      --tls-ca-cert string   path to TLS CA certificate file (default "$HELM_HOME/ca.pem")
-      --tls-cert string      path to TLS certificate file (default "$HELM_HOME/cert.pem")
-      --tls-key string       path to TLS key file (default "$HELM_HOME/key.pem")
-      --tls-verify           enable TLS for request and verify remote
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- - - -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- -

helm get values

- -

download the values file for a named release

- -

Synopsis

- -

This command downloads a values file for a given release.

- -
helm get values [flags] RELEASE_NAME
-
- -

Options

- -
  -a, --all                  dump all (computed) values
-      --revision int32       get the named release with revision
-      --tls                  enable TLS for request
-      --tls-ca-cert string   path to TLS CA certificate file (default "$HELM_HOME/ca.pem")
-      --tls-cert string      path to TLS certificate file (default "$HELM_HOME/cert.pem")
-      --tls-key string       path to TLS key file (default "$HELM_HOME/key.pem")
-      --tls-verify           enable TLS for request and verify remote
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- - - -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- -

helm history

- -

fetch release history

- -

Synopsis

- -

History prints historical revisions for a given release.

- -

A default maximum of 256 revisions will be returned. Setting ‘–max’ -configures the maximum length of the revision list returned.

- -

The historical release set is printed as a formatted table, e.g:

- -
$ helm history angry-bird --max=4
-REVISION   UPDATED                      STATUS           CHART        DESCRIPTION
-1           Mon Oct 3 10:15:13 2016     SUPERSEDED      alpine-0.1.0  Initial install
-2           Mon Oct 3 10:15:13 2016     SUPERSEDED      alpine-0.1.0  Upgraded successfully
-3           Mon Oct 3 10:15:13 2016     SUPERSEDED      alpine-0.1.0  Rolled back to 2
-4           Mon Oct 3 10:15:13 2016     DEPLOYED        alpine-0.1.0  Upgraded successfully
-
- -
helm history [flags] RELEASE_NAME
-
- -

Options

- -
      --col-width uint       specifies the max column width of output (default 60)
-      --max int32            maximum number of revision to include in history (default 256)
-      --tls                  enable TLS for request
-      --tls-ca-cert string   path to TLS CA certificate file (default "$HELM_HOME/ca.pem")
-      --tls-cert string      path to TLS certificate file (default "$HELM_HOME/cert.pem")
-      --tls-key string       path to TLS key file (default "$HELM_HOME/key.pem")
-      --tls-verify           enable TLS for request and verify remote
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm - The Helm package manager for Kubernetes.
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- -

helm home

- -

displays the location of HELM_HOME

- -

Synopsis

- -

This command displays the location of HELM_HOME. This is where -any helm configuration files live.

- -
helm home
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm - The Helm package manager for Kubernetes.
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- -

helm init

- -

initialize Helm on both client and server

- -

Synopsis

- -

This command installs Tiller (the Helm server-side component) onto your -Kubernetes Cluster and sets up local configuration in $HELM_HOME (default ~/.helm/).

- -

As with the rest of the Helm commands, ‘helm init’ discovers Kubernetes clusters -by reading $KUBECONFIG (default ‘~/.kube/config’) and using the default context.

- -

To set up just a local environment, use ‘–client-only’. That will configure -$HELM_HOME, but not attempt to connect to a Kubernetes cluster and install the Tiller -deployment.

- -

When installing Tiller, ‘helm init’ will attempt to install the latest released -version. You can specify an alternative image with ‘–tiller-image’. For those -frequently working on the latest code, the flag ‘–canary-image’ will install -the latest pre-release version of Tiller (e.g. the HEAD commit in the GitHub -repository on the master branch).

- -

To dump a manifest containing the Tiller deployment YAML, combine the -‘–dry-run’ and ‘–debug’ flags.

- -
helm init
-
- -

Options

- -
      --canary-image             use the canary Tiller image
-  -c, --client-only              if set does not install Tiller
-      --dry-run                  do not install local or remote
-      --force-upgrade            force upgrade of Tiller to the current helm version
-      --history-max int          limit the maximum number of revisions saved per release. Use 0 for no limit.
-      --local-repo-url string    URL for local repository (default "http://127.0.0.1:8879/charts")
-      --net-host                 install Tiller with net=host
-      --node-selectors string    labels to specify the node on which Tiller is installed (app=tiller,helm=rocks)
-  -o, --output OutputFormat      skip installation and output Tiller's manifest in specified format (json or yaml)
-      --override stringArray     override values for the Tiller Deployment manifest (can specify multiple or separate values with commas: key1=val1,key2=val2)
-      --service-account string   name of service account
-      --skip-refresh             do not refresh (download) the local repository cache
-      --stable-repo-url string   URL for stable repository (default "https://kubernetes-charts.storage.googleapis.com")
-  -i, --tiller-image string      override Tiller image
-      --tiller-tls               install Tiller with TLS enabled
-      --tiller-tls-cert string   path to TLS certificate file to install with Tiller
-      --tiller-tls-key string    path to TLS key file to install with Tiller
-      --tiller-tls-verify        install Tiller with TLS enabled and to verify remote certificates
-      --tls-ca-cert string       path to CA root certificate
-      --upgrade                  upgrade if Tiller is already installed
-      --wait                     block until Tiller is running and ready to receive requests
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm - The Helm package manager for Kubernetes.
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- -

helm inspect

- -

inspect a chart

- -

Synopsis

- -

This command inspects a chart and displays information. It takes a chart reference -(‘stable/drupal’), a full path to a directory or packaged chart, or a URL.

- -

Inspect prints the contents of the Chart.yaml file and the values.yaml file.

- -
helm inspect [CHART]
-
- -

Options

- -
      --ca-file string     chart repository url where to locate the requested chart
-      --cert-file string   verify certificates of HTTPS-enabled servers using this CA bundle
-      --key-file string    identify HTTPS client using this SSL key file
-      --keyring string     path to the keyring containing public verification keys (default "~/.gnupg/pubring.gpg")
-      --repo string        chart repository url where to locate the requested chart
-      --verify             verify the provenance data for this chart
-      --version string     version of the chart. By default, the newest chart is shown
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- - - -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- -

helm inspect chart

- -

shows inspect chart

- -

Synopsis

- -

This command inspects a chart (directory, file, or URL) and displays the contents -of the Charts.yaml file

- -
helm inspect chart [CHART]
-
- -

Options

- -
      --ca-file string     chart repository url where to locate the requested chart
-      --cert-file string   verify certificates of HTTPS-enabled servers using this CA bundle
-      --key-file string    identify HTTPS client using this SSL key file
-      --keyring string     path to the keyring containing public verification keys (default "~/.gnupg/pubring.gpg")
-      --repo string        chart repository url where to locate the requested chart
-      --verify             verify the provenance data for this chart
-      --version string     version of the chart. By default, the newest chart is shown
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- - - -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- -

helm inspect values

- -

shows inspect values

- -

Synopsis

- -

This command inspects a chart (directory, file, or URL) and displays the contents -of the values.yaml file

- -
helm inspect values [CHART]
-
- -

Options

- -
      --ca-file string     chart repository url where to locate the requested chart
-      --cert-file string   verify certificates of HTTPS-enabled servers using this CA bundle
-      --key-file string    identify HTTPS client using this SSL key file
-      --keyring string     path to the keyring containing public verification keys (default "~/.gnupg/pubring.gpg")
-      --repo string        chart repository url where to locate the requested chart
-      --verify             verify the provenance data for this chart
-      --version string     version of the chart. By default, the newest chart is shown
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- - - -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- -

helm install

- -

install a chart archive

- -

Synopsis

- -

This command installs a chart archive.

- -

The install argument must be a chart reference, a path to a packaged chart, -a path to an unpacked chart directory or a URL.

- -

To override values in a chart, use either the ‘–values’ flag and pass in a file -or use the ‘–set’ flag and pass configuration from the command line.

- -
$ helm install -f myvalues.yaml ./redis
-
- -

or

- -
$ helm install --set name=prod ./redis
-
- -

You can specify the ‘–values’/‘-f’ flag multiple times. The priority will be given to the -last (right-most) file specified. For example, if both myvalues.yaml and override.yaml -contained a key called ‘Test’, the value set in override.yaml would take precedence:

- -
$ helm install -f myvalues.yaml -f override.yaml ./redis
-
- -

You can specify the ‘–set’ flag multiple times. The priority will be given to the -last (right-most) set specified. For example, if both ‘bar’ and ‘newbar’ values are -set for a key called ‘foo’, the ‘newbar’ value would take precedence:

- -
$ helm install --set foo=bar --set foo=newbar ./redis
-
- -

To check the generated manifests of a release without installing the chart, -the ‘–debug’ and ‘–dry-run’ flags can be combined. This will still require a -round-trip to the Tiller server.

- -

If –verify is set, the chart MUST have a provenance file, and the provenance -file MUST pass all verification steps.

- -

There are five different ways you can express the chart you want to install:

- -
    -
  1. By chart reference: helm install stable/mariadb
  2. -
  3. By path to a packaged chart: helm install ./nginx-1.2.3.tgz
  4. -
  5. By path to an unpacked chart directory: helm install ./nginx
  6. -
  7. By absolute URL: helm install https://example.com/charts/nginx-1.2.3.tgz
  8. -
  9. By chart reference and repo url: helm install –repo https://example.com/charts/ nginx
  10. -
- -

CHART REFERENCES

- -

A chart reference is a convenient way of reference a chart in a chart repository.

- -

When you use a chart reference with a repo prefix (‘stable/mariadb’), Helm will look in the local -configuration for a chart repository named ‘stable’, and will then look for a -chart in that repository whose name is ‘mariadb’. It will install the latest -version of that chart unless you also supply a version number with the -‘–version’ flag.

- -

To see the list of chart repositories, use ‘helm repo list’. To search for -charts in a repository, use ‘helm search’.

- -
helm install [CHART]
-
- -

Options

- -
      --ca-file string         verify certificates of HTTPS-enabled servers using this CA bundle
-      --cert-file string       identify HTTPS client using this SSL certificate file
-      --dep-up                 run helm dependency update before installing the chart
-      --devel                  use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored.
-      --dry-run                simulate an install
-      --key-file string        identify HTTPS client using this SSL key file
-      --keyring string         location of public keys used for verification (default "~/.gnupg/pubring.gpg")
-  -n, --name string            release name. If unspecified, it will autogenerate one for you
-      --name-template string   specify template used to name the release
-      --namespace string       namespace to install the release into. Defaults to the current kube config namespace.
-      --no-hooks               prevent hooks from running during install
-      --replace                re-use the given name, even if that name is already used. This is unsafe in production
-      --repo string            chart repository url where to locate the requested chart
-      --set stringArray        set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
-      --timeout int            time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks) (default 300)
-      --tls                    enable TLS for request
-      --tls-ca-cert string     path to TLS CA certificate file (default "$HELM_HOME/ca.pem")
-      --tls-cert string        path to TLS certificate file (default "$HELM_HOME/cert.pem")
-      --tls-key string         path to TLS key file (default "$HELM_HOME/key.pem")
-      --tls-verify             enable TLS for request and verify remote
-  -f, --values valueFiles      specify values in a YAML file or a URL(can specify multiple) (default [])
-      --verify                 verify the package before installing it
-      --version string         specify the exact chart version to install. If this is not specified, the latest version is installed
-      --wait                   if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment are in a ready state before marking the release as successful. It will wait for as long as --timeout
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm - The Helm package manager for Kubernetes.
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- -

helm lint

- -

examines a chart for possible issues

- -

Synopsis

- -

This command takes a path to a chart and runs a series of tests to verify that -the chart is well-formed.

- -

If the linter encounters things that will cause the chart to fail installation, -it will emit [ERROR] messages. If it encounters issues that break with convention -or recommendation, it will emit [WARNING] messages.

- -
helm lint [flags] PATH
-
- -

Options

- -
      --namespace string    namespace to install the release into (only used if --install is set) (default "default")
-      --set stringArray     set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
-      --strict              fail on lint warnings
-  -f, --values valueFiles   specify values in a YAML file (can specify multiple) (default [])
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm - The Helm package manager for Kubernetes.
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- -

helm list

- -

list releases

- -

Synopsis

- -

This command lists all of the releases.

- -

By default, it lists only releases that are deployed or failed. Flags like -‘–deleted’ and ‘–all’ will alter this behavior. Such flags can be combined: -‘–deleted –failed’.

- -

By default, items are sorted alphabetically. Use the ‘-d’ flag to sort by -release date.

- -

If an argument is provided, it will be treated as a filter. Filters are -regular expressions (Perl compatible) that are applied to the list of releases. -Only items that match the filter will be returned.

- -
$ helm list 'ara[a-z]+'
-NAME                UPDATED                     CHART
-maudlin-arachnid    Mon May  9 16:07:08 2016    alpine-0.1.0
-
- -

If no results are found, ‘helm list’ will exit 0, but with no output (or in -the case of no ‘-q’ flag, only headers).

- -

By default, up to 256 items may be returned. To limit this, use the ‘–max’ flag. -Setting ‘–max’ to 0 will not return all results. Rather, it will return the -server’s default, which may be much higher than 256. Pairing the ‘–max’ -flag with the ‘–offset’ flag allows you to page through results.

- -
helm list [flags] [FILTER]
-
- -

Options

- -
  -a, --all                  show all releases, not just the ones marked DEPLOYED
-      --col-width uint       specifies the max column width of output (default 60)
-  -d, --date                 sort by release date
-      --deleted              show deleted releases
-      --deleting             show releases that are currently being deleted
-      --deployed             show deployed releases. If no other is specified, this will be automatically enabled
-      --failed               show failed releases
-  -m, --max int              maximum number of releases to fetch (default 256)
-      --namespace string     show releases within a specific namespace
-  -o, --offset string        next release name in the list, used to offset from start value
-      --pending              show pending releases
-  -r, --reverse              reverse the sort order
-  -q, --short                output short (quiet) listing format
-      --tls                  enable TLS for request
-      --tls-ca-cert string   path to TLS CA certificate file (default "$HELM_HOME/ca.pem")
-      --tls-cert string      path to TLS certificate file (default "$HELM_HOME/cert.pem")
-      --tls-key string       path to TLS key file (default "$HELM_HOME/key.pem")
-      --tls-verify           enable TLS for request and verify remote
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm - The Helm package manager for Kubernetes.
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- -

helm package

- -

package a chart directory into a chart archive

- -

Synopsis

- -

This command packages a chart into a versioned chart archive file. If a path -is given, this will look at that path for a chart (which must contain a -Chart.yaml file) and then package that directory.

- -

If no path is given, this will look in the present working directory for a -Chart.yaml file, and (if found) build the current directory into a chart.

- -

Versioned chart archives are used by Helm package repositories.

- -
helm package [flags] [CHART_PATH] [...]
-
- -

Options

- -
      --app-version string   set the appVersion on the chart to this version
-  -u, --dependency-update    update dependencies from "requirements.yaml" to dir "charts/" before packaging
-  -d, --destination string   location to write the chart. (default ".")
-      --key string           name of the key to use when signing. Used if --sign is true
-      --keyring string       location of a public keyring (default "~/.gnupg/pubring.gpg")
-      --save                 save packaged chart to local chart repository (default true)
-      --sign                 use a PGP private key to sign this package
-      --version string       set the version on the chart to this semver version
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm - The Helm package manager for Kubernetes.
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- -

helm plugin

- -

add, list, or remove Helm plugins

- -

Synopsis

- -

Manage client-side Helm plugins.

- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- - - -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- -

helm plugin install

- -

install one or more Helm plugins

- -

Synopsis

- -

This command allows you to install a plugin from a url to a VCS repo or a local path.

- -

Example usage: - $ helm plugin install https://github.com/technosophos/helm-template

- -
helm plugin install [options] <path|url>...
-
- -

Options

- -
      --version string   specify a version constraint. If this is not specified, the latest version is installed
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- - - -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- -

helm plugin list

- -

list installed Helm plugins

- -

Synopsis

- -

list installed Helm plugins

- -
helm plugin list
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- - - -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- -

helm plugin remove

- -

remove one or more Helm plugins

- -

Synopsis

- -

remove one or more Helm plugins

- -
helm plugin remove <plugin>...
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- - - -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- -

helm plugin update

- -

update one or more Helm plugins

- -

Synopsis

- -

update one or more Helm plugins

- -
helm plugin update <plugin>...
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- - - -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- -

helm repo

- -

add, list, remove, update, and index chart repositories

- -

Synopsis

- -

This command consists of multiple subcommands to interact with chart repositories.

- -

It can be used to add, remove, list, and index chart repositories. -Example usage: - $ helm repo add [NAME] [REPO_URL]

- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- - - -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- -

helm repo add

- -

add a chart repository

- -

Synopsis

- -

add a chart repository

- -
helm repo add [flags] [NAME] [URL]
-
- -

Options

- -
      --ca-file string     verify certificates of HTTPS-enabled servers using this CA bundle
-      --cert-file string   identify HTTPS client using this SSL certificate file
-      --key-file string    identify HTTPS client using this SSL key file
-      --no-update          raise error if repo is already registered
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm repo - add, list, remove, update, and index chart repositories
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- -

helm repo index

- -

generate an index file given a directory containing packaged charts

- -

Synopsis

- -

Read the current directory and generate an index file based on the charts found.

- -

This tool is used for creating an ‘index.yaml’ file for a chart repository. To -set an absolute URL to the charts, use ‘–url’ flag.

- -

To merge the generated index with an existing index file, use the ‘–merge’ -flag. In this case, the charts found in the current directory will be merged -into the existing index, with local charts taking priority over existing charts.

- -
helm repo index [flags] [DIR]
-
- -

Options

- -
      --merge string   merge the generated index into the given index
-      --url string     url of chart repository
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm repo - add, list, remove, update, and index chart repositories
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- -

helm repo list

- -

list chart repositories

- -

Synopsis

- -

list chart repositories

- -
helm repo list [flags]
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm repo - add, list, remove, update, and index chart repositories
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- -

helm repo remove

- -

remove a chart repository

- -

Synopsis

- -

remove a chart repository

- -
helm repo remove [flags] [NAME]
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm repo - add, list, remove, update, and index chart repositories
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- -

helm repo update

- -

update information of available charts locally from chart repositories

- -

Synopsis

- -

Update gets the latest information about charts from the respective chart repositories. -Information is cached locally, where it is used by commands like ‘helm search’.

- -

‘helm update’ is the deprecated form of ‘helm repo update’. It will be removed in -future releases.

- -
helm repo update
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm repo - add, list, remove, update, and index chart repositories
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- -

helm reset

- -

uninstalls Tiller from a cluster

- -

Synopsis

- -

This command uninstalls Tiller (the Helm server-side component) from your -Kubernetes Cluster and optionally deletes local configuration in -$HELM_HOME (default ~/.helm/)

- -
helm reset
-
- -

Options

- -
  -f, --force                forces Tiller uninstall even if there are releases installed, or if Tiller is not in ready state
-      --remove-helm-home     if set deletes $HELM_HOME
-      --tls                  enable TLS for request
-      --tls-ca-cert string   path to TLS CA certificate file (default "$HELM_HOME/ca.pem")
-      --tls-cert string      path to TLS certificate file (default "$HELM_HOME/cert.pem")
-      --tls-key string       path to TLS key file (default "$HELM_HOME/key.pem")
-      --tls-verify           enable TLS for request and verify remote
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm - The Helm package manager for Kubernetes.
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- -

helm rollback

- -

roll back a release to a previous revision

- -

Synopsis

- -

This command rolls back a release to a previous revision.

- -

The first argument of the rollback command is the name of a release, and the -second is a revision (version) number. To see revision numbers, run -‘helm history RELEASE’.

- -
helm rollback [flags] [RELEASE] [REVISION]
-
- -

Options

- -
      --dry-run              simulate a rollback
-      --force                force resource update through delete/recreate if needed
-      --no-hooks             prevent hooks from running during rollback
-      --recreate-pods        performs pods restart for the resource if applicable
-      --timeout int          time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks) (default 300)
-      --tls                  enable TLS for request
-      --tls-ca-cert string   path to TLS CA certificate file (default "$HELM_HOME/ca.pem")
-      --tls-cert string      path to TLS certificate file (default "$HELM_HOME/cert.pem")
-      --tls-key string       path to TLS key file (default "$HELM_HOME/key.pem")
-      --tls-verify           enable TLS for request and verify remote
-      --wait                 if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment are in a ready state before marking the release as successful. It will wait for as long as --timeout
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm - The Helm package manager for Kubernetes.
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- - - -

search for a keyword in charts

- -

Synopsis

- -

Search reads through all of the repositories configured on the system, and -looks for matches.

- -

Repositories are managed with ‘helm repo’ commands.

- -
helm search [keyword]
-
- -

Options

- -
  -r, --regexp           use regular expressions for searching
-  -v, --version string   search using semantic versioning constraints
-  -l, --versions         show the long listing, with each version of each chart on its own line
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm - The Helm package manager for Kubernetes.
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- -

helm serve

- -

start a local http web server

- -

Synopsis

- -

This command starts a local chart repository server that serves charts from a local directory.

- -

The new server will provide HTTP access to a repository. By default, it will -scan all of the charts in ‘$HELM_HOME/repository/local’ and serve those over -the local IPv4 TCP port (default ‘127.0.0.1:8879’).

- -

This command is intended to be used for educational and testing purposes only. -It is best to rely on a dedicated web server or a cloud-hosted solution like -Google Cloud Storage for production use.

- -

See https://github.com/kubernetes/helm/blob/master/docs/developing_charts.md#hosting-chart-repositories -for more information on hosting chart repositories in a production setting.

- -
helm serve
-
- -

Options

- -
      --address string     address to listen on (default "127.0.0.1:8879")
-      --repo-path string   local directory path from which to serve charts
-      --url string         external URL of chart repository
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm - The Helm package manager for Kubernetes.
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- -

helm status

- -

displays the status of the named release

- -

Synopsis

- -

This command shows the status of a named release. -The status consists of: -- last deployment time -- k8s namespace in which the release lives -- state of the release (can be: UNKNOWN, DEPLOYED, DELETED, SUPERSEDED, FAILED or DELETING) -- list of resources that this release consists of, sorted by kind -- details on last test suite run, if applicable -- additional notes provided by the chart

- -
helm status [flags] RELEASE_NAME
-
- -

Options

- -
  -o, --output string        output the status in the specified format (json or yaml)
-      --revision int32       if set, display the status of the named release with revision
-      --tls                  enable TLS for request
-      --tls-ca-cert string   path to TLS CA certificate file (default "$HELM_HOME/ca.pem")
-      --tls-cert string      path to TLS certificate file (default "$HELM_HOME/cert.pem")
-      --tls-key string       path to TLS key file (default "$HELM_HOME/key.pem")
-      --tls-verify           enable TLS for request and verify remote
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm - The Helm package manager for Kubernetes.
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- -

helm template

- -

locally render templates

- -

Synopsis

- -

Render chart templates locally and display the output.

- -

This does not require Tiller. However, any values that would normally be -looked up or retrieved in-cluster will be faked locally. Additionally, none -of the server-side testing of chart validity (e.g. whether an API is supported) -is done.

- -

To render just one template in a chart, use ‘-x’:

- -
$ helm template mychart -x templates/deployment.yaml
-
- -
helm template [flags] CHART
-
- -

Options

- -
  -x, --execute stringArray    only execute the given templates
-      --kube-version string    kubernetes version used as Capabilities.KubeVersion.Major/Minor (default "1.9")
-  -n, --name string            release name (default "RELEASE-NAME")
-      --name-template string   specify template used to name the release
-      --namespace string       namespace to install the release into
-      --notes                  show the computed NOTES.txt file as well
-      --output-dir string      writes the executed templates to files in output-dir instead of stdout
-      --set stringArray        set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
-  -f, --values valueFiles      specify values in a YAML file (can specify multiple) (default [])
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm - The Helm package manager for Kubernetes.
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- -

helm test

- -

test a release

- -

Synopsis

- -

The test command runs the tests for a release.

- -

The argument this command takes is the name of a deployed release. -The tests to be run are defined in the chart that was installed.

- -
helm test [RELEASE]
-
- -

Options

- -
      --cleanup              delete test pods upon completion
-      --timeout int          time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks) (default 300)
-      --tls                  enable TLS for request
-      --tls-ca-cert string   path to TLS CA certificate file (default "$HELM_HOME/ca.pem")
-      --tls-cert string      path to TLS certificate file (default "$HELM_HOME/cert.pem")
-      --tls-key string       path to TLS key file (default "$HELM_HOME/key.pem")
-      --tls-verify           enable TLS for request and verify remote
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm - The Helm package manager for Kubernetes.
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- -

helm upgrade

- -

upgrade a release

- -

Synopsis

- -

This command upgrades a release to a new version of a chart.

- -

The upgrade arguments must be a release and chart. The chart -argument can be either: a chart reference(‘stable/mariadb’), a path to a chart directory, -a packaged chart, or a fully qualified URL. For chart references, the latest -version will be specified unless the ‘–version’ flag is set.

- -

To override values in a chart, use either the ‘–values’ flag and pass in a file -or use the ‘–set’ flag and pass configuration from the command line.

- -

You can specify the ‘–values’/‘-f’ flag multiple times. The priority will be given to the -last (right-most) file specified. For example, if both myvalues.yaml and override.yaml -contained a key called ‘Test’, the value set in override.yaml would take precedence:

- -
$ helm upgrade -f myvalues.yaml -f override.yaml redis ./redis
-
- -

You can specify the ‘–set’ flag multiple times. The priority will be given to the -last (right-most) set specified. For example, if both ‘bar’ and ‘newbar’ values are -set for a key called ‘foo’, the ‘newbar’ value would take precedence:

- -
$ helm upgrade --set foo=bar --set foo=newbar redis ./redis
-
- -
helm upgrade [RELEASE] [CHART]
-
- -

Options

- -
      --ca-file string       verify certificates of HTTPS-enabled servers using this CA bundle
-      --cert-file string     identify HTTPS client using this SSL certificate file
-      --devel                use development versions, too. Equivalent to version '>0.0.0-0'. If --version is set, this is ignored.
-      --dry-run              simulate an upgrade
-      --force                force resource update through delete/recreate if needed
-  -i, --install              if a release by this name doesn't already exist, run an install
-      --key-file string      identify HTTPS client using this SSL key file
-      --keyring string       path to the keyring that contains public signing keys (default "~/.gnupg/pubring.gpg")
-      --namespace string     namespace to install the release into (only used if --install is set). Defaults to the current kube config namespace
-      --no-hooks             disable pre/post upgrade hooks
-      --recreate-pods        performs pods restart for the resource if applicable
-      --repo string          chart repository url where to locate the requested chart
-      --reset-values         when upgrading, reset the values to the ones built into the chart
-      --reuse-values         when upgrading, reuse the last release's values, and merge in any new values. If '--reset-values' is specified, this is ignored.
-      --set stringArray      set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
-      --timeout int          time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks) (default 300)
-      --tls                  enable TLS for request
-      --tls-ca-cert string   path to TLS CA certificate file (default "$HELM_HOME/ca.pem")
-      --tls-cert string      path to TLS certificate file (default "$HELM_HOME/cert.pem")
-      --tls-key string       path to TLS key file (default "$HELM_HOME/key.pem")
-      --tls-verify           enable TLS for request and verify remote
-  -f, --values valueFiles    specify values in a YAML file or a URL(can specify multiple) (default [])
-      --verify               verify the provenance of the chart before upgrading
-      --version string       specify the exact chart version to use. If this is not specified, the latest version is used
-      --wait                 if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment are in a ready state before marking the release as successful. It will wait for as long as --timeout
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm - The Helm package manager for Kubernetes.
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- -

helm verify

- -

verify that a chart at the given path has been signed and is valid

- -

Synopsis

- -

Verify that the given chart has a valid provenance file.

- -

Provenance files provide crytographic verification that a chart has not been -tampered with, and was packaged by a trusted provider.

- -

This command can be used to verify a local chart. Several other commands provide -‘–verify’ flags that run the same validation. To generate a signed package, use -the ‘helm package –sign’ command.

- -
helm verify [flags] PATH
-
- -

Options

- -
      --keyring string   keyring containing public keys (default "~/.gnupg/pubring.gpg")
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm - The Helm package manager for Kubernetes.
  • -
- -
Auto generated by spf13/cobra on 25-Jan-2018
-
-
- -
-
- -

helm version

- -

print the client/server version information

- -

Synopsis

- -

Show the client and server versions for Helm and tiller.

- -

This will print a representation of the client and server versions of Helm and -Tiller. The output will look something like this:

- -

Client: &version.Version{SemVer:“v2.0.0”, GitCommit:“ff52399e51bb880526e9cd0ed8386f6433b74da1”, GitTreeState:“clean”} -Server: &version.Version{SemVer:“v2.0.0”, GitCommit:“b0c113dfb9f612a9add796549da66c0d294508a3”, GitTreeState:“clean”}

- -
    -
  • SemVer is the semantic version of the release.
  • -
  • GitCommit is the SHA for the commit that this version was built from.
  • -
  • GitTreeState is “clean” if there are no local code changes when this binary was -built, and “dirty” if the binary was built from locally modified code.
  • -
- -

To print just the client version, use ‘–client’. To print just the server version, -use ‘–server’.

- -
helm version
-
- -

Options

- -
  -c, --client               client version only
-  -s, --server               server version only
-      --short                print the version number
-      --template string      template for version string format
-      --tls                  enable TLS for request
-      --tls-ca-cert string   path to TLS CA certificate file (default "$HELM_HOME/ca.pem")
-      --tls-cert string      path to TLS certificate file (default "$HELM_HOME/cert.pem")
-      --tls-key string       path to TLS key file (default "$HELM_HOME/key.pem")
-      --tls-verify           enable TLS for request and verify remote
-
- -

Options inherited from parent commands

- -
      --debug                     enable verbose output
-      --home string               location of your Helm config. Overrides $HELM_HOME (default "~/.helm")
-      --host string               address of Tiller. Overrides $HELM_HOST
-      --kube-context string       name of the kubeconfig context to use
-      --tiller-namespace string   namespace of Tiller (default "kube-system")
-
- -

SEE ALSO

- -
    -
  • helm - The Helm package manager for Kubernetes.
  • -
- -
Auto generated by spf13/cobra on 11-Feb-2018
-
-
- -
-
 
-
- -
-
-

- Helm is supported by and built with a community of over 250 developers. -

-

- helm.sh and docs.helm.sh are maintained by Microsoft -

-
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/helm/index.xml b/docs.helm.sh/rootfs/public/helm/index.xml deleted file mode 100644 index e0dfae082b..0000000000 --- a/docs.helm.sh/rootfs/public/helm/index.xml +++ /dev/null @@ -1,615 +0,0 @@ - - - - Helm - https://docs.helm.sh/helm/ - en-us - Mon, 01 Jan 0001 00:00:00 UTC - - - - https://docs.helm.sh/helm/helm/ - Mon, 01 Jan 0001 00:00:00 UTC - https://docs.helm.sh/helm/helm/ - - -<h2 id="helm">helm</h2> - -<p>The Helm package manager for Kubernetes.</p> - -<h3 id="synopsis">Synopsis</h3> - -<p>The Kubernetes package manager</p> - -<p>To begin working with Helm, run the &lsquo;helm init&rsquo; command:</p> - -<pre><code>$ helm init -</code></pre> - -<p>This will install Tiller to your running Kubernetes cluster. -It will also set up any necessary local configuration.</p> - -<p>Common actions from this point include:</p> - -<ul> -<li>helm search: search for charts</li> -<li>helm fetch: download a chart to your local directory to view</li> -<li>helm install: upload the chart to Kubernetes</li> -<li>helm list: list releases of charts</li> -</ul> - -<p>Environment: - $HELM_HOME set an alternative location for Helm files. By default, these are stored in ~/.helm - $HELM_HOST set an alternative Tiller host. The format is host:port - $HELM_NO_PLUGINS disable plugins. Set HELM_NO_PLUGINS=1 to disable plugins. - $TILLER_NAMESPACE set an alternative Tiller namespace (default &ldquo;kube-system&rdquo;) - $KUBECONFIG set an alternative Kubernetes configuration file (default &ldquo;~/.kube/config&rdquo;)</p> - -<h3 id="options">Options</h3> - -<pre><code> --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default &quot;~/.helm&quot;) - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default &quot;kube-system&quot;) -</code></pre> - -<h3 id="see-also">SEE ALSO</h3> - -<ul> -<li><a href="../../helm/#helm_completion">helm completion</a> - Generate autocompletions script for the specified shell (bash or zsh)</li> -<li><a href="../../helm/#helm_create">helm create</a> - create a new chart with the given name</li> -<li><a href="../../helm/#helm_delete">helm delete</a> - given a release name, delete the release from Kubernetes</li> -<li><a href="../../helm/#helm_dependency">helm dependency</a> - manage a chart&rsquo;s dependencies</li> -<li><a href="../../helm/#helm_fetch">helm fetch</a> - download a chart from a repository and (optionally) unpack it in local directory</li> -<li><a href="../../helm/#helm_get">helm get</a> - download a named release</li> -<li><a href="../../helm/#helm_history">helm history</a> - fetch release history</li> -<li><a href="../../helm/#helm_home">helm home</a> - displays the location of HELM_HOME</li> -<li><a href="../../helm/#helm_init">helm init</a> - initialize Helm on both client and server</li> -<li><a href="../../helm/#helm_inspect">helm inspect</a> - inspect a chart</li> -<li><a href="../../helm/#helm_install">helm install</a> - install a chart archive</li> -<li><a href="../../helm/#helm_lint">helm lint</a> - examines a chart for possible issues</li> -<li><a href="../../helm/#helm_list">helm list</a> - list releases</li> -<li><a href="../../helm/#helm_package">helm package</a> - package a chart directory into a chart archive</li> -<li><a href="../../helm/#helm_plugin">helm plugin</a> - add, list, or remove Helm plugins</li> -<li><a href="../../helm/#helm_repo">helm repo</a> - add, list, remove, update, and index chart repositories</li> -<li><a href="../../helm/#helm_reset">helm reset</a> - uninstalls Tiller from a cluster</li> -<li><a href="../../helm/#helm_rollback">helm rollback</a> - roll back a release to a previous revision</li> -<li><a href="../../helm/#helm_search">helm search</a> - search for a keyword in charts</li> -<li><a href="../../helm/#helm_serve">helm serve</a> - start a local http web server</li> -<li><a href="../../helm/#helm_status">helm status</a> - displays the status of the named release</li> -<li><a href="../../helm/#helm_template">helm template</a> - locally render templates</li> -<li><a href="../../helm/#helm_test">helm test</a> - test a release</li> -<li><a href="../../helm/#helm_upgrade">helm upgrade</a> - upgrade a release</li> -<li><a href="../../helm/#helm_verify">helm verify</a> - verify that a chart at the given path has been signed and is valid</li> -<li><a href="../../helm/#helm_version">helm version</a> - print the client/server version information</li> -</ul> - -<h6 id="auto-generated-by-spf13-cobra-on-25-jan-2018">Auto generated by spf13/cobra on 25-Jan-2018</h6> - - - - - - https://docs.helm.sh/helm/helm_completion/ - Mon, 01 Jan 0001 00:00:00 UTC - https://docs.helm.sh/helm/helm_completion/ - - -<h2 id="helm-completion">helm completion</h2> - -<p>Generate autocompletions script for the specified shell (bash or zsh)</p> - -<h3 id="synopsis">Synopsis</h3> - -<p>Generate autocompletions script for Helm for the specified shell (bash or zsh).</p> - -<p>This command can generate shell autocompletions. e.g.</p> - -<pre><code>$ helm completion bash -</code></pre> - -<p>Can be sourced as such</p> - -<pre><code>$ source &lt;(helm completion bash) -</code></pre> - -<pre><code>helm completion SHELL -</code></pre> - -<h3 id="options-inherited-from-parent-commands">Options inherited from parent commands</h3> - -<pre><code> --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default &quot;~/.helm&quot;) - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default &quot;kube-system&quot;) -</code></pre> - -<h3 id="see-also">SEE ALSO</h3> - -<ul> -<li><a href="../../helm/#helm">helm</a> - The Helm package manager for Kubernetes.</li> -</ul> - -<h6 id="auto-generated-by-spf13-cobra-on-25-jan-2018">Auto generated by spf13/cobra on 25-Jan-2018</h6> - - - - - - https://docs.helm.sh/helm/helm_create/ - Mon, 01 Jan 0001 00:00:00 UTC - https://docs.helm.sh/helm/helm_create/ - - -<h2 id="helm-create">helm create</h2> - -<p>create a new chart with the given name</p> - -<h3 id="synopsis">Synopsis</h3> - -<p>This command creates a chart directory along with the common files and -directories used in a chart.</p> - -<p>For example, &lsquo;helm create foo&rsquo; will create a directory structure that looks -something like this:</p> - -<pre><code>foo/ - | - |- .helmignore # Contains patterns to ignore when packaging Helm charts. - | - |- Chart.yaml # Information about your chart - | - |- values.yaml # The default values for your templates - | - |- charts/ # Charts that this chart depends on - | - |- templates/ # The template files -</code></pre> - -<p>&lsquo;helm create&rsquo; takes a path for an argument. If directories in the given path -do not exist, Helm will attempt to create them as it goes. If the given -destination exists and there are files in that directory, conflicting files -will be overwritten, but other files will be left alone.</p> - -<pre><code>helm create NAME -</code></pre> - -<h3 id="options">Options</h3> - -<pre><code> -p, --starter string the named Helm starter scaffold -</code></pre> - -<h3 id="options-inherited-from-parent-commands">Options inherited from parent commands</h3> - -<pre><code> --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default &quot;~/.helm&quot;) - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default &quot;kube-system&quot;) -</code></pre> - -<h3 id="see-also">SEE ALSO</h3> - -<ul> -<li><a href="../../helm/#helm">helm</a> - The Helm package manager for Kubernetes.</li> -</ul> - -<h6 id="auto-generated-by-spf13-cobra-on-25-jan-2018">Auto generated by spf13/cobra on 25-Jan-2018</h6> - - - - - - https://docs.helm.sh/helm/helm_delete/ - Mon, 01 Jan 0001 00:00:00 UTC - https://docs.helm.sh/helm/helm_delete/ - - -<h2 id="helm-delete">helm delete</h2> - -<p>given a release name, delete the release from Kubernetes</p> - -<h3 id="synopsis">Synopsis</h3> - -<p>This command takes a release name, and then deletes the release from Kubernetes. -It removes all of the resources associated with the last release of the chart.</p> - -<p>Use the &lsquo;&ndash;dry-run&rsquo; flag to see which releases will be deleted without actually -deleting them.</p> - -<pre><code>helm delete [flags] RELEASE_NAME [...] -</code></pre> - -<h3 id="options">Options</h3> - -<pre><code> --dry-run simulate a delete - --no-hooks prevent hooks from running during deletion - --purge remove the release from the store and make its name free for later use - --timeout int time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks) (default 300) - --tls enable TLS for request - --tls-ca-cert string path to TLS CA certificate file (default &quot;$HELM_HOME/ca.pem&quot;) - --tls-cert string path to TLS certificate file (default &quot;$HELM_HOME/cert.pem&quot;) - --tls-key string path to TLS key file (default &quot;$HELM_HOME/key.pem&quot;) - --tls-verify enable TLS for request and verify remote -</code></pre> - -<h3 id="options-inherited-from-parent-commands">Options inherited from parent commands</h3> - -<pre><code> --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default &quot;~/.helm&quot;) - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default &quot;kube-system&quot;) -</code></pre> - -<h3 id="see-also">SEE ALSO</h3> - -<ul> -<li><a href="../../helm/#helm">helm</a> - The Helm package manager for Kubernetes.</li> -</ul> - -<h6 id="auto-generated-by-spf13-cobra-on-25-jan-2018">Auto generated by spf13/cobra on 25-Jan-2018</h6> - - - - - - https://docs.helm.sh/helm/helm_dependency/ - Mon, 01 Jan 0001 00:00:00 UTC - https://docs.helm.sh/helm/helm_dependency/ - - -<h2 id="helm-dependency">helm dependency</h2> - -<p>manage a chart&rsquo;s dependencies</p> - -<h3 id="synopsis">Synopsis</h3> - -<p>Manage the dependencies of a chart.</p> - -<p>Helm charts store their dependencies in &lsquo;charts/&rsquo;. For chart developers, it is -often easier to manage a single dependency file (&lsquo;requirements.yaml&rsquo;) -which declares all dependencies.</p> - -<p>The dependency commands operate on that file, making it easy to synchronize -between the desired dependencies and the actual dependencies stored in the -&lsquo;charts/&rsquo; directory.</p> - -<p>A &lsquo;requirements.yaml&rsquo; file is a YAML file in which developers can declare chart -dependencies, along with the location of the chart and the desired version. -For example, this requirements file declares two dependencies:</p> - -<pre><code># requirements.yaml -dependencies: -- name: nginx - version: &quot;1.2.3&quot; - repository: &quot;https://example.com/charts&quot; -- name: memcached - version: &quot;3.2.1&quot; - repository: &quot;https://another.example.com/charts&quot; -</code></pre> - -<p>The &lsquo;name&rsquo; should be the name of a chart, where that name must match the name -in that chart&rsquo;s &lsquo;Chart.yaml&rsquo; file.</p> - -<p>The &lsquo;version&rsquo; field should contain a semantic version or version range.</p> - -<p>The &lsquo;repository&rsquo; URL should point to a Chart Repository. Helm expects that by -appending &lsquo;/index.yaml&rsquo; to the URL, it should be able to retrieve the chart -repository&rsquo;s index. Note: &lsquo;repository&rsquo; can be an alias. The alias must start -with &lsquo;alias:&rsquo; or &lsquo;@&rsquo;.</p> - -<p>Starting from 2.2.0, repository can be defined as the path to the directory of -the dependency charts stored locally. The path should start with a prefix of -&ldquo;file://&ldquo;. For example,</p> - -<pre><code># requirements.yaml -dependencies: -- name: nginx - version: &quot;1.2.3&quot; - repository: &quot;file://../dependency_chart/nginx&quot; -</code></pre> - -<p>If the dependency chart is retrieved locally, it is not required to have the -repository added to helm by &ldquo;helm add repo&rdquo;. Version matching is also supported -for this case.</p> - -<h3 id="options-inherited-from-parent-commands">Options inherited from parent commands</h3> - -<pre><code> --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default &quot;~/.helm&quot;) - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default &quot;kube-system&quot;) -</code></pre> - -<h3 id="see-also">SEE ALSO</h3> - -<ul> -<li><a href="../../helm/#helm">helm</a> - The Helm package manager for Kubernetes.</li> -<li><a href="../../helm/#helm_dependency_build">helm dependency build</a> - rebuild the charts/ directory based on the requirements.lock file</li> -<li><a href="../../helm/#helm_dependency_list">helm dependency list</a> - list the dependencies for the given chart</li> -<li><a href="../../helm/#helm_dependency_update">helm dependency update</a> - update charts/ based on the contents of requirements.yaml</li> -</ul> - -<h6 id="auto-generated-by-spf13-cobra-on-25-jan-2018">Auto generated by spf13/cobra on 25-Jan-2018</h6> - - - - - - https://docs.helm.sh/helm/helm_dependency_build/ - Mon, 01 Jan 0001 00:00:00 UTC - https://docs.helm.sh/helm/helm_dependency_build/ - - -<h2 id="helm-dependency-build">helm dependency build</h2> - -<p>rebuild the charts/ directory based on the requirements.lock file</p> - -<h3 id="synopsis">Synopsis</h3> - -<p>Build out the charts/ directory from the requirements.lock file.</p> - -<p>Build is used to reconstruct a chart&rsquo;s dependencies to the state specified in -the lock file. This will not re-negotiate dependencies, as &lsquo;helm dependency update&rsquo; -does.</p> - -<p>If no lock file is found, &lsquo;helm dependency build&rsquo; will mirror the behavior -of &lsquo;helm dependency update&rsquo;.</p> - -<pre><code>helm dependency build [flags] CHART -</code></pre> - -<h3 id="options">Options</h3> - -<pre><code> --keyring string keyring containing public keys (default &quot;~/.gnupg/pubring.gpg&quot;) - --verify verify the packages against signatures -</code></pre> - -<h3 id="options-inherited-from-parent-commands">Options inherited from parent commands</h3> - -<pre><code> --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default &quot;~/.helm&quot;) - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default &quot;kube-system&quot;) -</code></pre> - -<h3 id="see-also">SEE ALSO</h3> - -<ul> -<li><a href="../../helm/#helm_dependency">helm dependency</a> - manage a chart&rsquo;s dependencies</li> -</ul> - -<h6 id="auto-generated-by-spf13-cobra-on-25-jan-2018">Auto generated by spf13/cobra on 25-Jan-2018</h6> - - - - - - https://docs.helm.sh/helm/helm_dependency_list/ - Mon, 01 Jan 0001 00:00:00 UTC - https://docs.helm.sh/helm/helm_dependency_list/ - - -<h2 id="helm-dependency-list">helm dependency list</h2> - -<p>list the dependencies for the given chart</p> - -<h3 id="synopsis">Synopsis</h3> - -<p>List all of the dependencies declared in a chart.</p> - -<p>This can take chart archives and chart directories as input. It will not alter -the contents of a chart.</p> - -<p>This will produce an error if the chart cannot be loaded. It will emit a warning -if it cannot find a requirements.yaml.</p> - -<pre><code>helm dependency list [flags] CHART -</code></pre> - -<h3 id="options-inherited-from-parent-commands">Options inherited from parent commands</h3> - -<pre><code> --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default &quot;~/.helm&quot;) - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default &quot;kube-system&quot;) -</code></pre> - -<h3 id="see-also">SEE ALSO</h3> - -<ul> -<li><a href="../../helm/#helm_dependency">helm dependency</a> - manage a chart&rsquo;s dependencies</li> -</ul> - -<h6 id="auto-generated-by-spf13-cobra-on-25-jan-2018">Auto generated by spf13/cobra on 25-Jan-2018</h6> - - - - - - https://docs.helm.sh/helm/helm_dependency_update/ - Mon, 01 Jan 0001 00:00:00 UTC - https://docs.helm.sh/helm/helm_dependency_update/ - - -<h2 id="helm-dependency-update">helm dependency update</h2> - -<p>update charts/ based on the contents of requirements.yaml</p> - -<h3 id="synopsis">Synopsis</h3> - -<p>Update the on-disk dependencies to mirror the requirements.yaml file.</p> - -<p>This command verifies that the required charts, as expressed in &lsquo;requirements.yaml&rsquo;, -are present in &lsquo;charts/&rsquo; and are at an acceptable version. It will pull down -the latest charts that satisfy the dependencies, and clean up old dependencies.</p> - -<p>On successful update, this will generate a lock file that can be used to -rebuild the requirements to an exact version.</p> - -<p>Dependencies are not required to be represented in &lsquo;requirements.yaml&rsquo;. For that -reason, an update command will not remove charts unless they are (a) present -in the requirements.yaml file, but (b) at the wrong version.</p> - -<pre><code>helm dependency update [flags] CHART -</code></pre> - -<h3 id="options">Options</h3> - -<pre><code> --keyring string keyring containing public keys (default &quot;~/.gnupg/pubring.gpg&quot;) - --skip-refresh do not refresh the local repository cache - --verify verify the packages against signatures -</code></pre> - -<h3 id="options-inherited-from-parent-commands">Options inherited from parent commands</h3> - -<pre><code> --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default &quot;~/.helm&quot;) - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default &quot;kube-system&quot;) -</code></pre> - -<h3 id="see-also">SEE ALSO</h3> - -<ul> -<li><a href="../../helm/#helm_dependency">helm dependency</a> - manage a chart&rsquo;s dependencies</li> -</ul> - -<h6 id="auto-generated-by-spf13-cobra-on-25-jan-2018">Auto generated by spf13/cobra on 25-Jan-2018</h6> - - - - - - https://docs.helm.sh/helm/helm_fetch/ - Mon, 01 Jan 0001 00:00:00 UTC - https://docs.helm.sh/helm/helm_fetch/ - - -<h2 id="helm-fetch">helm fetch</h2> - -<p>download a chart from a repository and (optionally) unpack it in local directory</p> - -<h3 id="synopsis">Synopsis</h3> - -<p>Retrieve a package from a package repository, and download it locally.</p> - -<p>This is useful for fetching packages to inspect, modify, or repackage. It can -also be used to perform cryptographic verification of a chart without installing -the chart.</p> - -<p>There are options for unpacking the chart after download. This will create a -directory for the chart and uncompress into that directory.</p> - -<p>If the &ndash;verify flag is specified, the requested chart MUST have a provenance -file, and MUST pass the verification process. Failure in any part of this will -result in an error, and the chart will not be saved locally.</p> - -<pre><code>helm fetch [flags] [chart URL | repo/chartname] [...] -</code></pre> - -<h3 id="options">Options</h3> - -<pre><code> --ca-file string verify certificates of HTTPS-enabled servers using this CA bundle - --cert-file string identify HTTPS client using this SSL certificate file - -d, --destination string location to write the chart. If this and tardir are specified, tardir is appended to this (default &quot;.&quot;) - --devel use development versions, too. Equivalent to version '&gt;0.0.0-0'. If --version is set, this is ignored. - --key-file string identify HTTPS client using this SSL key file - --keyring string keyring containing public keys (default &quot;~/.gnupg/pubring.gpg&quot;) - --prov fetch the provenance file, but don't perform verification - --repo string chart repository url where to locate the requested chart - --untar if set to true, will untar the chart after downloading it - --untardir string if untar is specified, this flag specifies the name of the directory into which the chart is expanded (default &quot;.&quot;) - --verify verify the package against its signature - --version string specific version of a chart. Without this, the latest version is fetched -</code></pre> - -<h3 id="options-inherited-from-parent-commands">Options inherited from parent commands</h3> - -<pre><code> --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default &quot;~/.helm&quot;) - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default &quot;kube-system&quot;) -</code></pre> - -<h3 id="see-also">SEE ALSO</h3> - -<ul> -<li><a href="../../helm/#helm">helm</a> - The Helm package manager for Kubernetes.</li> -</ul> - -<h6 id="auto-generated-by-spf13-cobra-on-25-jan-2018">Auto generated by spf13/cobra on 25-Jan-2018</h6> - - - - - - https://docs.helm.sh/helm/helm_get/ - Mon, 01 Jan 0001 00:00:00 UTC - https://docs.helm.sh/helm/helm_get/ - - -<h2 id="helm-get">helm get</h2> - -<p>download a named release</p> - -<h3 id="synopsis">Synopsis</h3> - -<p>This command shows the details of a named release.</p> - -<p>It can be used to get extended information about the release, including:</p> - -<ul> -<li>The values used to generate the release</li> -<li>The chart used to generate the release</li> -<li>The generated manifest file</li> -</ul> - -<p>By default, this prints a human readable collection of information about the -chart, the supplied values, and the generated manifest file.</p> - -<pre><code>helm get [flags] RELEASE_NAME -</code></pre> - -<h3 id="options">Options</h3> - -<pre><code> --revision int32 get the named release with revision - --tls enable TLS for request - --tls-ca-cert string path to TLS CA certificate file (default &quot;$HELM_HOME/ca.pem&quot;) - --tls-cert string path to TLS certificate file (default &quot;$HELM_HOME/cert.pem&quot;) - --tls-key string path to TLS key file (default &quot;$HELM_HOME/key.pem&quot;) - --tls-verify enable TLS for request and verify remote -</code></pre> - -<h3 id="options-inherited-from-parent-commands">Options inherited from parent commands</h3> - -<pre><code> --debug enable verbose output - --home string location of your Helm config. Overrides $HELM_HOME (default &quot;~/.helm&quot;) - --host string address of Tiller. Overrides $HELM_HOST - --kube-context string name of the kubeconfig context to use - --tiller-namespace string namespace of Tiller (default &quot;kube-system&quot;) -</code></pre> - -<h3 id="see-also">SEE ALSO</h3> - -<ul> -<li><a href="../../helm/#helm">helm</a> - The Helm package manager for Kubernetes.</li> -<li><a href="../../helm/#helm_get_hooks">helm get hooks</a> - download all hooks for a named release</li> -<li><a href="../../helm/#helm_get_manifest">helm get manifest</a> - download the manifest for a named release</li> -<li><a href="../../helm/#helm_get_values">helm get values</a> - download the values file for a named release</li> -</ul> - -<h6 id="auto-generated-by-spf13-cobra-on-25-jan-2018">Auto generated by spf13/cobra on 25-Jan-2018</h6> - - - - - diff --git a/docs.helm.sh/rootfs/public/history/index.html b/docs.helm.sh/rootfs/public/history/index.html deleted file mode 100644 index 6e3e3c9806..0000000000 --- a/docs.helm.sh/rootfs/public/history/index.html +++ /dev/null @@ -1,1360 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

The History of the Project

- -

Kubernetes Helm is the merged result of Helm -Classic and the Kubernetes port of GCS Deployment -Manager. The project was jointly started by Google and Deis, though it -is now part of the CNCF. Many companies now contribute regularly to Helm.

- -

Differences from Helm Classic:

- -
    -
  • Helm now has both a client (helm) and a server (tiller). The -server runs inside of Kubernetes, and manages your resources.
  • -
  • Helm’s chart format has changed for the better: - -
      -
    • Dependencies are immutable and stored inside of a chart’s charts/ -directory.
    • -
    • Charts are strongly versioned using SemVer 2
    • -
    • Charts can be loaded from directories or from chart archive files
    • -
    • Helm supports Go templates without requiring you to run generate -or template commands.
    • -
    • Helm makes it easy to configure your releases – and share the -configuration with the rest of your team.
    • -
  • -
  • Helm chart repositories now use plain HTTP(S) instead of Git/GitHub. -There is no longer any GitHub dependency. - -
      -
    • A chart server is a simple HTTP server
    • -
    • Charts are referenced by version
    • -
    • The helm serve command will run a local chart server, though you -can easily use object storage (S3, GCS) or a regular web server.
    • -
    • And you can still load charts from a local directory.
    • -
  • -
  • The Helm workspace is gone. You can now work anywhere on your -filesystem that you want to work.
  • -
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/index.html b/docs.helm.sh/rootfs/public/index.html deleted file mode 100644 index 58ac262581..0000000000 --- a/docs.helm.sh/rootfs/public/index.html +++ /dev/null @@ -1,1406 +0,0 @@ - - - - - - - - - - Helm Docs - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - - - -
- - - - - - -
-
- - - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/index.md/index.html b/docs.helm.sh/rootfs/public/index.md/index.html deleted file mode 100644 index 46ab06f877..0000000000 --- a/docs.helm.sh/rootfs/public/index.md/index.html +++ /dev/null @@ -1 +0,0 @@ -https://docs.helm.sh/chart_template_guide/ \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/index.xml b/docs.helm.sh/rootfs/public/index.xml deleted file mode 100644 index 3d50857b80..0000000000 --- a/docs.helm.sh/rootfs/public/index.xml +++ /dev/null @@ -1,881 +0,0 @@ - - - - Helm Docs - https://docs.helm.sh/ - en-us - Mon, 01 Jan 0001 00:00:00 UTC - - - - https://docs.helm.sh/architecture/ - Mon, 01 Jan 0001 00:00:00 UTC - https://docs.helm.sh/architecture/ - - -<h1 id="the-kubernetes-helm-architecture">The Kubernetes Helm Architecture</h1> - -<p>This document describes the Helm architecture at a high level.</p> - -<h2 id="the-purpose-of-helm">The Purpose of Helm</h2> - -<p>Helm is a tool for managing Kubernetes packages called <em>charts</em>. Helm -can do the following:</p> - -<ul> -<li>Create new charts from scratch</li> -<li>Package charts into chart archive (tgz) files</li> -<li>Interact with chart repositories where charts are stored</li> -<li>Install and uninstall charts into an existing Kubernetes cluster</li> -<li>Manage the release cycle of charts that have been installed with Helm</li> -</ul> - -<p>For Helm, there are three important concepts:</p> - -<ol> -<li>The <em>chart</em> is a bundle of information necessary to create an -instance of a Kubernetes application.</li> -<li>The <em>config</em> contains configuration information that can be merged -into a packaged chart to create a releasable object.</li> -<li>A <em>release</em> is a running instance of a <em>chart</em>, combined with a -specific <em>config</em>.</li> -</ol> - -<h2 id="components">Components</h2> - -<p>Helm has two major components:</p> - -<p><strong>The Helm Client</strong> is a command-line client for end users. The client -is responsible for the following domains:</p> - -<ul> -<li>Local chart development</li> -<li>Managing repositories</li> -<li>Interacting with the Tiller server - -<ul> -<li>Sending charts to be installed</li> -<li>Asking for information about releases</li> -<li>Requesting upgrading or uninstalling of existing releases</li> -</ul></li> -</ul> - -<p><strong>The Tiller Server</strong> is an in-cluster server that interacts with the -Helm client, and interfaces with the Kubernetes API server. The server -is responsible for the following:</p> - -<ul> -<li>Listening for incoming requests from the Helm client</li> -<li>Combining a chart and configuration to build a release</li> -<li>Installing charts into Kubernetes, and then tracking the subsequent -release</li> -<li>Upgrading and uninstalling charts by interacting with Kubernetes</li> -</ul> - -<p>In a nutshell, the client is responsible for managing charts, and the -server is responsible for managing releases.</p> - -<h2 id="implementation">Implementation</h2> - -<p>The Helm client is written in the Go programming language, and uses the -gRPC protocol suite to interact with the Tiller server.</p> - -<p>The Tiller server is also written in Go. It provides a gRPC server to -connect with the client, and it uses the Kubernetes client library to -communicate with Kubernetes. Currently, that library uses REST+JSON.</p> - -<p>The Tiller server stores information in ConfigMaps located inside of -Kubernetes. It does not need its own database.</p> - -<p>Configuration files are, when possible, written in YAML.</p> - - - - - - https://docs.helm.sh/chart_best_practices/readme/ - Mon, 01 Jan 0001 00:00:00 UTC - https://docs.helm.sh/chart_best_practices/readme/ - - -<h1 id="the-chart-best-practices-guide">The Chart Best Practices Guide</h1> - -<p>This guide covers the Helm Team&rsquo;s considered best practices for creating charts. -It focuses on how charts should be structured.</p> - -<p>We focus primarily on best practices for charts that may be publicly deployed. -We know that many charts are for internal-use only, and authors of such charts -may find that their internal interests override our suggestions here.</p> - -<h2 id="table-of-contents">Table of Contents</h2> - -<ul> -<li><a href="./#conventions">General Conventions</a>: Learn about general chart conventions.</li> -<li><a href="./#values">Values Files</a>: See the best practices for structuring <code>values.yaml</code>.</li> -<li><a href="./#templates">Templates</a>: Learn some of the best techniques for writing templates.</li> -<li><a href="./#requirements">Requirements</a>: Follow best practices for <code>requirements.yaml</code> files.</li> -<li><a href="./#labels">Labels and Annotations</a>: Helm has a <em>heritage</em> of labeling and annotating.</li> -<li>Kubernetes Resources: - -<ul> -<li><a href="./#pods">Pods and Pod Specs</a>: See the best practices for working with pod specifications.</li> -<li><a href="./#rbac">Role-Based Access Control</a>: Guidance on creating and using service accounts, roles, and role bindings.</li> -<li><a href="./#third_party_resources">Third Party Resources</a>: Third Party Resources (TPRs) have their own associated best practices.</li> -</ul></li> -</ul> - - - - - - https://docs.helm.sh/chart_best_practices/conventions/ - Mon, 01 Jan 0001 00:00:00 UTC - https://docs.helm.sh/chart_best_practices/conventions/ - - -<h1 id="general-conventions">General Conventions</h1> - -<p>This part of the Best Practices Guide explains general conventions.</p> - -<h2 id="chart-names">Chart Names</h2> - -<p>Chart names should be lower case letters and numbers. Words <em>may</em> be separated with dashes (-):</p> - -<p>Examples:</p> - -<pre><code>drupal -nginx-lego -aws-cluster-autoscaler -</code></pre> - -<p>Neither uppercase letters nor underscores should be used in chart names. Dots should not be used in chart names.</p> - -<p>The directory that contains a chart MUST have the same name as the chart. Thus, the chart <code>nginx-lego</code> MUST be created in a directory called <code>nginx-lego/</code>. This is not merely a stylistic detail, but a requirement of the Helm Chart format.</p> - -<h2 id="version-numbers">Version Numbers</h2> - -<p>Wherever possible, Helm uses <a href="http://semver.org">SemVer 2</a> to represent version numbers. (Note that Docker image tags do not necessarily follow SemVer, and are thus considered an unfortunate exception to the rule.)</p> - -<p>When SemVer versions are stored in Kubernetes labels, we conventionally alter the <code>+</code> character to an <code>_</code> character, as labels do not allow the <code>+</code> sign as a value.</p> - -<h2 id="formatting-yaml">Formatting YAML</h2> - -<p>YAML files should be indented using <em>two spaces</em> (and never tabs).</p> - -<h2 id="usage-of-the-words-helm-tiller-and-chart">Usage of the Words Helm, Tiller, and Chart</h2> - -<p>There are a few small conventions followed for using the words Helm, helm, Tiller, and tiller.</p> - -<ul> -<li>Helm refers to the project, and is often used as an umbrella term</li> -<li><code>helm</code> refers to the client-side command</li> -<li>Tiller is the proper name of the backend</li> -<li><code>tiller</code> is the name of the binary run on the backend</li> -<li>The term &lsquo;chart&rsquo; does not need to be capitalized, as it is not a proper noun.</li> -</ul> - -<p>When in doubt, use <em>Helm</em> (with an uppercase &lsquo;H&rsquo;).</p> - -<h2 id="restricting-tiller-by-version">Restricting Tiller by Version</h2> - -<p>A <code>Chart.yaml</code> file can specify a <code>tillerVersion</code> SemVer constraint:</p> - -<pre><code class="language-yaml">name: mychart -version: 0.2.0 -tillerVersion: &quot;&gt;=2.4.0&quot; -</code></pre> - -<p>This constraint should be set when templates use a new feature that was not -supported in older versions of Helm. While this parameter will accept sophisticated -SemVer rules, the best practice is to default to the form <code>&gt;=2.4.0</code>, where <code>2.4.0</code> -is the version that introduced the new feature used in the chart.</p> - -<p>This feature was introduced in Helm 2.4.0, so any version of Tiller older than -2.4.0 will simply ignore this field.</p> - - - - - - https://docs.helm.sh/chart_best_practices/labels/ - Mon, 01 Jan 0001 00:00:00 UTC - https://docs.helm.sh/chart_best_practices/labels/ - - -<h1 id="labels-and-annotations">Labels and Annotations</h1> - -<p>This part of the Best Practices Guide discusses the best practices for using -labels and annotations in your chart.</p> - -<h2 id="is-it-a-label-or-an-annotation">Is it a Label or an Annotation?</h2> - -<p>An item of metadata should be a label under the following conditions:</p> - -<ul> -<li>It is used by Kubernetes to identify this resource</li> -<li>It is useful to expose to operators for the purpose of querying the system.</li> -</ul> - -<p>For example, we suggest using <code>chart: NAME-VERSION</code> as a label so that operators -can conveniently find all of the instances of a particular chart to use.</p> - -<p>If an item of metadata is not used for querying, it should be set as an annotation -instead.</p> - -<p>Helm hooks are always annotations.</p> - -<h2 id="standard-labels">Standard Labels</h2> - -<p>The following table defines common labels that Helm charts use. Helm itself never requires that a particular label be present. Labels that are marked REC -are recommended, and <em>should</em> be placed onto a chart for global consistency. Those marked OPT are optional. These are idiomatic or commonly in use, but are not relied upon frequently for operational purposes.</p> - -<table> -<thead> -<tr> -<th>Name</th> -<th>Status</th> -<th>Description</th> -</tr> -</thead> - -<tbody> -<tr> -<td>heritage</td> -<td>REC</td> -<td>This should always be set to <code>{{ .Release.Service }}</code>. It is for finding all things managed by Tiller.</td> -</tr> - -<tr> -<td>release</td> -<td>REC</td> -<td>This should be the <code>{{ .Release.Name }}</code>.</td> -</tr> - -<tr> -<td>chart</td> -<td>REC</td> -<td>This should be the chart name and version: <code>{{ .Chart.Name }}-{{ .Chart.Version \| replace &quot;+&quot; &quot;_&quot; }}</code>.</td> -</tr> - -<tr> -<td>app</td> -<td>REC</td> -<td>This should be the app name, reflecting the entire app. Usually <code>{{ template &quot;name&quot; . }}</code> is used for this. This is used by many Kubernetes manifests, and is not Helm-specific.</td> -</tr> - -<tr> -<td>component</td> -<td>OPT</td> -<td>This is a common label for marking the different roles that pieces may play in an application. For example, <code>component: frontend</code>.</td> -</tr> -</tbody> -</table> - - - - - - https://docs.helm.sh/chart_best_practices/pods/ - Mon, 01 Jan 0001 00:00:00 UTC - https://docs.helm.sh/chart_best_practices/pods/ - - -<h1 id="pods-and-podtemplates">Pods and PodTemplates</h1> - -<p>This part of the Best Practices Guide discusses formatting the Pod and PodTemplate -portions in chart manifests.</p> - -<p>The following (non-exhaustive) list of resources use PodTemplates:</p> - -<ul> -<li>Deployment</li> -<li>ReplicationController</li> -<li>ReplicaSet</li> -<li>DaemonSet</li> -<li>StatefulSet</li> -</ul> - -<h2 id="images">Images</h2> - -<p>A container image should use a fixed tag or the SHA of the image. It should not use the tags <code>latest</code>, <code>head</code>, <code>canary</code>, or other tags that are designed to be &ldquo;floating&rdquo;.</p> - -<p>Images <em>may</em> be defined in the <code>values.yaml</code> file to make it easy to swap out images.</p> - -<pre><code>image: {{ .Values.redisImage | quote }} -</code></pre> - -<p>An image and a tag <em>may</em> be defined in <code>values.yaml</code> as two separate fields:</p> - -<pre><code>image: &quot;{{ .Values.redisImage }}:{{ .Values.redisTag }}&quot; -</code></pre> - -<h2 id="imagepullpolicy">ImagePullPolicy</h2> - -<p><code>helm create</code> sets the <code>imagePullPolicy</code> to <code>IfNotPresent</code> by default by doing the following in your <code>deployment.yaml</code>:</p> - -<pre><code class="language-yaml">imagePullPolicy: {{ .Values.image.pullPolicy }} -</code></pre> - -<p>And <code>values.yaml</code>:</p> - -<pre><code class="language-yaml">pullPolicy: IfNotPresent -</code></pre> - -<p>Similarly, Kubernetes defaults the <code>imagePullPolicy</code> to <code>IfNotPresent</code> if it is not defined at all. If you want a value other than <code>IfNotPresent</code>, simply update the value in <code>values.yaml</code> to your desired value.</p> - -<h2 id="podtemplates-should-declare-selectors">PodTemplates Should Declare Selectors</h2> - -<p>All PodTemplate sections should specify a selector. For example:</p> - -<pre><code class="language-yaml">selector: - matchLabels: - app: MyName -template: - metadata: - labels: - app: MyName -</code></pre> - -<p>This is a good practice because it makes the relationship between the set and -the pod.</p> - -<p>But this is even more important for sets like Deployment. -Without this, the <em>entire</em> set of labels is used to select matching pods, and -this will break if you use labels that change, like version or release date.</p> - - - - - - https://docs.helm.sh/chart_best_practices/rbac/ - Mon, 01 Jan 0001 00:00:00 UTC - https://docs.helm.sh/chart_best_practices/rbac/ - - -<h1 id="role-based-access-control">Role-Based Access Control</h1> - -<p>This part of the Best Practices Guide discusses the creation and formatting of RBAC resources in chart manifests.</p> - -<p>RBAC resources are:</p> - -<ul> -<li>ServiceAccount (namespaced)</li> -<li>Role (namespaced)</li> -<li>ClusterRole</li> -<li>RoleBinding (namespaced)</li> -<li>ClusterRoleBinding</li> -</ul> - -<h2 id="yaml-configuration">YAML Configuration</h2> - -<p>RBAC and ServiceAccount configuration should happen under separate keys. They are separate things. Splitting these two concepts out in the YAML disambiguates them and make this clearer.</p> - -<pre><code class="language-yaml">rbac: - # Specifies whether RBAC resources should be created - create: true - -serviceAccount: - # Specifies whether a ServiceAccount should be created - create: true - # The name of the ServiceAccount to use. - # If not set and create is true, a name is generated using the fullname template - name: -</code></pre> - -<p>This structure can be extended for more complex charts that require multiple ServiceAccounts.</p> - -<pre><code class="language-yaml">serviceAccounts: - client: - create: true - name: - server: - create: true - name: -</code></pre> - -<h2 id="rbac-resources-should-be-created-by-default">RBAC Resources Should be Created by Default</h2> - -<p><code>rbac.create</code> should be a boolean value controlling whether RBAC resources are created. The default should be <code>true</code>. Users who wish to manage RBAC access controls themselves can set this value to <code>false</code> (in which case see below).</p> - -<h2 id="using-rbac-resources">Using RBAC Resources</h2> - -<p><code>serviceAccount.name</code> should set to the name of the ServiceAccount to be used by access-controlled resources created by the chart. If <code>serviceAccount.create</code> is true, then a ServiceAccount with this name should be created. If the name is not set, then a name is generated using the <code>fullname</code> template, If <code>serviceAccount.create</code> is false, then it should not be created, but it should still be associated with the same resources so that manually-created RBAC resources created later that reference it will function correctly. If <code>serviceAccount.create</code> is false and the name is not specified, then the default ServiceAccount is used.</p> - -<p>The following helper template should be used for the ServiceAccount.</p> - -<pre><code class="language-yaml">{{/* -Create the name of the service account to use -*/}} -{{- define &quot;mychart.serviceAccountName&quot; -}} -{{- if .Values.serviceAccount.create -}} - {{ default (include &quot;mychart.fullname&quot; .) .Values.serviceAccount.name }} -{{- else -}} - {{ default &quot;default&quot; .Values.serviceAccount.name }} -{{- end -}} -{{- end -}} -</code></pre> - - - - - - https://docs.helm.sh/chart_best_practices/requirements/ - Mon, 01 Jan 0001 00:00:00 UTC - https://docs.helm.sh/chart_best_practices/requirements/ - - -<h1 id="requirements-files">Requirements Files</h1> - -<p>This section of the guide covers best practices for <code>requirements.yaml</code> files.</p> - -<h2 id="versions">Versions</h2> - -<p>Where possible, use version ranges instead of pinning to an exact version. The suggested default is to use a patch-level version match:</p> - -<pre><code class="language-yaml">version: ~1.2.3 -</code></pre> - -<p>This will match version <code>1.2.3</code> and any patches to that release. In other words, <code>~1.2.3</code> is equivalent to <code>&gt;= 1.2.3, &lt; 1.3.0</code></p> - -<p>For the complete version matching syntax, please see the <a href="https://github.com/Masterminds/semver#checking-version-constraints">semver documentation</a></p> - -<h3 id="repository-urls">Repository URLs</h3> - -<p>Where possible, use <code>https://</code> repository URLs, followed by <code>http://</code> URLs.</p> - -<p>If the repository has been added to the repository index file, the repository name can be used as an alias of URL. Use <code>alias:</code> or <code>@</code> followed by repository names.</p> - -<p>File URLs (<code>file://...</code>) are considered a &ldquo;special case&rdquo; for charts that are assembled by a fixed deployment pipeline. Charts that use <code>file://</code> in a <code>requirements.yaml</code> file are not allowed in the official Helm repository.</p> - -<h2 id="conditions-and-tags">Conditions and Tags</h2> - -<p>Conditions or tags should be added to any dependencies that <em>are optional</em>.</p> - -<p>The preferred form of a condition is:</p> - -<pre><code class="language-yaml">condition: somechart.enabled -</code></pre> - -<p>Where <code>somechart</code> is the chart name of the dependency.</p> - -<p>When multiple subcharts (dependencies) together provide an optional or swappable feature, those charts should share the same tags.</p> - -<p>For example, if both <code>nginx</code> and <code>memcached</code> together provided performance optimizations for the main app in the chart, and were required to both be present when that feature is enabled, then they might both have a -tags section like this:</p> - -<pre><code>tags: - - webaccelerator -</code></pre> - -<p>This allows a user to turn that feature on and off with one tag.</p> - - - - - - https://docs.helm.sh/chart_best_practices/templates/ - Mon, 01 Jan 0001 00:00:00 UTC - https://docs.helm.sh/chart_best_practices/templates/ - - -<h1 id="templates">Templates</h1> - -<p>This part of the Best Practices Guide focuses on templates.</p> - -<h2 id="structure-of-templates">Structure of templates/</h2> - -<p>The templates directory should be structured as follows:</p> - -<ul> -<li>Template files should have the extension <code>.yaml</code> if they produce YAML output. The -extension <code>.tpl</code> may be used for template files that produce no formatted content.</li> -<li>Template file names should use dashed notation (<code>my-example-configmap.yaml</code>), not camelcase.</li> -<li>Each resource definition should be in its own template file.</li> -<li>Template file names should reflect the resource kind in the name. e.g. <code>foo-pod.yaml</code>, -<code>bar-svc.yaml</code></li> -</ul> - -<h2 id="names-of-defined-templates">Names of Defined Templates</h2> - -<p>Defined templates (templates created inside a <code>{{ define }}</code> directive) are -globally accessible. That means that a chart and all of its subcharts will have -access to all of the templates created with <code>{{ define }}</code>.</p> - -<p>For that reason, <em>all defined template names should be namespaced.</em></p> - -<p>Correct:</p> - -<pre><code class="language-yaml">{{- define &quot;nginx.fullname&quot; }} -{{/* ... */}} -{{ end -}} -</code></pre> - -<p>Incorrect:</p> - -<pre><code class="language-yaml">{{- define &quot;fullname&quot; -}} -{{/* ... */}} -{{ end -}} -</code></pre> - -<p>It is highly recommended that new charts are created via <code>helm create</code> command as the template names are automatically defined as per this best practice.</p> - -<h2 id="formatting-templates">Formatting Templates</h2> - -<p>Templates should be indented using <em>two spaces</em> (never tabs).</p> - -<p>Template directives should have whitespace after the opening braces and before the -closing braces:</p> - -<p>Correct:</p> - -<pre><code>{{ .foo }} -{{ print &quot;foo&quot; }} -{{- print &quot;bar&quot; -}} -</code></pre> - -<p>Incorrect:</p> - -<pre><code>{{.foo}} -{{print &quot;foo&quot;}} -{{-print &quot;bar&quot;-}} -</code></pre> - -<p>Templates should chomp whitespace where possible:</p> - -<pre><code>foo: - {{- range .Values.items }} - {{ . }} - {{ end -}} -</code></pre> - -<p>Blocks (such as control structures) may be indented to indicate flow of the template code.</p> - -<pre><code>{{ if $foo -}} - {{- with .Bar }}Hello{{ end -}} -{{- end -}} -</code></pre> - -<p>However, since YAML is a whitespace-oriented language, it is often not possible for code indentation to follow that convention.</p> - -<h2 id="whitespace-in-generated-templates">Whitespace in Generated Templates</h2> - -<p>It is preferable to keep the amount of whitespace in generated templates to -a minimum. In particular, numerous blank lines should not appear adjacent to each -other. But occasional empty lines (particularly between logical sections) is -fine.</p> - -<p>This is best:</p> - -<pre><code class="language-yaml">apiVersion: batch/v1 -kind: Job -metadata: - name: example - labels: - first: first - second: second -</code></pre> - -<p>This is okay:</p> - -<pre><code class="language-yaml">apiVersion: batch/v1 -kind: Job - -metadata: - name: example - - labels: - first: first - second: second - -</code></pre> - -<p>But this should be avoided:</p> - -<pre><code class="language-yaml">apiVersion: batch/v1 -kind: Job - -metadata: - name: example - - - - - - labels: - first: first - - second: second - -</code></pre> - -<h2 id="comments-yaml-comments-vs-template-comments">Comments (YAML Comments vs. Template Comments)</h2> - -<p>Both YAML and Helm Templates have comment markers.</p> - -<p>YAML comments:</p> - -<pre><code class="language-yaml"># This is a comment -type: sprocket -</code></pre> - -<p>Template Comments:</p> - -<pre><code class="language-yaml">{{- /* -This is a comment. -*/ -}} -type: frobnitz -</code></pre> - -<p>Template comments should be used when documenting features of a template, such as explaining a defined template:</p> - -<pre><code class="language-yaml">{{- /* -mychart.shortname provides a 6 char truncated version of the release name. -*/ }} -{{ define &quot;mychart.shortname&quot; -}} -{{ .Release.Name | trunc 6 }} -{{- end -}} - -</code></pre> - -<p>Inside of templates, YAML comments may be used when it is useful for Helm users to (possibly) see the comments during debugging.</p> - -<pre><code># This may cause problems if the value is more than 100Gi -memory: {{ .Values.maxMem | quote }} -</code></pre> - -<p>The comment above is visible when the user runs <code>helm install --debug</code>, while -comments specified in <code>{{- /* */ -}}</code> sections are not.</p> - -<h2 id="use-of-json-in-templates-and-template-output">Use of JSON in Templates and Template Output</h2> - -<p>YAML is a superset of JSON. In some cases, using a JSON syntax can be more -readable than other YAML representations.</p> - -<p>For example, this YAML is closer to the normal YAML method of expressing lists:</p> - -<pre><code class="language-yaml">arguments: - - &quot;--dirname&quot; - - &quot;/foo&quot; -</code></pre> - -<p>But it is easier to read when collapsed into a JSON list style:</p> - -<pre><code class="language-yaml">arguments: [&quot;--dirname&quot;, &quot;/foo&quot;] -</code></pre> - -<p>Using JSON for increased legibility is good. However, JSON syntax should not -be used for representing more complex constructs.</p> - -<p>When dealing with pure JSON embedded inside of YAML (such as init container -configuration), it is of course appropriate to use the JSON format.</p> - - - - - - https://docs.helm.sh/chart_best_practices/third_party_resources/ - Mon, 01 Jan 0001 00:00:00 UTC - https://docs.helm.sh/chart_best_practices/third_party_resources/ - - -<h1 id="third-party-resources">Third Party Resources</h1> - -<p>This section of the Best Practices Guide deals with creating and using Third Party Resource -objects.</p> - -<p>When working with Third Party Resources (TPRs), it is important to distinguish -two different pieces:</p> - -<ul> -<li>There is a declaration of a TPR. This is the YAML file that has the kind <code>ThirdPartyResource</code></li> -<li>Then there are resources that <em>use</em> the TPR. Say a TPR defines <code>foo.example.com/v1</code>. Any resource -that has <code>apiVersion: example.com/v1</code> and kind <code>Foo</code> is a resource that uses the -TPR.</li> -</ul> - -<h2 id="install-a-tpr-declaration-before-using-the-resource">Install a TPR Declaration Before Using the Resource</h2> - -<p>Helm is optimized to load as many resources into Kubernetes as fast as possible. -By design, Kubernetes can take an entire set of manifests and bring them all -online (this is called the reconciliation loop).</p> - -<p>But there&rsquo;s a difference with TPRs.</p> - -<p>For a TPR, the declaration must be registered before any resources of that TPRs -kind(s) can be used. And the registration process sometimes takes a few seconds.</p> - -<h3 id="method-1-separate-charts">Method 1: Separate Charts</h3> - -<p>One way to do this is to put the TPR definition in one chart, and then put any -resources that use that TPR in <em>another</em> chart.</p> - -<p>In this method, each chart must be installed separately.</p> - -<h3 id="method-2-pre-install-hooks">Method 2: Pre-install Hooks</h3> - -<p>To package the two together, add a <code>pre-install</code> hook to the TPR definition so -that it is fully installed before the rest of the chart is executed.</p> - -<p>Note that if you create the TPR with a <code>pre-install</code> hook, that TPR definition -will not be deleted when <code>helm delete</code> is run.</p> - - - - - - https://docs.helm.sh/chart_best_practices/values/ - Mon, 01 Jan 0001 00:00:00 UTC - https://docs.helm.sh/chart_best_practices/values/ - - -<h1 id="values">Values</h1> - -<p>This part of the best practices guide covers using values. In this part of the -guide, we provide recommendations on how you should structure and use your -values, with focus on designing a chart&rsquo;s <code>values.yaml</code> file.</p> - -<h2 id="naming-conventions">Naming Conventions</h2> - -<p>Variables names should begin with a lowercase letter, and words should be -separated with camelcase:</p> - -<p>Correct:</p> - -<pre><code class="language-yaml">chicken: true -chickenNoodleSoup: true -</code></pre> - -<p>Incorrect:</p> - -<pre><code class="language-yaml">Chicken: true # initial caps may conflict with built-ins -chicken-noodle-soup: true # do not use hyphens in the name -</code></pre> - -<p>Note that all of Helm&rsquo;s built-in variables begin with an uppercase letter to -easily distinguish them from user-defined values: <code>.Release.Name</code>, -<code>.Capabilities.KubeVersion</code>.</p> - -<h2 id="flat-or-nested-values">Flat or Nested Values</h2> - -<p>YAML is a flexible format, and values may be nested deeply or flattened.</p> - -<p>Nested:</p> - -<pre><code class="language-yaml">server: - name: nginx - port: 80 -</code></pre> - -<p>Flat:</p> - -<pre><code class="language-yaml">serverName: nginx -serverPort: 80 -</code></pre> - -<p>In most cases, flat should be favored over nested. The reason for this is that -it is simpler for template developers and users.</p> - -<p>For optimal safety, a nested value must be checked at every level:</p> - -<pre><code>{{ if .Values.server }} - {{ default &quot;none&quot; .Values.server.name }} -{{ end }} -</code></pre> - -<p>For every layer of nesting, an existence check must be done. But for flat -configuration, such checks can be skipped, making the template easier to read -and use.</p> - -<pre><code>{{ default &quot;none&quot; .Values.serverName }} -</code></pre> - -<p>When there are a large number of related variables, and at least one of them -is non-optional, nested values may be used to improve readability.</p> - -<h2 id="make-types-clear">Make Types Clear</h2> - -<p>YAML&rsquo;s type coercion rules are sometimes counterintuitive. For example, -<code>foo: false</code> is not the same as <code>foo: &quot;false&quot;</code>. Large integers like <code>foo: 12345678</code> -will get converted to scientific notation in some cases.</p> - -<p>The easiest way to avoid type conversion errors is to be explicit about strings, -and implicit about everything else. Or, in short, <em>quote all strings</em>.</p> - -<p>Often, to avoid the integer casting issues, it is advantageous to store your -integers as strings as well, and use <code>{{ int $value }}</code> in the template to convert -from a string back to an integer.</p> - -<p>In most cases, explicit type tags are respected, so <code>foo: !!string 1234</code> should -treat <code>1234</code> as a string. <em>However</em>, the YAML parser consumes tags, so the type -data is lost after one parse.</p> - -<h2 id="consider-how-users-will-use-your-values">Consider How Users Will Use Your Values</h2> - -<p>There are three potential sources of values:</p> - -<ul> -<li>A chart&rsquo;s <code>values.yaml</code> file</li> -<li>A values file supplied by <code>helm install -f</code> or <code>helm upgrade -f</code></li> -<li>The values passed to a <code>--set</code> flag on <code>helm install</code> or <code>helm upgrade</code></li> -</ul> - -<p>When designing the structure of your values, keep in mind that users of your -chart may want to override them via either the <code>-f</code> flag or with the <code>--set</code> -option.</p> - -<p>Since <code>--set</code> is more limited in expressiveness, the first guidelines for writing -your <code>values.yaml</code> file is <em>make it easy to override from <code>--set</code></em>.</p> - -<p>For this reason, it&rsquo;s often better to structure your values file using maps.</p> - -<p>Difficult to use with <code>--set</code>:</p> - -<pre><code class="language-yaml">servers: - - name: foo - port: 80 - - name: bar - port: 81 -</code></pre> - -<p>The above cannot be expressed with <code>--set</code> in Helm <code>&lt;=2.4</code>. In Helm 2.5, the -accessing the port on foo is <code>--set servers[0].port=80</code>. Not only is it harder -for the user to figure out, but it is prone to errors if at some later time the -order of the <code>servers</code> is changed.</p> - -<p>Easy to use:</p> - -<pre><code class="language-yaml">servers: - foo: - port: 80 - bar: - port: 81 -</code></pre> - -<p>Accessing foo&rsquo;s port is much more obvious: <code>--set servers.foo.port=80</code>.</p> - -<h2 id="document-values-yaml">Document &lsquo;values.yaml&rsquo;</h2> - -<p>Every defined property in &lsquo;values.yaml&rsquo; should be documented. The documentation string should begin with the name of the property that it describes, and then give at least a one-sentence description.</p> - -<p>Incorrect:</p> - -<pre><code># the host name for the webserver -serverHost = example -serverPort = 9191 -</code></pre> - -<p>Correct:</p> - -<pre><code># serverHost is the host name for the webserver -serverHost = example -# serverPort is the HTTP listener port for the webserver -serverPort = 9191 - -</code></pre> - -<p>Beginning each comment with the name of the parameter it documents makes it easy to grep out documentation, and will enable documentation tools to reliably correlate doc strings with the parameters they describe.</p> - - - - - diff --git a/docs.helm.sh/rootfs/public/install/index.html b/docs.helm.sh/rootfs/public/install/index.html deleted file mode 100644 index 4a2ef33159..0000000000 --- a/docs.helm.sh/rootfs/public/install/index.html +++ /dev/null @@ -1,1660 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

Installing Helm

- -

There are two parts to Helm: The Helm client (helm) and the Helm -server (Tiller). This guide shows how to install the client, and then -proceeds to show two ways to install the server.

- -

IMPORTANT: If you are responsible for ensuring your cluster is a controlled environment, especially when resources are shared, it is strongly recommended installing Tiller using a secured configuration. For guidance, see Securing your Helm Installation.

- -

Installing the Helm Client

- -

The Helm client can be installed either from source, or from pre-built binary -releases.

- -

From the Binary Releases

- -

Every release of Helm -provides binary releases for a variety of OSes. These binary versions -can be manually downloaded and installed.

- -
    -
  1. Download your desired version
  2. -
  3. Unpack it (tar -zxvf helm-v2.0.0-linux-amd64.tgz)
  4. -
  5. Find the helm binary in the unpacked directory, and move it to its -desired destination (mv linux-amd64/helm /usr/local/bin/helm)
  6. -
- -

From there, you should be able to run the client: helm help.

- -

From Homebrew (macOS)

- -

Members of the Kubernetes community have contributed a Helm formula build to -Homebrew. This formula is generally up to date.

- -
brew install kubernetes-helm
-
- -

(Note: There is also a formula for emacs-helm, which is a different -project.)

- -

From Script

- -

Helm now has an installer script that will automatically grab the latest version -of the Helm client and install it locally.

- -

You can fetch that script, and then execute it locally. It’s well documented so -that you can read through it and understand what it is doing before you run it.

- -
$ curl https://raw.githubusercontent.com/kubernetes/helm/master/scripts/get > get_helm.sh
-$ chmod 700 get_helm.sh
-$ ./get_helm.sh
-
- -

Yes, you can curl https://raw.githubusercontent.com/kubernetes/helm/master/scripts/get | bash that if you want to live on the edge.

- -

From Canary Builds

- -

“Canary” builds are versions of the Helm software that are built from -the latest master branch. They are not official releases, and may not be -stable. However, they offer the opportunity to test the cutting edge -features.

- -

Canary Helm binaries are stored in the Kubernetes Helm GCS bucket. -Here are links to the common builds:

- - - -

From Source (Linux, macOS)

- -

Building Helm from source is slightly more work, but is the best way to -go if you want to test the latest (pre-release) Helm version.

- -

You must have a working Go environment with -glide and Mercurial installed.

- -
$ cd $GOPATH
-$ mkdir -p src/k8s.io
-$ cd src/k8s.io
-$ git clone https://github.com/kubernetes/helm.git
-$ cd helm
-$ make bootstrap build
-
- -

The bootstrap target will attempt to install dependencies, rebuild the -vendor/ tree, and validate configuration.

- -

The build target will compile helm and place it in bin/helm. -Tiller is also compiled, and is placed in bin/tiller.

- -

Installing Tiller

- -

Tiller, the server portion of Helm, typically runs inside of your -Kubernetes cluster. But for development, it can also be run locally, and -configured to talk to a remote Kubernetes cluster.

- -

Easy In-Cluster Installation

- -

The easiest way to install tiller into the cluster is simply to run -helm init. This will validate that helm’s local environment is set -up correctly (and set it up if necessary). Then it will connect to -whatever cluster kubectl connects to by default (kubectl config -view). Once it connects, it will install tiller into the -kube-system namespace.

- -

After helm init, you should be able to run kubectl get pods --namespace -kube-system and see Tiller running.

- -

You can explicitly tell helm init to…

- -
    -
  • Install the canary build with the --canary-image flag
  • -
  • Install a particular image (version) with --tiller-image
  • -
  • Install to a particular cluster with --kube-context
  • -
  • Install into a particular namespace with --tiller-namespace
  • -
- -

Once Tiller is installed, running helm version should show you both -the client and server version. (If it shows only the client version, -helm cannot yet connect to the server. Use kubectl to see if any -tiller pods are running.)

- -

Helm will look for Tiller in the kube-system namespace unless ---tiller-namespace or TILLER_NAMESPACE is set.

- -

Installing Tiller Canary Builds

- -

Canary images are built from the master branch. They may not be -stable, but they offer you the chance to test out the latest features.

- -

The easiest way to install a canary image is to use helm init with the ---canary-image flag:

- -
$ helm init --canary-image
-
- -

This will use the most recently built container image. You can always -uninstall Tiller by deleting the Tiller deployment from the -kube-system namespace using kubectl.

- -

Running Tiller Locally

- -

For development, it is sometimes easier to work on Tiller locally, and -configure it to connect to a remote Kubernetes cluster.

- -

The process of building Tiller is explained above.

- -

Once tiller has been built, simply start it:

- -
$ bin/tiller
-Tiller running on :44134
-
- -

When Tiller is running locally, it will attempt to connect to the -Kubernetes cluster that is configured by kubectl. (Run kubectl config -view to see which cluster that is.)

- -

You must tell helm to connect to this new local Tiller host instead of -connecting to the one in-cluster. There are two ways to do this. The -first is to specify the --host option on the command line. The second -is to set the $HELM_HOST environment variable.

- -
$ export HELM_HOST=localhost:44134
-$ helm version # Should connect to localhost.
-Client: &version.Version{SemVer:"v2.0.0-alpha.4", GitCommit:"db...", GitTreeState:"dirty"}
-Server: &version.Version{SemVer:"v2.0.0-alpha.4", GitCommit:"a5...", GitTreeState:"dirty"}
-
- -

Importantly, even when running locally, Tiller will store release -configuration in ConfigMaps inside of Kubernetes.

- -

Upgrading Tiller

- -

As of Helm 2.2.0, Tiller can be upgraded using helm init --upgrade.

- -

For older versions of Helm, or for manual upgrades, you can use kubectl to modify -the Tiller image:

- -
$ export TILLER_TAG=v2.0.0-beta.1        # Or whatever version you want
-$ kubectl --namespace=kube-system set image deployments/tiller-deploy tiller=gcr.io/kubernetes-helm/tiller:$TILLER_TAG
-deployment "tiller-deploy" image updated
-
- -

Setting TILLER_TAG=canary will get the latest snapshot of master.

- -

Deleting or Reinstalling Tiller

- -

Because Tiller stores its data in Kubernetes ConfigMaps, you can safely -delete and re-install Tiller without worrying about losing any data. The -recommended way of deleting Tiller is with kubectl delete deployment -tiller-deploy --namespace kube-system, or more concisely helm reset.

- -

Tiller can then be re-installed from the client with:

- -
$ helm init
-
- -

Advanced Usage

- -

helm init provides additional flags for modifying Tiller’s deployment -manifest before it is installed.

- -

Using --node-selectors

- -

The --node-selectors flag allows us to specify the node labels required -for scheduling the Tiller pod.

- -

The example below will create the specified label under the nodeSelector -property.

- -
helm init --node-selectors "beta.kubernetes.io/os"="linux"
-
- -

The installed deployment manifest will contain our node selector label.

- -
...
-spec:
-  template:
-    spec:
-      nodeSelector:
-        beta.kubernetes.io/os: linux
-...
-
- -

Using --override

- -

--override allows you to specify properties of Tiller’s -deployment manifest. Unlike the --set command used elsewhere in Helm, -helm init --override manipulates the specified properties of the final -manifest (there is no “values” file). Therefore you may specify any valid -value for any valid property in the deployment manifest.

- -

Override annotation

- -

In the example below we use --override to add the revision property and set -its value to 1.

- -
helm init --override metadata.annotations."deployment\.kubernetes\.io/revision"="1"
-
- -

Output:

- -
apiVersion: extensions/v1beta1
-kind: Deployment
-metadata:
-  annotations:
-    deployment.kubernetes.io/revision: "1"
-...
-
- -

Override affinity

- -

In the example below we set properties for node affinity. Multiple ---override commands may be combined to modify different properties of the -same list item.

- -
helm init --override "spec.template.spec.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution[0].weight"="1" --override "spec.template.spec.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution[0].preference.matchExpressions[0].key"="e2e-az-name"
-
- -

The specified properties are combined into the -“preferredDuringSchedulingIgnoredDuringExecution” property’s first -list item.

- -
...
-spec:
-  strategy: {}
-  template:
-    ...
-    spec:
-      affinity:
-        nodeAffinity:
-          preferredDuringSchedulingIgnoredDuringExecution:
-          - preference:
-              matchExpressions:
-              - key: e2e-az-name
-                operator: ""
-            weight: 1
-...
-
- -

Using --output

- -

The --output flag allows us skip the installation of Tiller’s deployment -manifest and simply output the deployment manifest to stdout in either -JSON or YAML format. The output may then be modified with tools like jq -and installed manually with kubectl.

- -

In the example below we execute helm init with the --output json flag.

- -
helm init --output json
-
- -

The Tiller installation is skipped and the manifest is output to stdout -in JSON format.

- -
"apiVersion": "extensions/v1beta1",
-"kind": "Deployment",
-"metadata": {
-    "creationTimestamp": null,
-    "labels": {
-        "app": "helm",
-        "name": "tiller"
-    },
-    "name": "tiller-deploy",
-    "namespace": "kube-system"
-},
-...
-
- -

Storage backends

- -

By default, tiller stores release information in ConfigMaps in the namespace -where it is running. As of Helm 2.7.0, there is now a beta storage backend that -uses Secrets for storing release information. This was added for additional -security in protecting charts in conjunction with the release of Secret -encryption in Kubernetes.

- -

To enable the secrets backend, you’ll need to init Tiller with the following -options:

- -
helm init --override 'spec.template.spec.containers[0].command'='{/tiller,--storage=secret}'
-
- -

Currently, if you want to switch from the default backend to the secrets -backend, you’ll have to do the migration for this on your own. When this backend -graduates from beta, there will be a more official path of migration

- -

Conclusion

- -

In most cases, installation is as simple as getting a pre-built helm binary -and running helm init. This document covers additional cases for those -who want to do more sophisticated things with Helm.

- -

Once you have the Helm Client and Tiller successfully installed, you can -move on to using Helm to manage charts.

- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/install_faq/index.html b/docs.helm.sh/rootfs/public/install_faq/index.html deleted file mode 100644 index 391f08a0bf..0000000000 --- a/docs.helm.sh/rootfs/public/install_faq/index.html +++ /dev/null @@ -1,1553 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

Installation: Frequently Asked Questions

- -

This section tracks some of the more frequently encountered issues with installing -or getting started with Helm.

- -

We’d love your help making this document better. To add, correct, or remove -information, file an issue or -send us a pull request.

- -

Downloading

- -

I want to know more about my downloading options.

- -

Q: I can’t get to GitHub releases of the newest Helm. Where are they?

- -

A: We no longer use GitHub releases. Binaries are now stored in a -GCS public bucket.

- -

Q: Why aren’t there Debian/Fedora/… native packages of Helm?

- -

We’d love to provide these or point you toward a trusted provider. If you’re -interested in helping, we’d love it. This is how the Homebrew formula was -started.

- -

Q: Why do you provide a curl ...|bash script?

- -

A: There is a script in our repository (scripts/get) that can be executed as -a curl ..|bash script. The transfers are all protected by HTTPS, and the script -does some auditing of the packages it fetches. However, the script has all the -usual dangers of any shell script.

- -

We provide it because it is useful, but we suggest that users carefully read the -script first. What we’d really like, though, are better packaged releases of -Helm.

- -

Installing

- -

I’m trying to install Helm/Tiller, but something is not right.

- -

Q: How do I put the Helm client files somewhere other than ~/.helm?

- -

Set the $HELM_HOME environment variable, and then run helm init:

- -
export HELM_HOME=/some/path
-helm init --client-only
-
- -

Note that if you have existing repositories, you will need to re-add them -with helm repo add....

- -

Q: How do I configure Helm, but not install Tiller?

- -

A: By default, helm init will ensure that the local $HELM_HOME is configured, -and then install Tiller on your cluster. To locally configure, but not install -Tiller, use helm init --client-only.

- -

Q: How do I manually install Tiller on the cluster?

- -

A: Tiller is installed as a Kubernetes deployment. You can get the manifest -by running helm init --dry-run --debug, and then manually install it with -kubectl. It is suggested that you do not remove or change the labels on that -deployment, as they are sometimes used by supporting scripts and tools.

- -

Q: Why do I get Error response from daemon: target is unknown during Tiller install?

- -

A: Users have reported being unable to install Tiller on Kubernetes instances that -are using Docker 1.13.0. The root cause of this was a bug in Docker that made -that one version incompatible with images pushed to the Docker registry by -earlier versions of Docker.

- -

This issue was fixed shortly -after the release, and is available in Docker 1.13.1-RC1 and later.

- -

Getting Started

- -

I successfully installed Helm/Tiller but I can’t use it.

- -

Q: Trying to use Helm, I get the error “client transport was broken”

- -
E1014 02:26:32.885226   16143 portforward.go:329] an error occurred forwarding 37008 -> 44134: error forwarding port 44134 to pod tiller-deploy-2117266891-e4lev_kube-system, uid : unable to do port forwarding: socat not found.
-2016/10/14 02:26:32 transport: http2Client.notifyError got notified that the client transport was broken EOF.
-Error: transport is closing
-
- -

A: This is usually a good indication that Kubernetes is not set up to allow port forwarding.

- -

Typically, the missing piece is socat. If you are running CoreOS, we have been -told that it may have been misconfigured on installation. The CoreOS team -recommends reading this:

- - - -

Here are a few resolved issues that may help you get started:

- - - -

Q: Trying to use Helm, I get the error “lookup XXXXX on 8.8.8.8:53: no such host”

- -
Error: Error forwarding ports: error upgrading connection: dial tcp: lookup kube-4gb-lon1-02 on 8.8.8.8:53: no such host
-
- -

A: We have seen this issue with Ubuntu and Kubeadm in multi-node clusters. The -issue is that the nodes expect certain DNS records to be obtainable via global -DNS. Until this is resolved upstream, you can work around the issue as -follows. On each of the control plane nodes:

- -

1) Add entries to /etc/hosts, mapping your hostnames to their public IPs -2) Install dnsmasq (e.g. apt install -y dnsmasq) -3) Remove the k8s api server container (kubelet will recreate it) -4) Then systemctl restart docker (or reboot the node) for it to pick up the /etc/resolv.conf changes

- -

See this issue for more information: https://github.com/kubernetes/helm/issues/1455

- -

Q: On GKE (Google Container Engine) I get “No SSH tunnels currently open”

- -
Error: Error forwarding ports: error upgrading connection: No SSH tunnels currently open. Were the targets able to accept an ssh-key for user "gke-[redacted]"?
-
- -

Another variation of the error message is:

- -
Unable to connect to the server: x509: certificate signed by unknown authority
-
-
- -

A: The issue is that your local Kubernetes config file must have the correct credentials.

- -

When you create a cluster on GKE, it will give you credentials, including SSL -certificates and certificate authorities. These need to be stored in a Kubernetes -config file (Default: ~/.kube/config so that kubectl and helm can access -them.

- -

Q: When I run a Helm command, I get an error about the tunnel or proxy

- -

A: Helm uses the Kubernetes proxy service to connect to the Tiller server. -If the command kubectl proxy does not work for you, neither will Helm. -Typically, the error is related to a missing socat service.

- -

Q: Tiller crashes with a panic

- -

When I run a command on Helm, Tiller crashes with an error like this:

- -
Tiller is listening on :44134
-Probes server is listening on :44135
-Storage driver is ConfigMap
-Cannot initialize Kubernetes connection: the server has asked for the client to provide credentials 2016-12-20 15:18:40.545739 I | storage.go:37: Getting release "bailing-chinchilla" (v1) from storage
-panic: runtime error: invalid memory address or nil pointer dereference
-[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x8053d5]
-
-goroutine 77 [running]:
-panic(0x1abbfc0, 0xc42000a040)
-        /usr/local/go/src/runtime/panic.go:500 +0x1a1
-k8s.io/helm/vendor/k8s.io/kubernetes/pkg/client/unversioned.(*ConfigMaps).Get(0xc4200c6200, 0xc420536100, 0x15, 0x1ca7431, 0x6, 0xc42016b6a0)
-        /home/ubuntu/.go_workspace/src/k8s.io/helm/vendor/k8s.io/kubernetes/pkg/client/unversioned/configmap.go:58 +0x75
-k8s.io/helm/pkg/storage/driver.(*ConfigMaps).Get(0xc4201d6190, 0xc420536100, 0x15, 0xc420536100, 0x15, 0xc4205360c0)
-        /home/ubuntu/.go_workspace/src/k8s.io/helm/pkg/storage/driver/cfgmaps.go:69 +0x62
-k8s.io/helm/pkg/storage.(*Storage).Get(0xc4201d61a0, 0xc4205360c0, 0x12, 0xc400000001, 0x12, 0x0, 0xc420200070)
-        /home/ubuntu/.go_workspace/src/k8s.io/helm/pkg/storage/storage.go:38 +0x160
-k8s.io/helm/pkg/tiller.(*ReleaseServer).uniqName(0xc42002a000, 0x0, 0x0, 0xc42016b800, 0xd66a13, 0xc42055a040, 0xc420558050, 0xc420122001)
-        /home/ubuntu/.go_workspace/src/k8s.io/helm/pkg/tiller/release_server.go:577 +0xd7
-k8s.io/helm/pkg/tiller.(*ReleaseServer).prepareRelease(0xc42002a000, 0xc42027c1e0, 0xc42002a001, 0xc42016bad0, 0xc42016ba08)
-        /home/ubuntu/.go_workspace/src/k8s.io/helm/pkg/tiller/release_server.go:630 +0x71
-k8s.io/helm/pkg/tiller.(*ReleaseServer).InstallRelease(0xc42002a000, 0x7f284c434068, 0xc420250c00, 0xc42027c1e0, 0x0, 0x31a9, 0x31a9)
-        /home/ubuntu/.go_workspace/src/k8s.io/helm/pkg/tiller/release_server.go:604 +0x78
-k8s.io/helm/pkg/proto/hapi/services._ReleaseService_InstallRelease_Handler(0x1c51f80, 0xc42002a000, 0x7f284c434068, 0xc420250c00, 0xc42027c190, 0x0, 0x0, 0x0, 0x0, 0x0)
-        /home/ubuntu/.go_workspace/src/k8s.io/helm/pkg/proto/hapi/services/tiller.pb.go:747 +0x27d
-k8s.io/helm/vendor/google.golang.org/grpc.(*Server).processUnaryRPC(0xc4202f3ea0, 0x28610a0, 0xc420078000, 0xc420264690, 0xc420166150, 0x288cbe8, 0xc420250bd0, 0x0, 0x0)
-        /home/ubuntu/.go_workspace/src/k8s.io/helm/vendor/google.golang.org/grpc/server.go:608 +0xc50
-k8s.io/helm/vendor/google.golang.org/grpc.(*Server).handleStream(0xc4202f3ea0, 0x28610a0, 0xc420078000, 0xc420264690, 0xc420250bd0)
-        /home/ubuntu/.go_workspace/src/k8s.io/helm/vendor/google.golang.org/grpc/server.go:766 +0x6b0
-k8s.io/helm/vendor/google.golang.org/grpc.(*Server).serveStreams.func1.1(0xc420124710, 0xc4202f3ea0, 0x28610a0, 0xc420078000, 0xc420264690)
-        /home/ubuntu/.go_workspace/src/k8s.io/helm/vendor/google.golang.org/grpc/server.go:419 +0xab
-created by k8s.io/helm/vendor/google.golang.org/grpc.(*Server).serveStreams.func1
-        /home/ubuntu/.go_workspace/src/k8s.io/helm/vendor/google.golang.org/grpc/server.go:420 +0xa3
-
- -

A: Check your security settings for Kubernetes.

- -

A panic in Tiller is almost always the result of a failure to negotiate with the -Kubernetes API server (at which point Tiller can no longer do anything useful, so -it panics and exits).

- -

Often, this is a result of authentication failing because the Pod in which Tiller -is running does not have the right token.

- -

To fix this, you will need to change your Kubernetes configuration. Make sure -that --service-account-private-key-file from controller-manager and ---service-account-key-file from apiserver point to the same x509 RSA key.

- -

Upgrading

- -

My Helm used to work, then I upgrade. Now it is broken.

- -

Q: After upgrade, I get the error “Client version is incompatible”. What’s wrong?

- -

Tiller and Helm have to negotiate a common version to make sure that they can safely -communicate without breaking API assumptions. That error means that the version -difference is too great to safely continue. Typically, you need to upgrade -Tiller manually for this.

- -

The Installation Guide has definitive information about safely -upgrading Helm and Tiller.

- -

The rules for version numbers are as follows:

- -
    -
  • Pre-release versions are incompatible with everything else. Alpha.1 is incompatible with Alpha.2.
  • -
  • Patch revisions are compatible: 1.2.3 is compatible with 1.2.4
  • -
  • Minor revisions are not compatible: 1.2.0 is not compatible with 1.3.0, -though we may relax this constraint in the future.
  • -
  • Major revisions are not compatible: 1.0.0 is not compatible with 2.0.0.
  • -
- -

Uninstalling

- -

I am trying to remove stuff.

- -

Q: When I delete the Tiller deployment, how come all the releases are still there?

- -

Releases are stored in ConfigMaps inside of the kube-system namespace. You will -have to manually delete them to get rid of the record.

- -

Q: I want to delete my local Helm. Where are all its files?

- -

Along with the helm binary, Helm stores some files in $HELM_HOME, which is -located by default in ~/.helm.

- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/kubernetes_distros/index.html b/docs.helm.sh/rootfs/public/kubernetes_distros/index.html deleted file mode 100644 index f78214ff54..0000000000 --- a/docs.helm.sh/rootfs/public/kubernetes_distros/index.html +++ /dev/null @@ -1,1370 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

Kubernetes Distribution Guide

- -

This document captures information about using Helm in specific Kubernetes -environments.

- -

We are trying to add more details to this document. Please contribute via Pull -Requests if you can.

- -

MiniKube

- -

Helm is tested and known to work with minikube. -It requires no additional configuration.

- -

scripts/local-cluster and Hyperkube

- -

Hyperkube configured via scripts/local-cluster.sh is known to work. For raw -Hyperkube you may need to do some manual configuration.

- -

GKE

- -

Google’s GKE hosted Kubernetes platform is known to work with Helm, and requires -no additional configuration.

- -

Ubuntu with ‘kubeadm’

- -

Kubernetes bootstrapped with kubeadm is known to work on the following Linux -distributions:

- -
    -
  • Ubuntu 16.04
  • -
  • Fedora release 25
  • -
- -

Some versions of Helm (v2.0.0-beta2) require you to export KUBECONFIG=/etc/kubernetes/admin.conf -or create a ~/.kube/config.

- -

Container Linux by CoreOS

- -

Helm requires that kubelet have access to a copy of the socat program to proxy connections to the Tiller API. On Container Linux the Kubelet runs inside of a hyperkube container image that has socat. So, even though Container Linux doesn’t ship socat the container filesystem running kubelet does have socat. To learn more read the Kubelet Wrapper docs.

- -

Openshift

- -

Helm works straightforward on OpenShift Online, OpenShift Dedicated, OpenShift Container Platform (version >= 3.6) or OpenShift Origin (version >= 3.6). To learn more read this blog post.

- -

Platform9

- -

Helm Client and Helm Server (Tiller) are pre-installed with Platform9 Managed Kubernetes. Platform9 provides access to all official Helm charts through the App Catalog UI and native Kubernetes CLI. Additional repositories can be manually added. Further details are availble in this Platform9 App Catalog article.

- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/man/man1/helm.1 b/docs.helm.sh/rootfs/public/man/man1/helm.1 deleted file mode 100644 index 4128830f4a..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm.1 +++ /dev/null @@ -1,85 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm \- The Helm package manager for Kubernetes. - - -.SH SYNOPSIS -.PP -\fBhelm\fP - - -.SH DESCRIPTION -.PP -The Kubernetes package manager - -.PP -To begin working with Helm, run the 'helm init' command: - -.PP -.RS - -.nf -$ helm init - -.fi -.RE - -.PP -This will install Tiller to your running Kubernetes cluster. -It will also set up any necessary local configuration. - -.PP -Common actions from this point include: -.IP \(bu 2 -helm search: search for charts -.IP \(bu 2 -helm fetch: download a chart to your local directory to view -.IP \(bu 2 -helm install: upload the chart to Kubernetes -.IP \(bu 2 -helm list: list releases of charts - -.PP -Environment: - $HELM\_HOME set an alternative location for Helm files. By default, these are stored in \~/.helm - $HELM\_HOST set an alternative Tiller host. The format is host:port - $HELM\_NO\_PLUGINS disable plugins. Set HELM\_NO\_PLUGINS=1 to disable plugins. - $TILLER\_NAMESPACE set an alternative Tiller namespace (default "kube\-namespace") - $KUBECONFIG set an alternative Kubernetes configuration file (default "\~/.kube/config") - - -.SH OPTIONS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm\-completion(1)\fP, \fBhelm\-create(1)\fP, \fBhelm\-delete(1)\fP, \fBhelm\-dependency(1)\fP, \fBhelm\-fetch(1)\fP, \fBhelm\-get(1)\fP, \fBhelm\-history(1)\fP, \fBhelm\-home(1)\fP, \fBhelm\-init(1)\fP, \fBhelm\-inspect(1)\fP, \fBhelm\-install(1)\fP, \fBhelm\-lint(1)\fP, \fBhelm\-list(1)\fP, \fBhelm\-package(1)\fP, \fBhelm\-plugin(1)\fP, \fBhelm\-repo(1)\fP, \fBhelm\-reset(1)\fP, \fBhelm\-rollback(1)\fP, \fBhelm\-search(1)\fP, \fBhelm\-serve(1)\fP, \fBhelm\-status(1)\fP, \fBhelm\-test(1)\fP, \fBhelm\-upgrade(1)\fP, \fBhelm\-verify(1)\fP, \fBhelm\-version(1)\fP - - -.SH HISTORY -.PP -19\-May\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/man/man1/helm_completion.1 b/docs.helm.sh/rootfs/public/man/man1/helm_completion.1 deleted file mode 100644 index 83217073f6..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm_completion.1 +++ /dev/null @@ -1,74 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm\-completion \- Generate autocompletions script for the specified shell (bash or zsh) - - -.SH SYNOPSIS -.PP -\fBhelm completion SHELL\fP - - -.SH DESCRIPTION -.PP -Generate autocompletions script for Helm for the specified shell (bash or zsh). - -.PP -This command can generate shell autocompletions. e.g. - -.PP -.RS - -.nf -$ helm completion bash - -.fi -.RE - -.PP -Can be sourced as such - -.PP -.RS - -.nf -$ source <(helm completion bash) - -.fi -.RE - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm(1)\fP - - -.SH HISTORY -.PP -19\-May\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/man/man1/helm_create.1 b/docs.helm.sh/rootfs/public/man/man1/helm_create.1 deleted file mode 100644 index 3a1f4b26f4..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm_create.1 +++ /dev/null @@ -1,86 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm\-create \- create a new chart with the given name - - -.SH SYNOPSIS -.PP -\fBhelm create NAME\fP - - -.SH DESCRIPTION -.PP -This command creates a chart directory along with the common files and -directories used in a chart. - -.PP -For example, 'helm create foo' will create a directory structure that looks -something like this: - -.PP -.RS - -.nf -foo/ - | - |\- .helmignore # Contains patterns to ignore when packaging Helm charts. - | - |\- Chart.yaml # Information about your chart - | - |\- values.yaml # The default values for your templates - | - |\- charts/ # Charts that this chart depends on - | - |\- templates/ # The template files - -.fi -.RE - -.PP -\&'helm create' takes a path for an argument. If directories in the given path -do not exist, Helm will attempt to create them as it goes. If the given -destination exists and there are files in that directory, conflicting files -will be overwritten, but other files will be left alone. - - -.SH OPTIONS -.PP -\fB\-p\fP, \fB\-\-starter\fP="" - the named Helm starter scaffold - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm(1)\fP - - -.SH HISTORY -.PP -19\-May\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/man/man1/helm_delete.1 b/docs.helm.sh/rootfs/public/man/man1/helm_delete.1 deleted file mode 100644 index ecce68398f..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm_delete.1 +++ /dev/null @@ -1,93 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm\-delete \- given a release name, delete the release from Kubernetes - - -.SH SYNOPSIS -.PP -\fBhelm delete [flags] RELEASE\_NAME [...]\fP - - -.SH DESCRIPTION -.PP -This command takes a release name, and then deletes the release from Kubernetes. -It removes all of the resources associated with the last release of the chart. - -.PP -Use the '\-\-dry\-run' flag to see which releases will be deleted without actually -deleting them. - - -.SH OPTIONS -.PP -\fB\-\-dry\-run\fP[=false] - simulate a delete - -.PP -\fB\-\-no\-hooks\fP[=false] - prevent hooks from running during deletion - -.PP -\fB\-\-purge\fP[=false] - remove the release from the store and make its name free for later use - -.PP -\fB\-\-timeout\fP=300 - time in seconds to wait for any individual kubernetes operation (like Jobs for hooks) - -.PP -\fB\-\-tls\fP[=false] - enable TLS for request - -.PP -\fB\-\-tls\-ca\-cert\fP="$HELM\_HOME/ca.pem" - path to TLS CA certificate file - -.PP -\fB\-\-tls\-cert\fP="$HELM\_HOME/cert.pem" - path to TLS certificate file - -.PP -\fB\-\-tls\-key\fP="$HELM\_HOME/key.pem" - path to TLS key file - -.PP -\fB\-\-tls\-verify\fP[=false] - enable TLS for request and verify remote - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm(1)\fP - - -.SH HISTORY -.PP -19\-May\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/man/man1/helm_dependency.1 b/docs.helm.sh/rootfs/public/man/man1/helm_dependency.1 deleted file mode 100644 index fd4fc195e7..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm_dependency.1 +++ /dev/null @@ -1,117 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm\-dependency \- manage a chart's dependencies - - -.SH SYNOPSIS -.PP -\fBhelm dependency update|build|list\fP - - -.SH DESCRIPTION -.PP -Manage the dependencies of a chart. - -.PP -Helm charts store their dependencies in 'charts/'. For chart developers, it is -often easier to manage a single dependency file ('requirements.yaml') -which declares all dependencies. - -.PP -The dependency commands operate on that file, making it easy to synchronize -between the desired dependencies and the actual dependencies stored in the -'charts/' directory. - -.PP -A 'requirements.yaml' file is a YAML file in which developers can declare chart -dependencies, along with the location of the chart and the desired version. -For example, this requirements file declares two dependencies: - -.PP -.RS - -.nf -# requirements.yaml -dependencies: -\- name: nginx - version: "1.2.3" - repository: "https://example.com/charts" -\- name: memcached - version: "3.2.1" - repository: "https://another.example.com/charts" - -.fi -.RE - -.PP -The 'name' should be the name of a chart, where that name must match the name -in that chart's 'Chart.yaml' file. - -.PP -The 'version' field should contain a semantic version or version range. - -.PP -The 'repository' URL should point to a Chart Repository. Helm expects that by -appending '/index.yaml' to the URL, it should be able to retrieve the chart -repository's index. Note: 'repository' cannot be a repository alias. It must be -a URL. - -.PP -Starting from 2.2.0, repository can be defined as the path to the directory of -the dependency charts stored locally. The path should start with a prefix of -"file://". For example, - -.PP -.RS - -.nf -# requirements.yaml -dependencies: -\- name: nginx - version: "1.2.3" - repository: "file://../dependency\_chart/nginx" - -.fi -.RE - -.PP -If the dependency chart is retrieved locally, it is not required to have the -repository added to helm by "helm add repo". Version matching is also supported -for this case. - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm(1)\fP, \fBhelm\-dependency\-build(1)\fP, \fBhelm\-dependency\-list(1)\fP, \fBhelm\-dependency\-update(1)\fP - - -.SH HISTORY -.PP -19\-May\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/man/man1/helm_dependency_build.1 b/docs.helm.sh/rootfs/public/man/man1/helm_dependency_build.1 deleted file mode 100644 index adc225a815..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm_dependency_build.1 +++ /dev/null @@ -1,69 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm\-dependency\-build \- rebuild the charts/ directory based on the requirements.lock file - - -.SH SYNOPSIS -.PP -\fBhelm dependency build [flags] CHART\fP - - -.SH DESCRIPTION -.PP -Build out the charts/ directory from the requirements.lock file. - -.PP -Build is used to reconstruct a chart's dependencies to the state specified in -the lock file. This will not re\-negotiate dependencies, as 'helm dependency update' -does. - -.PP -If no lock file is found, 'helm dependency build' will mirror the behavior -of 'helm dependency update'. - - -.SH OPTIONS -.PP -\fB\-\-keyring\fP="~/.gnupg/pubring.gpg" - keyring containing public keys - -.PP -\fB\-\-verify\fP[=false] - verify the packages against signatures - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm\-dependency(1)\fP - - -.SH HISTORY -.PP -19\-May\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/man/man1/helm_dependency_list.1 b/docs.helm.sh/rootfs/public/man/man1/helm_dependency_list.1 deleted file mode 100644 index 30a686bb41..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm_dependency_list.1 +++ /dev/null @@ -1,58 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm\-dependency\-list \- list the dependencies for the given chart - - -.SH SYNOPSIS -.PP -\fBhelm dependency list [flags] CHART\fP - - -.SH DESCRIPTION -.PP -List all of the dependencies declared in a chart. - -.PP -This can take chart archives and chart directories as input. It will not alter -the contents of a chart. - -.PP -This will produce an error if the chart cannot be loaded. It will emit a warning -if it cannot find a requirements.yaml. - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm\-dependency(1)\fP - - -.SH HISTORY -.PP -19\-May\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/man/man1/helm_dependency_update.1 b/docs.helm.sh/rootfs/public/man/man1/helm_dependency_update.1 deleted file mode 100644 index 02d9ec94bd..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm_dependency_update.1 +++ /dev/null @@ -1,78 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm\-dependency\-update \- update charts/ based on the contents of requirements.yaml - - -.SH SYNOPSIS -.PP -\fBhelm dependency update [flags] CHART\fP - - -.SH DESCRIPTION -.PP -Update the on\-disk dependencies to mirror the requirements.yaml file. - -.PP -This command verifies that the required charts, as expressed in 'requirements.yaml', -are present in 'charts/' and are at an acceptable version. It will pull down -the latest charts that satisfy the dependencies, and clean up old dependencies. - -.PP -On successful update, this will generate a lock file that can be used to -rebuild the requirements to an exact version. - -.PP -Dependencies are not required to be represented in 'requirements.yaml'. For that -reason, an update command will not remove charts unless they are (a) present -in the requirements.yaml file, but (b) at the wrong version. - - -.SH OPTIONS -.PP -\fB\-\-keyring\fP="~/.gnupg/pubring.gpg" - keyring containing public keys - -.PP -\fB\-\-skip\-refresh\fP[=false] - do not refresh the local repository cache - -.PP -\fB\-\-verify\fP[=false] - verify the packages against signatures - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm\-dependency(1)\fP - - -.SH HISTORY -.PP -19\-May\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/man/man1/helm_fetch.1 b/docs.helm.sh/rootfs/public/man/man1/helm_fetch.1 deleted file mode 100644 index 9a8ad185c1..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm_fetch.1 +++ /dev/null @@ -1,114 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm\-fetch \- download a chart from a repository and (optionally) unpack it in local directory - - -.SH SYNOPSIS -.PP -\fBhelm fetch [flags] [chart URL | repo/chartname] [...]\fP - - -.SH DESCRIPTION -.PP -Retrieve a package from a package repository, and download it locally. - -.PP -This is useful for fetching packages to inspect, modify, or repackage. It can -also be used to perform cryptographic verification of a chart without installing -the chart. - -.PP -There are options for unpacking the chart after download. This will create a -directory for the chart and uncomparess into that directory. - -.PP -If the \-\-verify flag is specified, the requested chart MUST have a provenance -file, and MUST pass the verification process. Failure in any part of this will -result in an error, and the chart will not be saved locally. - - -.SH OPTIONS -.PP -\fB\-\-ca\-file\fP="" - verify certificates of HTTPS\-enabled servers using this CA bundle - -.PP -\fB\-\-cert\-file\fP="" - identify HTTPS client using this SSL certificate file - -.PP -\fB\-d\fP, \fB\-\-destination\fP="." - location to write the chart. If this and tardir are specified, tardir is appended to this - -.PP -\fB\-\-devel\fP[=false] - use development versions, too. Equivalent to version '>0.0.0\-a'. If \-\-version is set, this is ignored. - -.PP -\fB\-\-key\-file\fP="" - identify HTTPS client using this SSL key file - -.PP -\fB\-\-keyring\fP="~/.gnupg/pubring.gpg" - keyring containing public keys - -.PP -\fB\-\-prov\fP[=false] - fetch the provenance file, but don't perform verification - -.PP -\fB\-\-repo\fP="" - chart repository url where to locate the requested chart - -.PP -\fB\-\-untar\fP[=false] - if set to true, will untar the chart after downloading it - -.PP -\fB\-\-untardir\fP="." - if untar is specified, this flag specifies the name of the directory into which the chart is expanded - -.PP -\fB\-\-verify\fP[=false] - verify the package against its signature - -.PP -\fB\-\-version\fP="" - specific version of a chart. Without this, the latest version is fetched - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm(1)\fP - - -.SH HISTORY -.PP -19\-May\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/man/man1/helm_get.1 b/docs.helm.sh/rootfs/public/man/man1/helm_get.1 deleted file mode 100644 index e680f49dcd..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm_get.1 +++ /dev/null @@ -1,89 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm\-get \- download a named release - - -.SH SYNOPSIS -.PP -\fBhelm get [flags] RELEASE\_NAME\fP - - -.SH DESCRIPTION -.PP -This command shows the details of a named release. - -.PP -It can be used to get extended information about the release, including: -.IP \(bu 2 -The values used to generate the release -.IP \(bu 2 -The chart used to generate the release -.IP \(bu 2 -The generated manifest file - -.PP -By default, this prints a human readable collection of information about the -chart, the supplied values, and the generated manifest file. - - -.SH OPTIONS -.PP -\fB\-\-revision\fP=0 - get the named release with revision - -.PP -\fB\-\-tls\fP[=false] - enable TLS for request - -.PP -\fB\-\-tls\-ca\-cert\fP="$HELM\_HOME/ca.pem" - path to TLS CA certificate file - -.PP -\fB\-\-tls\-cert\fP="$HELM\_HOME/cert.pem" - path to TLS certificate file - -.PP -\fB\-\-tls\-key\fP="$HELM\_HOME/key.pem" - path to TLS key file - -.PP -\fB\-\-tls\-verify\fP[=false] - enable TLS for request and verify remote - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm(1)\fP, \fBhelm\-get\-hooks(1)\fP, \fBhelm\-get\-manifest(1)\fP, \fBhelm\-get\-values(1)\fP - - -.SH HISTORY -.PP -19\-May\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/man/man1/helm_get_hooks.1 b/docs.helm.sh/rootfs/public/man/man1/helm_get_hooks.1 deleted file mode 100644 index 34e460d193..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm_get_hooks.1 +++ /dev/null @@ -1,59 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm\-get\-hooks \- download all hooks for a named release - - -.SH SYNOPSIS -.PP -\fBhelm get hooks [flags] RELEASE\_NAME\fP - - -.SH DESCRIPTION -.PP -This command downloads hooks for a given release. - -.PP -Hooks are formatted in YAML and separated by the YAML '\-\-\-\\n' separator. - - -.SH OPTIONS -.PP -\fB\-\-revision\fP=0 - get the named release with revision - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm\-get(1)\fP - - -.SH HISTORY -.PP -19\-May\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/man/man1/helm_get_manifest.1 b/docs.helm.sh/rootfs/public/man/man1/helm_get_manifest.1 deleted file mode 100644 index 7132db38e5..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm_get_manifest.1 +++ /dev/null @@ -1,61 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm\-get\-manifest \- download the manifest for a named release - - -.SH SYNOPSIS -.PP -\fBhelm get manifest [flags] RELEASE\_NAME\fP - - -.SH DESCRIPTION -.PP -This command fetches the generated manifest for a given release. - -.PP -A manifest is a YAML\-encoded representation of the Kubernetes resources that -were generated from this release's chart(s). If a chart is dependent on other -charts, those resources will also be included in the manifest. - - -.SH OPTIONS -.PP -\fB\-\-revision\fP=0 - get the named release with revision - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm\-get(1)\fP - - -.SH HISTORY -.PP -19\-May\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/man/man1/helm_get_values.1 b/docs.helm.sh/rootfs/public/man/man1/helm_get_values.1 deleted file mode 100644 index 349f97c144..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm_get_values.1 +++ /dev/null @@ -1,60 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm\-get\-values \- download the values file for a named release - - -.SH SYNOPSIS -.PP -\fBhelm get values [flags] RELEASE\_NAME\fP - - -.SH DESCRIPTION -.PP -This command downloads a values file for a given release. - - -.SH OPTIONS -.PP -\fB\-a\fP, \fB\-\-all\fP[=false] - dump all (computed) values - -.PP -\fB\-\-revision\fP=0 - get the named release with revision - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm\-get(1)\fP - - -.SH HISTORY -.PP -19\-May\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/man/man1/helm_history.1 b/docs.helm.sh/rootfs/public/man/man1/helm_history.1 deleted file mode 100644 index 40789ef927..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm_history.1 +++ /dev/null @@ -1,97 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm\-history \- fetch release history - - -.SH SYNOPSIS -.PP -\fBhelm history [flags] RELEASE\_NAME\fP - - -.SH DESCRIPTION -.PP -History prints historical revisions for a given release. - -.PP -A default maximum of 256 revisions will be returned. Setting '\-\-max' -configures the maximum length of the revision list returned. - -.PP -The historical release set is printed as a formatted table, e.g: - -.PP -.RS - -.nf -$ helm history angry\-bird \-\-max=4 -REVISION UPDATED STATUS CHART DESCRIPTION -1 Mon Oct 3 10:15:13 2016 SUPERSEDED alpine\-0.1.0 Initial install -2 Mon Oct 3 10:15:13 2016 SUPERSEDED alpine\-0.1.0 Upgraded successfully -3 Mon Oct 3 10:15:13 2016 SUPERSEDED alpine\-0.1.0 Rolled back to 2 -4 Mon Oct 3 10:15:13 2016 DEPLOYED alpine\-0.1.0 Upgraded successfully - -.fi -.RE - - -.SH OPTIONS -.PP -\fB\-\-max\fP=256 - maximum number of revision to include in history - -.PP -\fB\-\-tls\fP[=false] - enable TLS for request - -.PP -\fB\-\-tls\-ca\-cert\fP="$HELM\_HOME/ca.pem" - path to TLS CA certificate file - -.PP -\fB\-\-tls\-cert\fP="$HELM\_HOME/cert.pem" - path to TLS certificate file - -.PP -\fB\-\-tls\-key\fP="$HELM\_HOME/key.pem" - path to TLS key file - -.PP -\fB\-\-tls\-verify\fP[=false] - enable TLS for request and verify remote - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm(1)\fP - - -.SH HISTORY -.PP -19\-May\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/man/man1/helm_home.1 b/docs.helm.sh/rootfs/public/man/man1/helm_home.1 deleted file mode 100644 index 77024d53eb..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm_home.1 +++ /dev/null @@ -1,51 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm\-home \- displays the location of HELM\_HOME - - -.SH SYNOPSIS -.PP -\fBhelm home\fP - - -.SH DESCRIPTION -.PP -This command displays the location of HELM\_HOME. This is where -any helm configuration files live. - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm(1)\fP - - -.SH HISTORY -.PP -19\-May\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/man/man1/helm_init.1 b/docs.helm.sh/rootfs/public/man/man1/helm_init.1 deleted file mode 100644 index 74871ebe81..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm_init.1 +++ /dev/null @@ -1,135 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm\-init \- initialize Helm on both client and server - - -.SH SYNOPSIS -.PP -\fBhelm init\fP - - -.SH DESCRIPTION -.PP -This command installs Tiller (the helm server side component) onto your -Kubernetes Cluster and sets up local configuration in $HELM\_HOME (default \~/.helm/) - -.PP -As with the rest of the Helm commands, 'helm init' discovers Kubernetes clusters -by reading $KUBECONFIG (default '\~/.kube/config') and using the default context. - -.PP -To set up just a local environment, use '\-\-client\-only'. That will configure -$HELM\_HOME, but not attempt to connect to a remote cluster and install the Tiller -deployment. - -.PP -When installing Tiller, 'helm init' will attempt to install the latest released -version. You can specify an alternative image with '\-\-tiller\-image'. For those -frequently working on the latest code, the flag '\-\-canary\-image' will install -the latest pre\-release version of Tiller (e.g. the HEAD commit in the GitHub -repository on the master branch). - -.PP -To dump a manifest containing the Tiller deployment YAML, combine the -'\-\-dry\-run' and '\-\-debug' flags. - - -.SH OPTIONS -.PP -\fB\-\-canary\-image\fP[=false] - use the canary tiller image - -.PP -\fB\-c\fP, \fB\-\-client\-only\fP[=false] - if set does not install tiller - -.PP -\fB\-\-dry\-run\fP[=false] - do not install local or remote - -.PP -\fB\-\-local\-repo\-url\fP=" -\[la]http://127.0.0.1:8879/charts"\[ra] - URL for local repository - -.PP -\fB\-\-net\-host\fP[=false] - install tiller with net=host - -.PP -\fB\-\-service\-account\fP="" - name of service account - -.PP -\fB\-\-skip\-refresh\fP[=false] - do not refresh (download) the local repository cache - -.PP -\fB\-\-stable\-repo\-url\fP=" -\[la]https://kubernetes-charts.storage.googleapis.com"\[ra] - URL for stable repository - -.PP -\fB\-i\fP, \fB\-\-tiller\-image\fP="" - override tiller image - -.PP -\fB\-\-tiller\-tls\fP[=false] - install tiller with TLS enabled - -.PP -\fB\-\-tiller\-tls\-cert\fP="" - path to TLS certificate file to install with tiller - -.PP -\fB\-\-tiller\-tls\-key\fP="" - path to TLS key file to install with tiller - -.PP -\fB\-\-tiller\-tls\-verify\fP[=false] - install tiller with TLS enabled and to verify remote certificates - -.PP -\fB\-\-tls\-ca\-cert\fP="" - path to CA root certificate - -.PP -\fB\-\-upgrade\fP[=false] - upgrade if tiller is already installed - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm(1)\fP - - -.SH HISTORY -.PP -19\-May\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/man/man1/helm_inspect.1 b/docs.helm.sh/rootfs/public/man/man1/helm_inspect.1 deleted file mode 100644 index 0783476c7c..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm_inspect.1 +++ /dev/null @@ -1,84 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm\-inspect \- inspect a chart - - -.SH SYNOPSIS -.PP -\fBhelm inspect [CHART]\fP - - -.SH DESCRIPTION -.PP -This command inspects a chart and displays information. It takes a chart reference -('stable/drupal'), a full path to a directory or packaged chart, or a URL. - -.PP -Inspect prints the contents of the Chart.yaml file and the values.yaml file. - - -.SH OPTIONS -.PP -\fB\-\-ca\-file\fP="" - chart repository url where to locate the requested chart - -.PP -\fB\-\-cert\-file\fP="" - verify certificates of HTTPS\-enabled servers using this CA bundle - -.PP -\fB\-\-key\-file\fP="" - identify HTTPS client using this SSL key file - -.PP -\fB\-\-keyring\fP="~/.gnupg/pubring.gpg" - path to the keyring containing public verification keys - -.PP -\fB\-\-repo\fP="" - chart repository url where to locate the requested chart - -.PP -\fB\-\-verify\fP[=false] - verify the provenance data for this chart - -.PP -\fB\-\-version\fP="" - version of the chart. By default, the newest chart is shown - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm(1)\fP, \fBhelm\-inspect\-chart(1)\fP, \fBhelm\-inspect\-values(1)\fP - - -.SH HISTORY -.PP -19\-May\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/man/man1/helm_inspect_chart.1 b/docs.helm.sh/rootfs/public/man/man1/helm_inspect_chart.1 deleted file mode 100644 index f728df410d..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm_inspect_chart.1 +++ /dev/null @@ -1,81 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm\-inspect\-chart \- shows inspect chart - - -.SH SYNOPSIS -.PP -\fBhelm inspect chart [CHART]\fP - - -.SH DESCRIPTION -.PP -This command inspects a chart (directory, file, or URL) and displays the contents -of the Charts.yaml file - - -.SH OPTIONS -.PP -\fB\-\-ca\-file\fP="" - chart repository url where to locate the requested chart - -.PP -\fB\-\-cert\-file\fP="" - verify certificates of HTTPS\-enabled servers using this CA bundle - -.PP -\fB\-\-key\-file\fP="" - identify HTTPS client using this SSL key file - -.PP -\fB\-\-keyring\fP="~/.gnupg/pubring.gpg" - path to the keyring containing public verification keys - -.PP -\fB\-\-repo\fP="" - chart repository url where to locate the requested chart - -.PP -\fB\-\-verify\fP[=false] - verify the provenance data for this chart - -.PP -\fB\-\-version\fP="" - version of the chart. By default, the newest chart is shown - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm\-inspect(1)\fP - - -.SH HISTORY -.PP -19\-May\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/man/man1/helm_inspect_values.1 b/docs.helm.sh/rootfs/public/man/man1/helm_inspect_values.1 deleted file mode 100644 index c87dd9c602..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm_inspect_values.1 +++ /dev/null @@ -1,81 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm\-inspect\-values \- shows inspect values - - -.SH SYNOPSIS -.PP -\fBhelm inspect values [CHART]\fP - - -.SH DESCRIPTION -.PP -This command inspects a chart (directory, file, or URL) and displays the contents -of the values.yaml file - - -.SH OPTIONS -.PP -\fB\-\-ca\-file\fP="" - chart repository url where to locate the requested chart - -.PP -\fB\-\-cert\-file\fP="" - verify certificates of HTTPS\-enabled servers using this CA bundle - -.PP -\fB\-\-key\-file\fP="" - identify HTTPS client using this SSL key file - -.PP -\fB\-\-keyring\fP="~/.gnupg/pubring.gpg" - path to the keyring containing public verification keys - -.PP -\fB\-\-repo\fP="" - chart repository url where to locate the requested chart - -.PP -\fB\-\-verify\fP[=false] - verify the provenance data for this chart - -.PP -\fB\-\-version\fP="" - version of the chart. By default, the newest chart is shown - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm\-inspect(1)\fP - - -.SH HISTORY -.PP -19\-May\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/man/man1/helm_install.1 b/docs.helm.sh/rootfs/public/man/man1/helm_install.1 deleted file mode 100644 index fe1856bed2..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm_install.1 +++ /dev/null @@ -1,243 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm\-install \- install a chart archive - - -.SH SYNOPSIS -.PP -\fBhelm install [CHART]\fP - - -.SH DESCRIPTION -.PP -This command installs a chart archive. - -.PP -The install argument must be a chart reference, a path to a packaged chart, -a path to an unpacked chart directory or a URL. - -.PP -To override values in a chart, use either the '\-\-values' flag and pass in a file -or use the '\-\-set' flag and pass configuration from the command line. - -.PP -.RS - -.nf -$ helm install \-f myvalues.yaml ./redis - -.fi -.RE - -.PP -or - -.PP -.RS - -.nf -$ helm install \-\-set name=prod ./redis - -.fi -.RE - -.PP -You can specify the '\-\-values'/'\-f' flag multiple times. The priority will be given to the -last (right\-most) file specified. For example, if both myvalues.yaml and override.yaml -contained a key called 'Test', the value set in override.yaml would take precedence: - -.PP -.RS - -.nf -$ helm install \-f myvalues.yaml \-f override.yaml ./redis - -.fi -.RE - -.PP -You can specify the '\-\-set' flag multiple times. The priority will be given to the -last (right\-most) set specified. For example, if both 'bar' and 'newbar' values are -set for a key called 'foo', the 'newbar' value would take precedence: - -.PP -.RS - -.nf -$ helm install \-\-set foo=bar \-\-set foo=newbar ./redis - -.fi -.RE - -.PP -To check the generated manifests of a release without installing the chart, -the '\-\-debug' and '\-\-dry\-run' flags can be combined. This will still require a -round\-trip to the Tiller server. - -.PP -If \-\-verify is set, the chart MUST have a provenance file, and the provenenace -fall MUST pass all verification steps. - -.PP -There are four different ways you can express the chart you want to install: -.IP " 1." 5 -By chart reference: helm install stable/mariadb -.IP " 2." 5 -By path to a packaged chart: helm install ./nginx\-1.2.3.tgz -.IP " 3." 5 -By path to an unpacked chart directory: helm install ./nginx -.IP " 4." 5 -By absolute URL: helm install -\[la]https://example.com/charts/nginx-1.2.3.tgz\[ra] - -.PP -CHART REFERENCES - -.PP -A chart reference is a convenient way of reference a chart in a chart repository. - -.PP -When you use a chart reference ('stable/mariadb'), Helm will look in the local -configuration for a chart repository named 'stable', and will then look for a -chart in that repository whose name is 'mariadb'. It will install the latest -version of that chart unless you also supply a version number with the -'\-\-version' flag. - -.PP -To see the list of chart repositories, use 'helm repo list'. To search for -charts in a repository, use 'helm search'. - - -.SH OPTIONS -.PP -\fB\-\-ca\-file\fP="" - verify certificates of HTTPS\-enabled servers using this CA bundle - -.PP -\fB\-\-cert\-file\fP="" - identify HTTPS client using this SSL certificate file - -.PP -\fB\-\-dep\-up\fP[=false] - run helm dependency update before installing the chart. - -.PP -\fB\-\-devel\fP[=false] - use development versions, too. Equivalent to version '>0.0.0\-a'. If \-\-version is set, this is ignored. - -.PP -\fB\-\-dry\-run\fP[=false] - simulate an install - -.PP -\fB\-\-key\-file\fP="" - identify HTTPS client using this SSL key file - -.PP -\fB\-\-keyring\fP="~/.gnupg/pubring.gpg" - location of public keys used for verification - -.PP -\fB\-n\fP, \fB\-\-name\fP="" - release name. If unspecified, it will autogenerate one for you - -.PP -\fB\-\-name\-template\fP="" - specify template used to name the release - -.PP -\fB\-\-namespace\fP="" - namespace to install the release into - -.PP -\fB\-\-no\-hooks\fP[=false] - prevent hooks from running during install - -.PP -\fB\-\-replace\fP[=false] - re\-use the given name, even if that name is already used. This is unsafe in production - -.PP -\fB\-\-repo\fP="" - chart repository url where to locate the requested chart - -.PP -\fB\-\-set\fP=[] - set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) - -.PP -\fB\-\-timeout\fP=300 - time in seconds to wait for any individual kubernetes operation (like Jobs for hooks) - -.PP -\fB\-\-tls\fP[=false] - enable TLS for request - -.PP -\fB\-\-tls\-ca\-cert\fP="$HELM\_HOME/ca.pem" - path to TLS CA certificate file - -.PP -\fB\-\-tls\-cert\fP="$HELM\_HOME/cert.pem" - path to TLS certificate file - -.PP -\fB\-\-tls\-key\fP="$HELM\_HOME/key.pem" - path to TLS key file - -.PP -\fB\-\-tls\-verify\fP[=false] - enable TLS for request and verify remote - -.PP -\fB\-f\fP, \fB\-\-values\fP=[] - specify values in a YAML file or a URL(can specify multiple) - -.PP -\fB\-\-verify\fP[=false] - verify the package before installing it - -.PP -\fB\-\-version\fP="" - specify the exact chart version to install. If this is not specified, the latest version is installed - -.PP -\fB\-\-wait\fP[=false] - if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment are in a ready state before marking the release as successful. It will wait for as long as \-\-timeout - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm(1)\fP - - -.SH HISTORY -.PP -31\-Oct\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/man/man1/helm_lint.1 b/docs.helm.sh/rootfs/public/man/man1/helm_lint.1 deleted file mode 100644 index e0d5226859..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm_lint.1 +++ /dev/null @@ -1,62 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm\-lint \- examines a chart for possible issues - - -.SH SYNOPSIS -.PP -\fBhelm lint [flags] PATH\fP - - -.SH DESCRIPTION -.PP -This command takes a path to a chart and runs a series of tests to verify that -the chart is well\-formed. - -.PP -If the linter encounters things that will cause the chart to fail installation, -it will emit [ERROR] messages. If it encounters issues that break with convention -or recommendation, it will emit [WARNING] messages. - - -.SH OPTIONS -.PP -\fB\-\-strict\fP[=false] - fail on lint warnings - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm(1)\fP - - -.SH HISTORY -.PP -19\-May\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/man/man1/helm_list.1 b/docs.helm.sh/rootfs/public/man/man1/helm_list.1 deleted file mode 100644 index d4fccf9605..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm_list.1 +++ /dev/null @@ -1,151 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm\-list \- list releases - - -.SH SYNOPSIS -.PP -\fBhelm list [flags] [FILTER]\fP - - -.SH DESCRIPTION -.PP -This command lists all of the releases. - -.PP -By default, it lists only releases that are deployed or failed. Flags like -'\-\-deleted' and '\-\-all' will alter this behavior. Such flags can be combined: -'\-\-deleted \-\-failed'. - -.PP -By default, items are sorted alphabetically. Use the '\-d' flag to sort by -release date. - -.PP -If an argument is provided, it will be treated as a filter. Filters are -regular expressions (Perl compatible) that are applied to the list of releases. -Only items that match the filter will be returned. - -.PP -.RS - -.nf -$ helm list 'ara[a\-z]+' -NAME UPDATED CHART -maudlin\-arachnid Mon May 9 16:07:08 2016 alpine\-0.1.0 - -.fi -.RE - -.PP -If no results are found, 'helm list' will exit 0, but with no output (or in -the case of no '\-q' flag, only headers). - -.PP -By default, up to 256 items may be returned. To limit this, use the '\-\-max' flag. -Setting '\-\-max' to 0 will not return all results. Rather, it will return the -server's default, which may be much higher than 256. Pairing the '\-\-max' -flag with the '\-\-offset' flag allows you to page through results. - - -.SH OPTIONS -.PP -\fB\-\-all\fP[=false] - show all releases, not just the ones marked DEPLOYED - -.PP -\fB\-d\fP, \fB\-\-date\fP[=false] - sort by release date - -.PP -\fB\-\-deleted\fP[=false] - show deleted releases - -.PP -\fB\-\-deleting\fP[=false] - show releases that are currently being deleted - -.PP -\fB\-\-deployed\fP[=false] - show deployed releases. If no other is specified, this will be automatically enabled - -.PP -\fB\-\-failed\fP[=false] - show failed releases - -.PP -\fB\-m\fP, \fB\-\-max\fP=256 - maximum number of releases to fetch - -.PP -\fB\-\-namespace\fP="" - show releases within a specific namespace - -.PP -\fB\-o\fP, \fB\-\-offset\fP="" - next release name in the list, used to offset from start value - -.PP -\fB\-r\fP, \fB\-\-reverse\fP[=false] - reverse the sort order - -.PP -\fB\-q\fP, \fB\-\-short\fP[=false] - output short (quiet) listing format - -.PP -\fB\-\-tls\fP[=false] - enable TLS for request - -.PP -\fB\-\-tls\-ca\-cert\fP="$HELM\_HOME/ca.pem" - path to TLS CA certificate file - -.PP -\fB\-\-tls\-cert\fP="$HELM\_HOME/cert.pem" - path to TLS certificate file - -.PP -\fB\-\-tls\-key\fP="$HELM\_HOME/key.pem" - path to TLS key file - -.PP -\fB\-\-tls\-verify\fP[=false] - enable TLS for request and verify remote - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm(1)\fP - - -.SH HISTORY -.PP -19\-May\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/man/man1/helm_package.1 b/docs.helm.sh/rootfs/public/man/man1/helm_package.1 deleted file mode 100644 index 07185a4c22..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm_package.1 +++ /dev/null @@ -1,85 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm\-package \- package a chart directory into a chart archive - - -.SH SYNOPSIS -.PP -\fBhelm package [flags] [CHART\_PATH] [...]\fP - - -.SH DESCRIPTION -.PP -This command packages a chart into a versioned chart archive file. If a path -is given, this will look at that path for a chart (which must contain a -Chart.yaml file) and then package that directory. - -.PP -If no path is given, this will look in the present working directory for a -Chart.yaml file, and (if found) build the current directory into a chart. - -.PP -Versioned chart archives are used by Helm package repositories. - - -.SH OPTIONS -.PP -\fB\-d\fP, \fB\-\-destination\fP="." - location to write the chart. - -.PP -\fB\-\-key\fP="" - name of the key to use when signing. Used if \-\-sign is true - -.PP -\fB\-\-keyring\fP="~/.gnupg/pubring.gpg" - location of a public keyring - -.PP -\fB\-\-save\fP[=true] - save packaged chart to local chart repository - -.PP -\fB\-\-sign\fP[=false] - use a PGP private key to sign this package - -.PP -\fB\-\-version\fP="" - set the version on the chart to this semver version - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm(1)\fP - - -.SH HISTORY -.PP -19\-May\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/man/man1/helm_plugin.1 b/docs.helm.sh/rootfs/public/man/man1/helm_plugin.1 deleted file mode 100644 index 7af4f39fcb..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm_plugin.1 +++ /dev/null @@ -1,50 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm\-plugin \- add, list, or remove Helm plugins - - -.SH SYNOPSIS -.PP -\fBhelm plugin\fP - - -.SH DESCRIPTION -.PP -Manage client\-side Helm plugins. - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm(1)\fP, \fBhelm\-plugin\-install(1)\fP, \fBhelm\-plugin\-list(1)\fP, \fBhelm\-plugin\-remove(1)\fP, \fBhelm\-plugin\-update(1)\fP - - -.SH HISTORY -.PP -19\-May\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/man/man1/helm_plugin_install.1 b/docs.helm.sh/rootfs/public/man/man1/helm_plugin_install.1 deleted file mode 100644 index d2a8d13260..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm_plugin_install.1 +++ /dev/null @@ -1,56 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm\-plugin\-install \- install one or more Helm plugins - - -.SH SYNOPSIS -.PP -\fBhelm plugin install [options] \&...\fP - - -.SH DESCRIPTION -.PP -install one or more Helm plugins - - -.SH OPTIONS -.PP -\fB\-\-version\fP="" - specify a version constraint. If this is not specified, the latest version is installed - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm\-plugin(1)\fP - - -.SH HISTORY -.PP -19\-May\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/man/man1/helm_plugin_list.1 b/docs.helm.sh/rootfs/public/man/man1/helm_plugin_list.1 deleted file mode 100644 index 5fcebd748b..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm_plugin_list.1 +++ /dev/null @@ -1,50 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm\-plugin\-list \- list installed Helm plugins - - -.SH SYNOPSIS -.PP -\fBhelm plugin list\fP - - -.SH DESCRIPTION -.PP -list installed Helm plugins - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm\-plugin(1)\fP - - -.SH HISTORY -.PP -19\-May\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/man/man1/helm_plugin_remove.1 b/docs.helm.sh/rootfs/public/man/man1/helm_plugin_remove.1 deleted file mode 100644 index de64220dda..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm_plugin_remove.1 +++ /dev/null @@ -1,50 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm\-plugin\-remove \- remove one or more Helm plugins - - -.SH SYNOPSIS -.PP -\fBhelm plugin remove \&...\fP - - -.SH DESCRIPTION -.PP -remove one or more Helm plugins - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm\-plugin(1)\fP - - -.SH HISTORY -.PP -19\-May\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/man/man1/helm_plugin_update.1 b/docs.helm.sh/rootfs/public/man/man1/helm_plugin_update.1 deleted file mode 100644 index ad7d70a174..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm_plugin_update.1 +++ /dev/null @@ -1,50 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm\-plugin\-update \- update one or more Helm plugins - - -.SH SYNOPSIS -.PP -\fBhelm plugin update \&...\fP - - -.SH DESCRIPTION -.PP -update one or more Helm plugins - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm\-plugin(1)\fP - - -.SH HISTORY -.PP -19\-May\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/man/man1/helm_repo.1 b/docs.helm.sh/rootfs/public/man/man1/helm_repo.1 deleted file mode 100644 index 19b2da8a3d..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm_repo.1 +++ /dev/null @@ -1,55 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm\-repo \- add, list, remove, update, and index chart repositories - - -.SH SYNOPSIS -.PP -\fBhelm repo [FLAGS] add|remove|list|index|update [ARGS]\fP - - -.SH DESCRIPTION -.PP -This command consists of multiple subcommands to interact with chart repositories. - -.PP -It can be used to add, remove, list, and index chart repositories. -Example usage: - $ helm repo add [NAME] [REPO\_URL] - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm(1)\fP, \fBhelm\-repo\-add(1)\fP, \fBhelm\-repo\-index(1)\fP, \fBhelm\-repo\-list(1)\fP, \fBhelm\-repo\-remove(1)\fP, \fBhelm\-repo\-update(1)\fP - - -.SH HISTORY -.PP -19\-May\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/man/man1/helm_repo_add.1 b/docs.helm.sh/rootfs/public/man/man1/helm_repo_add.1 deleted file mode 100644 index 3cd9f790b8..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm_repo_add.1 +++ /dev/null @@ -1,68 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm\-repo\-add \- add a chart repository - - -.SH SYNOPSIS -.PP -\fBhelm repo add [flags] [NAME] [URL]\fP - - -.SH DESCRIPTION -.PP -add a chart repository - - -.SH OPTIONS -.PP -\fB\-\-ca\-file\fP="" - verify certificates of HTTPS\-enabled servers using this CA bundle - -.PP -\fB\-\-cert\-file\fP="" - identify HTTPS client using this SSL certificate file - -.PP -\fB\-\-key\-file\fP="" - identify HTTPS client using this SSL key file - -.PP -\fB\-\-no\-update\fP[=false] - raise error if repo is already registered - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm\-repo(1)\fP - - -.SH HISTORY -.PP -19\-May\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/man/man1/helm_repo_index.1 b/docs.helm.sh/rootfs/public/man/man1/helm_repo_index.1 deleted file mode 100644 index edfcda6f55..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm_repo_index.1 +++ /dev/null @@ -1,69 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm\-repo\-index \- generate an index file given a directory containing packaged charts - - -.SH SYNOPSIS -.PP -\fBhelm repo index [flags] [DIR]\fP - - -.SH DESCRIPTION -.PP -Read the current directory and generate an index file based on the charts found. - -.PP -This tool is used for creating an 'index.yaml' file for a chart repository. To -set an absolute URL to the charts, use '\-\-url' flag. - -.PP -To merge the generated index with an existing index file, use the '\-\-merge' -flag. In this case, the charts found in the current directory will be merged -into the existing index, with local charts taking priority over existing charts. - - -.SH OPTIONS -.PP -\fB\-\-merge\fP="" - merge the generated index into the given index - -.PP -\fB\-\-url\fP="" - url of chart repository - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm\-repo(1)\fP - - -.SH HISTORY -.PP -19\-May\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/man/man1/helm_repo_list.1 b/docs.helm.sh/rootfs/public/man/man1/helm_repo_list.1 deleted file mode 100644 index 7623f73fe6..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm_repo_list.1 +++ /dev/null @@ -1,50 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm\-repo\-list \- list chart repositories - - -.SH SYNOPSIS -.PP -\fBhelm repo list [flags]\fP - - -.SH DESCRIPTION -.PP -list chart repositories - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm\-repo(1)\fP - - -.SH HISTORY -.PP -19\-May\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/man/man1/helm_repo_remove.1 b/docs.helm.sh/rootfs/public/man/man1/helm_repo_remove.1 deleted file mode 100644 index cfbf217a44..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm_repo_remove.1 +++ /dev/null @@ -1,50 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm\-repo\-remove \- remove a chart repository - - -.SH SYNOPSIS -.PP -\fBhelm repo remove [flags] [NAME]\fP - - -.SH DESCRIPTION -.PP -remove a chart repository - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm\-repo(1)\fP - - -.SH HISTORY -.PP -19\-May\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/man/man1/helm_repo_update.1 b/docs.helm.sh/rootfs/public/man/man1/helm_repo_update.1 deleted file mode 100644 index 42bf511dd1..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm_repo_update.1 +++ /dev/null @@ -1,55 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm\-repo\-update \- update information of available charts locally from chart repositories - - -.SH SYNOPSIS -.PP -\fBhelm repo update\fP - - -.SH DESCRIPTION -.PP -Update gets the latest information about charts from the respective chart repositories. -Information is cached locally, where it is used by commands like 'helm search'. - -.PP -\&'helm update' is the deprecated form of 'helm repo update'. It will be removed in -future releases. - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm\-repo(1)\fP - - -.SH HISTORY -.PP -19\-May\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/man/man1/helm_reset.1 b/docs.helm.sh/rootfs/public/man/man1/helm_reset.1 deleted file mode 100644 index bf735591d2..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm_reset.1 +++ /dev/null @@ -1,82 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm\-reset \- uninstalls Tiller from a cluster - - -.SH SYNOPSIS -.PP -\fBhelm reset\fP - - -.SH DESCRIPTION -.PP -This command uninstalls Tiller (the helm server side component) from your -Kubernetes Cluster and optionally deletes local configuration in -$HELM\_HOME (default \~/.helm/) - - -.SH OPTIONS -.PP -\fB\-f\fP, \fB\-\-force\fP[=false] - forces Tiller uninstall even if there are releases installed - -.PP -\fB\-\-remove\-helm\-home\fP[=false] - if set deletes $HELM\_HOME - -.PP -\fB\-\-tls\fP[=false] - enable TLS for request - -.PP -\fB\-\-tls\-ca\-cert\fP="$HELM\_HOME/ca.pem" - path to TLS CA certificate file - -.PP -\fB\-\-tls\-cert\fP="$HELM\_HOME/cert.pem" - path to TLS certificate file - -.PP -\fB\-\-tls\-key\fP="$HELM\_HOME/key.pem" - path to TLS key file - -.PP -\fB\-\-tls\-verify\fP[=false] - enable TLS for request and verify remote - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm(1)\fP - - -.SH HISTORY -.PP -19\-May\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/man/man1/helm_rollback.1 b/docs.helm.sh/rootfs/public/man/man1/helm_rollback.1 deleted file mode 100644 index d91ab881d8..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm_rollback.1 +++ /dev/null @@ -1,101 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm\-rollback \- roll back a release to a previous revision - - -.SH SYNOPSIS -.PP -\fBhelm rollback [flags] [RELEASE] [REVISION]\fP - - -.SH DESCRIPTION -.PP -This command rolls back a release to a previous revision. - -.PP -The first argument of the rollback command is the name of a release, and the -second is a revision (version) number. To see revision numbers, run -'helm history RELEASE'. - - -.SH OPTIONS -.PP -\fB\-\-dry\-run\fP[=false] - simulate a rollback - -.PP -\fB\-\-force\fP[=false] - force resource update through delete/recreate if needed - -.PP -\fB\-\-no\-hooks\fP[=false] - prevent hooks from running during rollback - -.PP -\fB\-\-recreate\-pods\fP[=false] - performs pods restart for the resource if applicable - -.PP -\fB\-\-timeout\fP=300 - time in seconds to wait for any individual kubernetes operation (like Jobs for hooks) - -.PP -\fB\-\-tls\fP[=false] - enable TLS for request - -.PP -\fB\-\-tls\-ca\-cert\fP="$HELM\_HOME/ca.pem" - path to TLS CA certificate file - -.PP -\fB\-\-tls\-cert\fP="$HELM\_HOME/cert.pem" - path to TLS certificate file - -.PP -\fB\-\-tls\-key\fP="$HELM\_HOME/key.pem" - path to TLS key file - -.PP -\fB\-\-tls\-verify\fP[=false] - enable TLS for request and verify remote - -.PP -\fB\-\-wait\fP[=false] - if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment are in a ready state before marking the release as successful. It will wait for as long as \-\-timeout - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm(1)\fP - - -.SH HISTORY -.PP -19\-May\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/man/man1/helm_search.1 b/docs.helm.sh/rootfs/public/man/man1/helm_search.1 deleted file mode 100644 index ac2467bf25..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm_search.1 +++ /dev/null @@ -1,68 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm\-search \- search for a keyword in charts - - -.SH SYNOPSIS -.PP -\fBhelm search [keyword]\fP - - -.SH DESCRIPTION -.PP -Search reads through all of the repositories configured on the system, and -looks for matches. - -.PP -Repositories are managed with 'helm repo' commands. - - -.SH OPTIONS -.PP -\fB\-r\fP, \fB\-\-regexp\fP[=false] - use regular expressions for searching - -.PP -\fB\-v\fP, \fB\-\-version\fP="" - search using semantic versioning constraints - -.PP -\fB\-l\fP, \fB\-\-versions\fP[=false] - show the long listing, with each version of each chart on its own line - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm(1)\fP - - -.SH HISTORY -.PP -19\-May\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/man/man1/helm_serve.1 b/docs.helm.sh/rootfs/public/man/man1/helm_serve.1 deleted file mode 100644 index a4a9c51da7..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm_serve.1 +++ /dev/null @@ -1,79 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm\-serve \- start a local http web server - - -.SH SYNOPSIS -.PP -\fBhelm serve\fP - - -.SH DESCRIPTION -.PP -This command starts a local chart repository server that serves charts from a local directory. - -.PP -The new server will provide HTTP access to a repository. By default, it will -scan all of the charts in '$HELM\_HOME/repository/local' and serve those over -the local IPv4 TCP port (default '127.0.0.1:8879'). - -.PP -This command is intended to be used for educational and testing purposes only. -It is best to rely on a dedicated web server or a cloud\-hosted solution like -Google Cloud Storage for production use. - -.PP -See -\[la]https://github.com/kubernetes/helm/blob/master/docs/chart_repository.md#hosting-chart-repositories\[ra] -for more information on hosting chart repositories in a production setting. - - -.SH OPTIONS -.PP -\fB\-\-address\fP="127.0.0.1:8879" - address to listen on - -.PP -\fB\-\-repo\-path\fP="" - local directory path from which to serve charts - -.PP -\fB\-\-url\fP="" - external URL of chart repository - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm(1)\fP - - -.SH HISTORY -.PP -19\-May\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/man/man1/helm_status.1 b/docs.helm.sh/rootfs/public/man/man1/helm_status.1 deleted file mode 100644 index 8f23668089..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm_status.1 +++ /dev/null @@ -1,83 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm\-status \- displays the status of the named release - - -.SH SYNOPSIS -.PP -\fBhelm status [flags] RELEASE\_NAME\fP - - -.SH DESCRIPTION -.PP -This command shows the status of a named release. -The status consists of: -\- last deployment time -\- k8s namespace in which the release lives -\- state of the release (can be: UNKNOWN, DEPLOYED, DELETED, SUPERSEDED, FAILED or DELETING) -\- list of resources that this release consists of, sorted by kind -\- details on last test suite run, if applicable -\- additional notes provided by the chart - - -.SH OPTIONS -.PP -\fB\-\-revision\fP=0 - if set, display the status of the named release with revision - -.PP -\fB\-\-tls\fP[=false] - enable TLS for request - -.PP -\fB\-\-tls\-ca\-cert\fP="$HELM\_HOME/ca.pem" - path to TLS CA certificate file - -.PP -\fB\-\-tls\-cert\fP="$HELM\_HOME/cert.pem" - path to TLS certificate file - -.PP -\fB\-\-tls\-key\fP="$HELM\_HOME/key.pem" - path to TLS key file - -.PP -\fB\-\-tls\-verify\fP[=false] - enable TLS for request and verify remote - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm(1)\fP - - -.SH HISTORY -.PP -19\-May\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/man/man1/helm_test.1 b/docs.helm.sh/rootfs/public/man/man1/helm_test.1 deleted file mode 100644 index 6da36b33b5..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm_test.1 +++ /dev/null @@ -1,84 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm\-test \- test a release - - -.SH SYNOPSIS -.PP -\fBhelm test [RELEASE]\fP - - -.SH DESCRIPTION -.PP -The test command runs the tests for a release. - -.PP -The argument this command takes is the name of a deployed release. -The tests to be run are defined in the chart that was installed. - - -.SH OPTIONS -.PP -\fB\-\-cleanup\fP[=false] - delete test pods upon completion - -.PP -\fB\-\-timeout\fP=300 - time in seconds to wait for any individual kubernetes operation (like Jobs for hooks) - -.PP -\fB\-\-tls\fP[=false] - enable TLS for request - -.PP -\fB\-\-tls\-ca\-cert\fP="$HELM\_HOME/ca.pem" - path to TLS CA certificate file - -.PP -\fB\-\-tls\-cert\fP="$HELM\_HOME/cert.pem" - path to TLS certificate file - -.PP -\fB\-\-tls\-key\fP="$HELM\_HOME/key.pem" - path to TLS key file - -.PP -\fB\-\-tls\-verify\fP[=false] - enable TLS for request and verify remote - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm(1)\fP - - -.SH HISTORY -.PP -19\-May\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/man/man1/helm_upgrade.1 b/docs.helm.sh/rootfs/public/man/man1/helm_upgrade.1 deleted file mode 100644 index 24bba7c85d..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm_upgrade.1 +++ /dev/null @@ -1,190 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm\-upgrade \- upgrade a release - - -.SH SYNOPSIS -.PP -\fBhelm upgrade [RELEASE] [CHART]\fP - - -.SH DESCRIPTION -.PP -This command upgrades a release to a new version of a chart. - -.PP -The upgrade arguments must be a release and chart. The chart -argument can be either: a chart reference('stable/mariadb'), a path to a chart directory, -a packaged chart, or a fully qualified URL. For chart references, the latest -version will be specified unless the '\-\-version' flag is set. - -.PP -To override values in a chart, use either the '\-\-values' flag and pass in a file -or use the '\-\-set' flag and pass configuration from the command line. - -.PP -You can specify the '\-\-values'/'\-f' flag multiple times. The priority will be given to the -last (right\-most) file specified. For example, if both myvalues.yaml and override.yaml -contained a key called 'Test', the value set in override.yaml would take precedence: - -.PP -.RS - -.nf -$ helm upgrade \-f myvalues.yaml \-f override.yaml redis ./redis - -.fi -.RE - -.PP -You can specify the '\-\-set' flag multiple times. The priority will be given to the -last (right\-most) set specified. For example, if both 'bar' and 'newbar' values are -set for a key called 'foo', the 'newbar' value would take precedence: - -.PP -.RS - -.nf -$ helm upgrade \-\-set foo=bar \-\-set foo=newbar redis ./redis - -.fi -.RE - - -.SH OPTIONS -.PP -\fB\-\-ca\-file\fP="" - verify certificates of HTTPS\-enabled servers using this CA bundle - -.PP -\fB\-\-cert\-file\fP="" - identify HTTPS client using this SSL certificate file - -.PP -\fB\-\-devel\fP[=false] - use development versions, too. Equivalent to version '>0.0.0\-a'. If \-\-version is set, this is ignored. - -.PP -\fB\-\-dry\-run\fP[=false] - simulate an upgrade - -.PP -\fB\-\-force\fP[=false] - force resource update through delete/recreate if needed - -.PP -\fB\-i\fP, \fB\-\-install\fP[=false] - if a release by this name doesn't already exist, run an install - -.PP -\fB\-\-key\-file\fP="" - identify HTTPS client using this SSL key file - -.PP -\fB\-\-keyring\fP="~/.gnupg/pubring.gpg" - path to the keyring that contains public signing keys - -.PP -\fB\-\-namespace\fP="default" - namespace to install the release into (only used if \-\-install is set) - -.PP -\fB\-\-no\-hooks\fP[=false] - disable pre/post upgrade hooks - -.PP -\fB\-\-recreate\-pods\fP[=false] - performs pods restart for the resource if applicable - -.PP -\fB\-\-repo\fP="" - chart repository url where to locate the requested chart - -.PP -\fB\-\-reset\-values\fP[=false] - when upgrading, reset the values to the ones built into the chart - -.PP -\fB\-\-reuse\-values\fP[=false] - when upgrading, reuse the last release's values, and merge in any new values. If '\-\-reset\-values' is specified, this is ignored. - -.PP -\fB\-\-set\fP=[] - set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) - -.PP -\fB\-\-timeout\fP=300 - time in seconds to wait for any individual kubernetes operation (like Jobs for hooks) - -.PP -\fB\-\-tls\fP[=false] - enable TLS for request - -.PP -\fB\-\-tls\-ca\-cert\fP="$HELM\_HOME/ca.pem" - path to TLS CA certificate file - -.PP -\fB\-\-tls\-cert\fP="$HELM\_HOME/cert.pem" - path to TLS certificate file - -.PP -\fB\-\-tls\-key\fP="$HELM\_HOME/key.pem" - path to TLS key file - -.PP -\fB\-\-tls\-verify\fP[=false] - enable TLS for request and verify remote - -.PP -\fB\-f\fP, \fB\-\-values\fP=[] - specify values in a YAML file or a URL(can specify multiple) - -.PP -\fB\-\-verify\fP[=false] - verify the provenance of the chart before upgrading - -.PP -\fB\-\-version\fP="" - specify the exact chart version to use. If this is not specified, the latest version is used - -.PP -\fB\-\-wait\fP[=false] - if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment are in a ready state before marking the release as successful. It will wait for as long as \-\-timeout - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm(1)\fP - - -.SH HISTORY -.PP -19\-May\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/man/man1/helm_verify.1 b/docs.helm.sh/rootfs/public/man/man1/helm_verify.1 deleted file mode 100644 index 5297924ae8..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm_verify.1 +++ /dev/null @@ -1,65 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm\-verify \- verify that a chart at the given path has been signed and is valid - - -.SH SYNOPSIS -.PP -\fBhelm verify [flags] PATH\fP - - -.SH DESCRIPTION -.PP -Verify that the given chart has a valid provenance file. - -.PP -Provenance files provide crytographic verification that a chart has not been -tampered with, and was packaged by a trusted provider. - -.PP -This command can be used to verify a local chart. Several other commands provide -'\-\-verify' flags that run the same validation. To generate a signed package, use -the 'helm package \-\-sign' command. - - -.SH OPTIONS -.PP -\fB\-\-keyring\fP="~/.gnupg/pubring.gpg" - keyring containing public keys - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm(1)\fP - - -.SH HISTORY -.PP -19\-May\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/man/man1/helm_version.1 b/docs.helm.sh/rootfs/public/man/man1/helm_version.1 deleted file mode 100644 index 1f1bf600d0..0000000000 --- a/docs.helm.sh/rootfs/public/man/man1/helm_version.1 +++ /dev/null @@ -1,103 +0,0 @@ -.TH "HELM" "1" "May 2017" "Auto generated by spf13/cobra" "" -.nh -.ad l - - -.SH NAME -.PP -helm\-version \- print the client/server version information - - -.SH SYNOPSIS -.PP -\fBhelm version\fP - - -.SH DESCRIPTION -.PP -Show the client and server versions for Helm and tiller. - -.PP -This will print a representation of the client and server versions of Helm and -Tiller. The output will look something like this: - -.PP -Client: \&version.Version{SemVer:"v2.0.0", GitCommit:"ff52399e51bb880526e9cd0ed8386f6433b74da1", GitTreeState:"clean"} -Server: \&version.Version{SemVer:"v2.0.0", GitCommit:"b0c113dfb9f612a9add796549da66c0d294508a3", GitTreeState:"clean"} -.IP \(bu 2 -SemVer is the semantic version of the release. -.IP \(bu 2 -GitCommit is the SHA for the commit that this version was built from. -.IP \(bu 2 -GitTreeState is "clean" if there are no local code changes when this binary was -built, and "dirty" if the binary was built from locally modified code. - -.PP -To print just the client version, use '\-\-client'. To print just the server version, -use '\-\-server'. - - -.SH OPTIONS -.PP -\fB\-c\fP, \fB\-\-client\fP[=false] - client version only - -.PP -\fB\-s\fP, \fB\-\-server\fP[=false] - server version only - -.PP -\fB\-\-short\fP[=false] - print the version number - -.PP -\fB\-\-tls\fP[=false] - enable TLS for request - -.PP -\fB\-\-tls\-ca\-cert\fP="$HELM\_HOME/ca.pem" - path to TLS CA certificate file - -.PP -\fB\-\-tls\-cert\fP="$HELM\_HOME/cert.pem" - path to TLS certificate file - -.PP -\fB\-\-tls\-key\fP="$HELM\_HOME/key.pem" - path to TLS key file - -.PP -\fB\-\-tls\-verify\fP[=false] - enable TLS for request and verify remote - - -.SH OPTIONS INHERITED FROM PARENT COMMANDS -.PP -\fB\-\-debug\fP[=false] - enable verbose output - -.PP -\fB\-\-home\fP="~/.helm" - location of your Helm config. Overrides $HELM\_HOME - -.PP -\fB\-\-host\fP="localhost:44134" - address of tiller. Overrides $HELM\_HOST - -.PP -\fB\-\-kube\-context\fP="" - name of the kubeconfig context to use - -.PP -\fB\-\-tiller\-namespace\fP="kube\-system" - namespace of tiller - - -.SH SEE ALSO -.PP -\fBhelm(1)\fP - - -.SH HISTORY -.PP -19\-May\-2017 Auto generated by spf13/cobra diff --git a/docs.helm.sh/rootfs/public/plugins/index.html b/docs.helm.sh/rootfs/public/plugins/index.html deleted file mode 100644 index 7be90ff306..0000000000 --- a/docs.helm.sh/rootfs/public/plugins/index.html +++ /dev/null @@ -1,1533 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

The Helm Plugins Guide

- -

Helm 2.1.0 introduced the concept of a client-side Helm plugin. A plugin is a -tool that can be accessed through the helm CLI, but which is not part of the -built-in Helm codebase.

- -

Existing plugins can be found on related section or by searching Github.

- -

This guide explains how to use and create plugins.

- -

An Overview

- -

Helm plugins are add-on tools that integrate seamlessly with Helm. They provide -a way to extend the core feature set of Helm, but without requiring every new -feature to be written in Go and added to the core tool.

- -

Helm plugins have the following features:

- -
    -
  • They can be added and removed from a Helm installation without impacting the -core Helm tool.
  • -
  • They can be written in any programming language.
  • -
  • They integrate with Helm, and will show up in helm help and other places.
  • -
- -

Helm plugins live in $(helm home)/plugins.

- -

The Helm plugin model is partially modeled on Git’s plugin model. To that end, -you may sometimes hear helm referred to as the porcelain layer, with -plugins being the plumbing. This is a shorthand way of suggesting that -Helm provides the user experience and top level processing logic, while the -plugins do the “detail work” of performing a desired action.

- -

Installing a Plugin

- -

Plugins are installed using the $ helm plugin install <path|url> command. You can pass in a path to a plugin on your local file system or a url of a remote VCS repo. The helm plugin install command clones or copies the plugin at the path/url given into $ (helm home)/plugins

- -
$ helm plugin install https://github.com/technosophos/helm-template
-
- -

If you have a plugin tar distribution, simply untar the plugin into the -$(helm home)/plugins directory.

- -

You can also install tarball plugins directly from url by issuing helm plugin install http://domain/path/to/plugin.tar.gz

- -

Building Plugins

- -

In many ways, a plugin is similar to a chart. Each plugin has a top-level -directory, and then a plugin.yaml file.

- -
$(helm home)/plugins/
-  |- keybase/
-      |
-      |- plugin.yaml
-      |- keybase.sh
-
-
- -

In the example above, the keybase plugin is contained inside of a directory -named keybase. It has two files: plugin.yaml (required) and an executable -script, keybase.sh (optional).

- -

The core of a plugin is a simple YAML file named plugin.yaml. -Here is a plugin YAML for a plugin that adds support for Keybase operations:

- -
name: "keybase"
-version: "0.1.0"
-usage: "Integrate Keybase.io tools with Helm"
-description: |-
-  This plugin provides Keybase services to Helm.
-ignoreFlags: false
-useTunnel: false
-command: "$HELM_PLUGIN_DIR/keybase.sh"
-
- -

The name is the name of the plugin. When Helm executes it plugin, this is the -name it will use (e.g. helm NAME will invoke this plugin).

- -

name should match the directory name. In our example above, that means the -plugin with name: keybase should be contained in a directory named keybase.

- -

Restrictions on name:

- -
    -
  • name cannot duplicate one of the existing helm top-level commands.
  • -
  • name must be restricted to the characters ASCII a-z, A-Z, 0-9, _ and -.
  • -
- -

version is the SemVer 2 version of the plugin. -usage and description are both used to generate the help text of a command.

- -

The ignoreFlags switch tells Helm to not pass flags to the plugin. So if a -plugin is called with helm myplugin --foo and ignoreFlags: true, then --foo -is silently discarded.

- -

The useTunnel switch indicates that the plugin needs a tunnel to Tiller. This -should be set to true anytime a plugin talks to Tiller. It will cause Helm -to open a tunnel, and then set $TILLER_HOST to the right local address for that -tunnel. But don’t worry: if Helm detects that a tunnel is not necessary because -Tiller is running locally, it will not create the tunnel.

- -

Finally, and most importantly, command is the command that this plugin will -execute when it is called. Environment variables are interpolated before the plugin -is executed. The pattern above illustrates the preferred way to indicate where -the plugin program lives.

- -

There are some strategies for working with plugin commands:

- -
    -
  • If a plugin includes an executable, the executable for a command: should be -packaged in the plugin directory.
  • -
  • The command: line will have any environment variables expanded before -execution. $HELM_PLUGIN_DIR will point to the plugin directory.
  • -
  • The command itself is not executed in a shell. So you can’t oneline a shell script.
  • -
  • Helm injects lots of configuration into environment variables. Take a look at -the environment to see what information is available.
  • -
  • Helm makes no assumptions about the language of the plugin. You can write it -in whatever you prefer.
  • -
  • Commands are responsible for implementing specific help text for -h and --help. -Helm will use usage and description for helm help and helm help myplugin, -but will not handle helm myplugin --help.
  • -
- -

Downloader Plugins

- -

By default, Helm is able to fetch Charts using HTTP/S. As of Helm 2.4.0, plugins -can have a special capability to download Charts from arbitrary sources.

- -

Plugins shall declare this special capability in the plugin.yaml file (top level):

- -
downloaders:
-- command: "bin/mydownloader"
-  protocols:
-  - "myprotocol"
-  - "myprotocols"
-
- -

If such plugin is installed, Helm can interact with the repository using the specified -protocol scheme by invoking the command. The special repository shall be added -similarily to the regular ones: helm repo add favorite myprotocol://example.com/ -The rules for the special repos are the same to the regular ones: Helm must be able -to download the index.yaml file in order to discover and cache the list of -available Charts.

- -

The defined command will be invoked with the following scheme: -command certFile keyFile caFile full-URL. The SSL credentials are coming from the -repo definition, stored in $HELM_HOME/repository/repositories.yaml. Downloader -plugin is expected to dump the raw content to stdout and report errors on stderr.

- -

Environment Variables

- -

When Helm executes a plugin, it passes the outer environment to the plugin, and -also injects some additional environment variables.

- -

Variables like KUBECONFIG are set for the plugin if they are set in the -outer environment.

- -

The following variables are guaranteed to be set:

- -
    -
  • HELM_PLUGIN: The path to the plugins directory
  • -
  • HELM_PLUGIN_NAME: The name of the plugin, as invoked by helm. So -helm myplug will have the short name myplug.
  • -
  • HELM_PLUGIN_DIR: The directory that contains the plugin.
  • -
  • HELM_BIN: The path to the helm command (as executed by the user).
  • -
  • HELM_HOME: The path to the Helm home.
  • -
  • HELM_PATH_*: Paths to important Helm files and directories are stored in -environment variables prefixed by HELM_PATH.
  • -
  • TILLER_HOST: The domain:port to Tiller. If a tunnel is created, this -will point to the local endpoint for the tunnel. Otherwise, it will point -to $HELM_HOST, --host, or the default host (according to Helm’s rules of -precedence).
  • -
- -

While HELM_HOST may be set, there is no guarantee that it will point to the -correct Tiller instance. This is done to allow plugin developer to access -HELM_HOST in its raw state when the plugin itself needs to manually configure -a connection.

- -

A Note on useTunnel

- -

If a plugin specifies useTunnel: true, Helm will do the following (in order):

- -
    -
  1. Parse global flags and the environment
  2. -
  3. Create the tunnel
  4. -
  5. Set TILLER_HOST
  6. -
  7. Execute the plugin
  8. -
  9. Close the tunnel
  10. -
- -

The tunnel is removed as soon as the command returns. So, for example, a -command cannot background a process and assume that that process will be able -to use the tunnel.

- -

A Note on Flag Parsing

- -

When executing a plugin, Helm will parse global flags for its own use. Some of -these flags are not passed on to the plugin.

- -
    -
  • --debug: If this is specified, $HELM_DEBUG is set to 1
  • -
  • --home: This is converted to $HELM_HOME
  • -
  • --host: This is converted to $HELM_HOST
  • -
  • --kube-context: This is simply dropped. If your plugin uses useTunnel, this -is used to set up the tunnel for you.
  • -
- -

Plugins should display help text and then exit for -h and --help. In all -other cases, plugins may use flags as appropriate.

- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/provenance/index.html b/docs.helm.sh/rootfs/public/provenance/index.html deleted file mode 100644 index 61b26749db..0000000000 --- a/docs.helm.sh/rootfs/public/provenance/index.html +++ /dev/null @@ -1,1606 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

Helm Provenance and Integrity

- -

Helm has provenance tools which help chart users verify the integrity and origin -of a package. Using industry-standard tools based on PKI, GnuPG, and well-respected -package managers, Helm can generate and verify signature files.

- -

Note: -Version 2.0.0-alpha.4 introduced a system for verifying the authenticity of charts. -While we do not anticipate that any major changes will be made to the file formats -or provenancing algorithms, this portion of Helm is not considered frozen until -2.0.0-RC1 is released. The original plan for this feature can be found -at issue 983.

- -

Overview

- -

Integrity is established by comparing a chart to a provenance record. Provenance -records are stored in provenance files, which are stored alongside a packaged -chart. For example, if a chart is named myapp-1.2.3.tgz, its provenance file -will be myapp-1.2.3.tgz.prov.

- -

Provenance files are generated at packaging time (helm package --sign ...), and -can be checked by multiple commands, notable helm install --verify.

- -

The Workflow

- -

This section describes a potential workflow for using provenance data effectively.

- -

Prerequisites:

- -
    -
  • A valid PGP keypair in a binary (not ASCII-armored) format
  • -
  • The helm command line tool
  • -
  • GnuPG command line tools (optional)
  • -
  • Keybase command line tools (optional)
  • -
- -

NOTE: If your PGP private key has a passphrase, you will be prompted to enter -that passphrase for any commands that support the --sign option.

- -

Creating a new chart is the same as before:

- -
$ helm create mychart
-Creating mychart
-
- -

Once ready to package, add the --sign flag to helm package. Also, specify -the name under which the signing key is known and the keyring containing the corresponding private key:

- -
$ helm package --sign --key 'helm signing key' --keyring path/to/keyring.secret mychart
-
- -

TIP: for GnuPG users, your secret keyring is in ~/.gnupg/secring.gpg. You can -use gpg --list-secret-keys to list the keys you have.

- -

At this point, you should see both mychart-0.1.0.tgz and mychart-0.1.0.tgz.prov. -Both files should eventually be uploaded to your desired chart repository.

- -

You can verify a chart using helm verify:

- -
$ helm verify mychart-0.1.0.tgz
-
- -

A failed verification looks like this:

- -
$ helm verify topchart-0.1.0.tgz
-Error: sha256 sum does not match for topchart-0.1.0.tgz: "sha256:1939fbf7c1023d2f6b865d137bbb600e0c42061c3235528b1e8c82f4450c12a7" != "sha256:5a391a90de56778dd3274e47d789a2c84e0e106e1a37ef8cfa51fd60ac9e623a"
-
- -

To verify during an install, use the --verify flag.

- -
$ helm install --verify mychart-0.1.0.tgz
-
- -

If the keyring (containing the public key associated with the signed chart) is not in the default location, you may need to point to the -keyring with --keyring PATH as in the helm package example.

- -

If verification fails, the install will be aborted before the chart is even pushed -up to Tiller.

- -

Using Keybase.io credentials

- -

The Keybase.io service makes it easy to establish a chain of -trust for a cryptographic identity. Keybase credentials can be used to sign charts.

- -

Prerequisites:

- -
    -
  • A configured Keybase.io account
  • -
  • GnuPG installed locally
  • -
  • The keybase CLI installed locally
  • -
- -

Signing packages

- -

The first step is to import your keybase keys into your local GnuPG keyring:

- -
$ keybase pgp export -s | gpg --import
-
- -

This will convert your Keybase key into the OpenPGP format, and then import it -locally into your ~/.gnupg/secring.gpg file.

- -

You can double check by running gpg --list-secret-keys.

- -
$ gpg --list-secret-keys                                                                                                       1 ↵
-/Users/mattbutcher/.gnupg/secring.gpg
--------------------------------------
-sec   2048R/1FC18762 2016-07-25
-uid                  technosophos (keybase.io/technosophos) <technosophos@keybase.io>
-ssb   2048R/D125E546 2016-07-25
-
- -

Note that your secret key will have an identifier string:

- -
technosophos (keybase.io/technosophos) <technosophos@keybase.io>
-
- -

That is the full name of your key.

- -

Next, you can package and sign a chart with helm package. Make sure you use at -least part of that name string in --key.

- -
$ helm package --sign --key technosophos --keyring ~/.gnupg/secring.gpg mychart
-
- -

As a result, the package command should produce both a .tgz file and a .tgz.prov -file.

- -

Verifying packages

- -

You can also use a similar technique to verify a chart signed by someone else’s -Keybase key. Say you want to verify a package signed by keybase.io/technosophos. -To do this, use the keybase tool:

- -
$ keybase follow technosophos
-$ keybase pgp pull
-
- -

The first command above tracks the user technosophos. Next keybase pgp pull -downloads the OpenPGP keys of all of the accounts you follow, placing them in -your GnuPG keyring (~/.gnupg/pubring.gpg).

- -

At this point, you can now use helm verify or any of the commands with a --verify -flag:

- -
$ helm verify somechart-1.2.3.tgz
-
- -

Reasons a chart may not verify

- -

These are common reasons for failure.

- -
    -
  • The prov file is missing or corrupt. This indicates that something is misconfigured -or that the original maintainer did not create a provenance file.
  • -
  • The key used to sign the file is not in your keyring. This indicate that the -entity who signed the chart is not someone you’ve already signaled that you trust.
  • -
  • The verification of the prov file failed. This indicates that something is wrong -with either the chart or the provenance data.
  • -
  • The file hashes in the provenance file do not match the hash of the archive file. This -indicates that the archive has been tampered with.
  • -
- -

If a verification fails, there is reason to distrust the package.

- -

The Provenance File

- -

The provenance file contains a chart’s YAML file plus several pieces of -verification information. Provenance files are designed to be automatically -generated.

- -

The following pieces of provenance data are added:

- -
    -
  • The chart file (Chart.yaml) is included to give both humans and tools an easy -view into the contents of the chart.
  • -
  • The signature (SHA256, just like Docker) of the chart package (the .tgz file) -is included, and may be used to verify the integrity of the chart package.
  • -
  • The entire body is signed using the algorithm used by PGP (see -[http://keybase.io] for an emerging way of making crypto signing and -verification easy).
  • -
- -

The combination of this gives users the following assurances:

- -
    -
  • The package itself has not been tampered with (checksum package tgz).
  • -
  • The entity who released this package is known (via the GnuPG/PGP signature).
  • -
- -

The format of the file looks something like this:

- -
-----BEGIN PGP SIGNED MESSAGE-----
-name: nginx
-description: The nginx web server as a replication controller and service pair.
-version: 0.5.1
-keywords:
-  - https
-  - http
-  - web server
-  - proxy
-source:
-- https://github.com/foo/bar
-home: http://nginx.com
-
-...
-files:
-        nginx-0.5.1.tgz: “sha256:9f5270f50fc842cfcb717f817e95178f”
------BEGIN PGP SIGNATURE-----
-Version: GnuPG v1.4.9 (GNU/Linux)
-
-iEYEARECAAYFAkjilUEACgQkB01zfu119ZnHuQCdGCcg2YxF3XFscJLS4lzHlvte
-WkQAmQGHuuoLEJuKhRNo+Wy7mhE7u1YG
-=eifq
------END PGP SIGNATURE-----
-
- -

Note that the YAML section contains two documents (separated by ...\n). The -first is the Chart.yaml. The second is the checksums, a map of filenames to -SHA-256 digests (value shown is fake/truncated)

- -

The signature block is a standard PGP signature, which provides tamper -resistance.

- -

Chart Repositories

- -

Chart repositories serve as a centralized collection of Helm charts.

- -

Chart repositories must make it possible to serve provenance files over HTTP via -a specific request, and must make them available at the same URI path as the chart.

- -

For example, if the base URL for a package is https://example.com/charts/mychart-1.2.3.tgz, -the provenance file, if it exists, MUST be accessible at https://example.com/charts/mychart-1.2.3.tgz.prov.

- -

From the end user’s perspective, helm install --verify myrepo/mychart-1.2.3 -should result in the download of both the chart and the provenance file with no -additional user configuration or action.

- -

Establishing Authority and Authenticity

- -

When dealing with chain-of-trust systems, it is important to be able to -establish the authority of a signer. Or, to put this plainly, the system -above hinges on the fact that you trust the person who signed the chart. -That, in turn, means you need to trust the public key of the signer.

- -

One of the design decisions with Kubernetes Helm has been that the Helm -project would not insert itself into the chain of trust as a necessary -party. We don’t want to be “the certificate authority” for all chart -signers. Instead, we strongly favor a decentralized model, which is part -of the reason we chose OpenPGP as our foundational technology. -So when it comes to establishing authority, we have left this -step more-or-less undefined in Helm 2.0.0.

- -

However, we have some pointers and recommendations for those interested -in using the provenance system:

- -
    -
  • The Keybase platform provides a public -centralized repository for trust information. - -
      -
    • You can use Keybase to store your keys or to get the public keys of others.
    • -
    • Keybase also has fabulous documentation available
    • -
    • While we haven’t tested it, Keybase’s “secure website” feature could -be used to serve Helm charts.
    • -
  • -
  • The official Kubernetes Charts project -is trying to solve this problem for the official chart repository. - -
      -
    • There is a long issue there detailing the current thoughts.
    • -
    • The basic idea is that an official “chart reviewer” signs charts with -her or his key, and the resulting provenance file is then uploaded -to the chart repository.
    • -
    • There has been some work on the idea that a list of valid signing -keys may be included in the index.yaml file of a repository.
    • -
  • -
- -

Finally, chain-of-trust is an evolving feature of Helm, and some -community members have proposed adapting part of the OSI model for -signatures. This is an open line of inquiry in the Helm team. If you’re -interested, jump on in.

- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/quickstart/index.html b/docs.helm.sh/rootfs/public/quickstart/index.html deleted file mode 100644 index 2078da951a..0000000000 --- a/docs.helm.sh/rootfs/public/quickstart/index.html +++ /dev/null @@ -1,1457 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

Quickstart Guide

- -

This guide covers how you can quickly get started using Helm.

- -

Prerequisites

- -

The following prerequisites are required for a successful and properly secured use of Helm.

- -
    -
  1. A Kubernetes cluster
  2. -
  3. Deciding what security configurations to apply to your installation, if any
  4. -
  5. Installing and configuring Helm and Tiller, the cluster-side service.
  6. -
- -

Install Kubernetes or have access to a cluster

- -
    -
  • You must have Kubernetes installed. For the latest release of Helm, we recommend the latest stable release of Kubernetes, which in most cases is the second-latest minor release.
  • -
  • You should also have a local configured copy of kubectl.
  • -
- -

NOTE: Kubernetes versions prior to 1.6 have limited or no support for role-based access controls (RBAC).

- -

Helm will figure out where to install Tiller by reading your Kubernetes -configuration file (usually $HOME/.kube/config). This is the same file -that kubectl uses.

- -

To find out which cluster Tiller would install to, you can run -kubectl config current-context or kubectl cluster-info.

- -
$ kubectl config current-context
-my-cluster
-
- -

Understand your Security Context

- -

As with all powerful tools, ensure you are installing it correctly for your scenario.

- -

If you’re using Helm on a cluster that you completely control, like minikube or a cluster on a private network in which sharing is not a concern, the default installation – which applies no security configuration – is fine, and it’s definitely the easiest. To install Helm without additional security steps, install Helm and then initialize Helm.

- -

However, if your cluster is exposed to a larger network or if you share your cluster with others – production clusters fall into this category – you must take extra steps to secure your installation to prevent careless or malicious actors from damaging the cluster or its data. To apply configurations that secure Helm for use in production environments and other multi-tenant scenarios, see Securing a Helm installation

- -

If your cluster has Role-Based Access Control (RBAC) enabled, you may want -to configure a service account and rules before proceeding.

- -

Install Helm

- -

Download a binary release of the Helm client. You can use tools like -homebrew, or look at the official releases page.

- -

For more details, or for other options, see the installation -guide.

- -

Initialize Helm and Install Tiller

- -

Once you have Helm ready, you can initialize the local CLI and also -install Tiller into your Kubernetes cluster in one step:

- -
$ helm init
-
- -

This will install Tiller into the Kubernetes cluster you saw with -kubectl config current-context.

- -

TIP: Want to install into a different cluster? Use the ---kube-context flag.

- -

TIP: When you want to upgrade Tiller, just run helm init --upgrade.

- -

By default, when Tiller is installed,it does not have authentication enabled. -To learn more about configuring strong TLS authentication for Tiller, consult -the Tiller TLS guide.

- -

Install an Example Chart

- -

To install a chart, you can run the helm install command. Helm has -several ways to find and install a chart, but the easiest is to use one -of the official stable charts.

- -
$ helm repo update              # Make sure we get the latest list of charts
-$ helm install stable/mysql
-Released smiling-penguin
-
- -

In the example above, the stable/mysql chart was released, and the name of -our new release is smiling-penguin. You get a simple idea of the -features of this MySQL chart by running helm inspect stable/mysql.

- -

Whenever you install a chart, a new release is created. So one chart can -be installed multiple times into the same cluster. And each can be -independently managed and upgraded.

- -

The helm install command is a very powerful command with many -capabilities. To learn more about it, check out the Using Helm -Guide

- -

Learn About Releases

- -

It’s easy to see what has been released using Helm:

- -
$ helm ls
-NAME             VERSION   UPDATED                   STATUS    CHART
-smiling-penguin  1         Wed Sep 28 12:59:46 2016  DEPLOYED  mysql-0.1.0
-
- -

The helm list function will show you a list of all deployed releases.

- -

Uninstall a Release

- -

To uninstall a release, use the helm delete command:

- -
$ helm delete smiling-penguin
-Removed smiling-penguin
-
- -

This will uninstall smiling-penguin from Kubernetes, but you will -still be able to request information about that release:

- -
$ helm status smiling-penguin
-Status: DELETED
-...
-
- -

Because Helm tracks your releases even after you’ve deleted them, you -can audit a cluster’s history, and even undelete a release (with helm -rollback).

- -

Reading the Help Text

- -

To learn more about the available Helm commands, use helm help or type -a command followed by the -h flag:

- -
$ helm get -h
-
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/rbac/index.html b/docs.helm.sh/rootfs/public/rbac/index.html deleted file mode 100644 index 6e6b353f34..0000000000 --- a/docs.helm.sh/rootfs/public/rbac/index.html +++ /dev/null @@ -1,1584 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

Role-based Access Control

- -

In Kubernetes, granting a role to an application-specific service account is a best practice to ensure that your application is operating in the scope that you have specified. Read more about service account permissions in the official Kubernetes docs.

- -

Bitnami also has a fantastic guide for configuring RBAC in your cluster that takes you through RBAC basics.

- -

This guide is for users who want to restrict tiller’s capabilities to install resources to certain namespaces, or to grant a helm client running access to a tiller instance.

- -

Tiller and Role-based Access Control

- -

You can add a service account to Tiller using the --service-account <NAME> flag while you’re configuring helm. As a prerequisite, you’ll have to create a role binding which specifies a role and a service account name that have been set up in advance.

- -

Once you have satisfied the pre-requisite and have a service account with the correct permissions, you’ll run a command like this: helm init --service-account <NAME>

- -

Example: Service account with cluster-admin role

- -
$ kubectl create serviceaccount tiller --namespace kube-system
-serviceaccount "tiller" created
-
- -

In rbac-config.yaml:

- -
apiVersion: v1
-kind: ServiceAccount
-metadata:
-  name: tiller
-  namespace: kube-system
----
-apiVersion: rbac.authorization.k8s.io/v1beta1
-kind: ClusterRoleBinding
-metadata:
-  name: tiller
-roleRef:
-  apiGroup: rbac.authorization.k8s.io
-  kind: ClusterRole
-  name: cluster-admin
-subjects:
-  - kind: ServiceAccount
-    name: tiller
-    namespace: kube-system
-
- -

Note: The cluster-admin role is created by default in a Kubernetes cluster, so you don’t have to define it explicitly.

- -
$ kubectl create -f rbac-config.yaml
-serviceaccount "tiller" created
-clusterrolebinding "tiller" created
-$ helm init --service-account tiller
-
- -

Example: Deploy tiller in a namespace, restricted to deploying resources only in that namespace

- -

In the example above, we gave Tiller admin access to the entire cluster. You are not at all required to give Tiller cluster-admin access for it to work. Instead of specifying a ClusterRole or a ClusterRoleBinding, you can specify a Role and RoleBinding to limit Tiller’s scope to a particular namespace.

- -
$ kubectl create namespace tiller-world
-namespace "tiller-world" created
-$ kubectl create serviceaccount tiller --namespace tiller-world
-serviceaccount "tiller" created
-
- -

Define a Role that allows tiller to manage all resources in tiller-world like in role-tiller.yaml:

- -
kind: Role
-apiVersion: rbac.authorization.k8s.io/v1beta1
-metadata:
-  name: tiller-manager
-  namespace: tiller-world
-rules:
-- apiGroups: ["", "extensions", "apps"]
-  resources: ["*"]
-  verbs: ["*"]
-
- -
$ kubectl create -f role-tiller.yaml
-role "tiller-manager" created
-
- -

In rolebinding-tiller.yaml,

- -
kind: RoleBinding
-apiVersion: rbac.authorization.k8s.io/v1beta1
-metadata:
-  name: tiller-binding
-  namespace: tiller-world
-subjects:
-- kind: ServiceAccount
-  name: tiller
-  namespace: tiller-world
-roleRef:
-  kind: Role
-  name: tiller-manager
-  apiGroup: rbac.authorization.k8s.io
-
- -
$ kubectl create -f rolebinding-tiller.yaml
-rolebinding "tiller-binding" created
-
- -

Afterwards you can run helm init to install tiller in the tiller-world namespace.

- -
$ helm init --service-account tiller --tiller-namespace tiller-world
-$HELM_HOME has been configured at /Users/awesome-user/.helm.
-
-Tiller (the helm server side component) has been installed into your Kubernetes Cluster.
-Happy Helming!
-
-$ helm install nginx --tiller-namespace tiller-world --namespace tiller-world
-NAME:   wayfaring-yak
-LAST DEPLOYED: Mon Aug  7 16:00:16 2017
-NAMESPACE: tiller-world
-STATUS: DEPLOYED
-
-RESOURCES:
-==> v1/Pod
-NAME                  READY  STATUS             RESTARTS  AGE
-wayfaring-yak-alpine  0/1    ContainerCreating  0         0s
-
- -

Example: Deploy tiller in a namespace, restricted to deploying resources in another namespace

- -

In the example above, we gave Tiller admin access to the namespace it was deployed inside. Now, let’s limit Tiller’s scope to deploy resources in a different namespace!

- -

For example, let’s install tiller in the namespace myorg-system and allow tiller to deploy resources in the namespace myorg-users.

- -
$ kubectl create namespace myorg-system
-namespace "myorg-system" created
-$ kubectl create serviceaccount tiller --namespace myorg-system
-serviceaccount "tiller" created
-
- -

Define a Role that allows tiller to manage all resources in myorg-users like in role-tiller.yaml:

- -
kind: Role
-apiVersion: rbac.authorization.k8s.io/v1beta1
-metadata:
-  name: tiller-manager
-  namespace: myorg-users
-rules:
-- apiGroups: ["", "extensions", "apps"]
-  resources: ["*"]
-  verbs: ["*"]
-
- -
$ kubectl create -f role-tiller.yaml
-role "tiller-manager" created
-
- -

Bind the service account to that role. In rolebinding-tiller.yaml,

- -
kind: RoleBinding
-apiVersion: rbac.authorization.k8s.io/v1beta1
-metadata:
-  name: tiller-binding
-  namespace: myorg-users
-subjects:
-- kind: ServiceAccount
-  name: tiller
-  namespace: myorg-system
-roleRef:
-  kind: Role
-  name: tiller-manager
-  apiGroup: rbac.authorization.k8s.io
-
- -
$ kubectl create -f rolebinding-tiller.yaml
-rolebinding "tiller-binding" created
-
- -

We’ll also need to grant tiller access to read configmaps in myorg-system so it can store release information. In role-tiller-myorg-system.yaml:

- -
kind: Role
-apiVersion: rbac.authorization.k8s.io/v1beta1
-metadata:
-  namespace: myorg-system
-  name: tiller-manager
-rules:
-- apiGroups: ["", "extensions", "apps"]
-  resources: ["configmaps"]
-  verbs: ["*"]
-
- -
$ kubectl create -f role-tiller-myorg-system.yaml
-role "tiller-manager" created
-
- -

And the respective role binding. In rolebinding-tiller-myorg-system.yaml:

- -
kind: RoleBinding
-apiVersion: rbac.authorization.k8s.io/v1beta1
-metadata:
-  name: tiller-binding
-  namespace: myorg-system
-subjects:
-- kind: ServiceAccount
-  name: tiller
-  namespace: myorg-system
-roleRef:
-  kind: Role
-  name: tiller-manager
-  apiGroup: rbac.authorization.k8s.io
-
- -
$ kubectl create -f rolebinding-tiller-myorg-system.yaml
-rolebinding "tiller-binding" created
-
- -

Helm and Role-based Access Control

- -

When running a helm client in a pod, in order for the helm client to talk to a tiller instance, it will need certain privileges to be granted. Specifically, the helm client will need to be able to create pods, forward ports and be able to list pods in the namespace where tiller is running (so it can find tiller).

- -

Example: Deploy Helm in a namespace, talking to Tiller in another namespace

- -

In this example, we will assume tiller is running in a namespace called tiller-world and that the helm client is running in a namespace called helm-world. By default, tiller is running in the kube-system namespace.

- -

In helm-user.yaml:

- -
apiVersion: v1
-kind: ServiceAccount
-metadata:
-  name: helm
-  namespace: helm-world
----
-apiVersion: rbac.authorization.k8s.io/v1beta1
-kind: Role
-metadata:
-  name: tiller-user
-  namespace: tiller-world
-rules:
-- apiGroups:
-  - ""
-  resources:
-  - pods/portforward
-  verbs:
-  - create
-- apiGroups:
-  - ""
-  resources:
-  - pods
-  verbs:
-  - list
----
-apiVersion: rbac.authorization.k8s.io/v1beta1
-kind: RoleBinding
-metadata:
-  name: tiller-user-binding
-  namespace: tiller-world
-roleRef:
-  apiGroup: rbac.authorization.k8s.io
-  kind: Role
-  name: tiller-user
-subjects:
-- kind: ServiceAccount
-  name: helm
-  namespace: helm-world
-
- -
$ kubectl create -f helm-user.yaml
-serviceaccount "helm" created
-role "tiller-user" created
-rolebinding "tiller-user-binding" created
-
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/related/index.html b/docs.helm.sh/rootfs/public/related/index.html deleted file mode 100644 index 0d89a66aa2..0000000000 --- a/docs.helm.sh/rootfs/public/related/index.html +++ /dev/null @@ -1,1415 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

Related Projects and Documentation

- -

The Helm community has produced many extra tools, plugins, and documentation about -Helm. We love to hear about these projects. If you have anything you’d like to -add to this list, please open an issue -or pull request.

- -

Article, Blogs, How-Tos, and Extra Documentation

- - - -

Video, Audio, and Podcast

- - - -

Helm Plugins

- - - -

We also encourage GitHub authors to use the helm-plugin -tag on their plugin repositories.

- -

Additional Tools

- -

Tools layered on top of Helm or Tiller.

- -
    -
  • AppsCode Swift - Ajax friendly Helm Tiller Proxy using grpc-gateway
  • -
  • Quay App Registry - Open Kubernetes application registry, including a Helm access client
  • -
  • Chartify - Generate Helm charts from existing Kubernetes resources.
  • -
  • VIM-Kubernetes - VIM plugin for Kubernetes and Helm
  • -
  • Landscaper - “Landscaper takes a set of Helm Chart references with values (a desired state), and realizes this in a Kubernetes cluster.”
  • -
  • Rudder - RESTful (JSON) proxy for Tiller’s API
  • -
  • Helmfile - Helmfile is a declarative spec for deploying helm charts
  • -
  • Schelm - Render a Helm manifest to a directory
  • -
  • Drone.io Helm Plugin - Run Helm inside of the Drone CI/CD system
  • -
  • Cog - Helm chart to deploy Cog on Kubernetes
  • -
  • Monocular - Web UI for Helm Chart repositories
  • -
  • Helm Chart Publisher - HTTP API for publishing Helm Charts in an easy way
  • -
  • Armada - Manage prefixed releases throughout various Kubernetes namespaces, and removes completed jobs for complex deployments. Used by the Openstack-Helm team.
  • -
  • ChartMuseum - Helm Chart Repository with support for Amazon S3 and Google Cloud Storage
  • -
- -

Helm Included

- -

Platforms, distributions, and services that include Helm support.

- -
    -
  • Kubernetic - Kubernetes Desktop Client
  • -
  • Cabin - Mobile App for Managing Kubernetes
  • -
  • Qstack
  • -
  • Fabric8 - Integrated development platform for Kubernetes
  • -
- -

Misc

- -

Grab bag of useful things for Chart authors and Helm users

- -
    -
  • Await - Docker image to “await” different conditions–especially useful for init containers. More Info
  • -
- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/release-checklist/index.html b/docs.helm.sh/rootfs/public/release-checklist/index.html deleted file mode 100644 index 08527f3b53..0000000000 --- a/docs.helm.sh/rootfs/public/release-checklist/index.html +++ /dev/null @@ -1,1571 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

Release Checklist

- -

IMPORTANT: If your experience deviates from this document, please document the changes to keep it up-to-date.

- -

A Maintainer’s Guide to Releasing Helm

- -

So you’re in charge of a new release for helm? Cool. Here’s what to do…

- -

TODO: Nothing

- -

Just kidding! :trollface:

- -

All releases will be of the form vX.Y.Z where X is the major version number, Y is the minor version number and Z is the patch release number. This project strictly follows semantic versioning so following this step is critical.

- -

It is important to note that this document assumes that the git remote in your repository that corresponds to “https://github.com/kubernetes/helm" is named “upstream”. If yours is not (for example, if you’ve chosen to name it “origin” or something similar instead), be sure to adjust the listed snippets for your local environment accordingly. If you are not sure what your upstream remote is named, use a command like git remote -v to find out.

- -

If you don’t have an upstream remote, you can add one easily using something like:

- -
git remote add upstream git@github.com:kubernetes/helm.git
-
- -

In this doc, we are going to reference a few environment variables as well, which you may want to set for convenience. For major/minor releases, use the following:

- -
export RELEASE_NAME=vX.Y.0
-export RELEASE_BRANCH_NAME="release-$RELEASE_NAME"
-export RELEASE_CANDIDATE_NAME="$RELEASE_NAME-rc1"
-
- -

If you are creating a patch release, you may want to use the following instead:

- -
export PREVIOUS_PATCH_RELEASE=vX.Y.Z
-export RELEASE_NAME=vX.Y.Z+1
-export RELEASE_BRANCH_NAME="release-X.Y"
-export RELEASE_CANDIDATE_NAME="$RELEASE_NAME-rc1"
-
- -

1. Create the Release Branch

- -

Major/Minor Releases

- -

Major releases are for new feature additions and behavioral changes that break backwards compatibility. Minor releases are for new feature additions that do not break backwards compatibility. To create a major or minor release, start by creating a release-vX.Y.0 branch from master.

- -
git fetch upstream
-git checkout upstream/master
-git checkout -b $RELEASE_BRANCH_NAME
-
- -

This new branch is going to be the base for the release, which we are going to iterate upon later.

- -

Patch releases

- -

Patch releases are a few critical cherry-picked fixes to existing releases. Start by creating a release-vX.Y.Z branch from the latest patch release.

- -
git fetch upstream --tags
-git checkout $PREVIOUS_PATCH_RELEASE
-git checkout -b $RELEASE_BRANCH_NAME
-
- -

From here, we can cherry-pick the commits we want to bring into the patch release:

- -
# get the commits ids we want to cherry-pick
-git log --oneline
-# cherry-pick the commits starting from the oldest one, without including merge commits
-git cherry-pick -x <commit-id>
-git cherry-pick -x <commit-id>
-
- -

This new branch is going to be the base for the release, which we are going to iterate upon later.

- -

2. Change the Version Number in Git

- -

When doing a minor release, make sure to update pkg/version/version.go with the new release version.

- -
$ git diff pkg/version/version.go
-diff --git a/pkg/version/version.go b/pkg/version/version.go
-index 2109a0a..6f5a1a4 100644
---- a/pkg/version/version.go
-+++ b/pkg/version/version.go
-@@ -26,7 +26,7 @@ var (
-        // Increment major number for new feature additions and behavioral changes.
-        // Increment minor number for bug fixes and performance enhancements.
-        // Increment patch number for critical fixes to existing releases.
--       Version = "v2.6"
-+       Version = "v2.7"
-
-        // BuildMetadata is extra build time data
-        BuildMetadata = "unreleased"
-
- -

The README stores links to the latest release for helm. We want to change the version to the first release candidate which we are releasing (more on that in step 5).

- -
$ git diff README.md
-diff --git a/README.md b/README.md
-index 022afd79..547839e2 100644
---- a/README.md
-+++ b/README.md
-@@ -34,10 +34,10 @@ Think of it like apt/yum/homebrew for Kubernetes.
-
- Binary downloads of the Helm client can be found at the following links:
-
--- [OSX](https://kubernetes-helm.storage.googleapis.com/helm-v2.7.0-darwin-amd64.tar.gz)
--- [Linux](https://kubernetes-helm.storage.googleapis.com/helm-v2.7.0-linux-amd64.tar.gz)
--- [Linux 32-bit](https://kubernetes-helm.storage.googleapis.com/helm-v2.7.0-linux-386.tar.gz)
--- [Windows](https://kubernetes-helm.storage.googleapis.com/helm-v2.7.0-windows-amd64.tar.gz)
-+- [OSX](https://kubernetes-helm.storage.googleapis.com/helm-v2.8.0-darwin-amd64.tar.gz)
-+- [Linux](https://kubernetes-helm.storage.googleapis.com/helm-v2.8.0-linux-amd64.tar.gz)
-+- [Linux 32-bit](https://kubernetes-helm.storage.googleapis.com/helm-v2.8.0-linux-386.tar.gz)
-+- [Windows](https://kubernetes-helm.storage.googleapis.com/helm-v2.8.0-windows-amd64.tar.gz)
-
- Unpack the `helm` binary and add it to your PATH and you are good to go!
- macOS/[homebrew](https://brew.sh/) users can also use `brew install kubernetes-helm`.
-
- -

For patch releases, the old version number will be the latest patch release, so just bump the patch number, incrementing Z by one.

- -
git add .
-git commit -m "bump version to $RELEASE_CANDIDATE_NAME"
-
- -

3. Commit and Push the Release Branch

- -

In order for others to start testing, we can now push the release branch upstream and start the test process.

- -
git push upstream $RELEASE_BRANCH_NAME
-
- -

Make sure to check helm on CircleCI and make sure the release passed CI before proceeding.

- -

If anyone is available, let others peer-review the branch before continuing to ensure that all the proper changes have been made and all of the commits for the release are there.

- -

4. Create a Release Candidate

- -

Now that the release branch is out and ready, it is time to start creating and iterating on release candidates.

- -
git tag --sign --annotate "${RELEASE_CANDIDATE_NAME}" --message "Helm release ${RELEASE_CANDIDATE_NAME}"
-git push upstream $RELEASE_CANDIDATE_NAME
-
- -

CircleCI will automatically create a tagged release image and client binary to test with.

- -

For testers, the process to start testing after CircleCI finishes building the artifacts involves the following steps to grab the client from Google Cloud Storage:

- -

linux/amd64, using /bin/bash:

- -
wget https://kubernetes-helm.storage.googleapis.com/helm-$RELEASE_CANDIDATE_NAME-linux-amd64.tar.gz
-
- -

darwin/amd64, using Terminal.app:

- -
wget https://kubernetes-helm.storage.googleapis.com/helm-$RELEASE_CANDIDATE_NAME-darwin-amd64.tar.gz
-
- -

windows/amd64, using PowerShell:

- -
PS C:\> Invoke-WebRequest -Uri "https://kubernetes-helm.storage.googleapis.com/helm-$RELEASE_CANDIDATE_NAME-windows-amd64.tar.gz" -OutFile "helm-$ReleaseCandidateName-windows-amd64.tar.gz"
-
- -

Then, unpack and move the binary to somewhere on your $PATH, or move it somewhere and add it to your $PATH (e.g. /usr/local/bin/helm for linux/macOS, C:\Program Files\helm\helm.exe for Windows).

- -

5. Iterate on Successive Release Candidates

- -

Spend several days explicitly investing time and resources to try and break helm in every possible way, documenting any findings pertinent to the release. This time should be spent testing and finding ways in which the release might have caused various features or upgrade environments to have issues, not coding. During this time, the release is in code freeze, and any additional code changes will be pushed out to the next release.

- -

During this phase, the $RELEASE_BRANCH_NAME branch will keep evolving as you will produce new release candidates. The frequency of new candidates is up to the release manager: use your best judgement taking into account the severity of reported issues, testers’ availability, and the release deadline date. Generally speaking, it is better to let a release roll over the deadline than to ship a broken release.

- -

Each time you’ll want to produce a new release candidate, you will start by adding commits to the branch by cherry-picking from master:

- -
git cherry-pick -x <commit_id>
-
- -

You will also want to update the release version number and the CHANGELOG as we did in steps 2 and 3 as separate commits.

- -

After that, tag it and notify users of the new release candidate:

- -
export RELEASE_CANDIDATE_NAME="$RELEASE_NAME-rc2"
-git tag --sign --annotate "${RELEASE_CANDIDATE_NAME}" --message "Helm release ${RELEASE_CANDIDATE_NAME}"
-git push upstream $RELEASE_CANDIDATE_NAME
-
- -

From here on just repeat this process, continuously testing until you’re happy with the release candidate.

- -

6. Finalize the Release

- -

When you’re finally happy with the quality of a release candidate, you can move on and create the real thing. Double-check one last time to make sure eveything is in order, then finally push the release tag.

- -
git checkout $RELEASE_BRANCH_NAME
-git tag --sign --annotate "${RELEASE_NAME}" --message "Helm release ${RELEASE_NAME}"
-git push upstream $RELEASE_NAME
-
- -

7. Write the Release Notes

- -

We will auto-generate a changelog based on the commits that occurred during a release cycle, but it is usually more beneficial to the end-user if the release notes are hand-written by a human being/marketing team/dog.

- -

If you’re releasing a major/minor release, listing notable user-facing features is usually sufficient. For patch releases, do the same, but make note of the symptoms and who is affected.

- -

An example release note for a minor release would look like this:

- -
## vX.Y.Z
-
-Helm vX.Y.Z is a feature release. This release, we focused on <insert focal point>. Users are encouraged to upgrade for the best experience.
-
-The community keeps growing, and we'd love to see you there.
-
-- Join the discussion in [Kubernetes Slack](https://slack.k8s.io/):
-  - `#helm-users` for questions and just to hang out
-  - `#helm-dev` for discussing PRs, code, and bugs
-- Hang out at the Public Developer Call: Thursday, 9:30 Pacific via [Zoom](https://zoom.us/j/4526666954)
-- Test, debug, and contribute charts: [GitHub/kubernetes/charts](https://github.com/kubernetes/charts)
-
-## Installation and Upgrading
-
-Download Helm X.Y. The common platform binaries are here:
-
-- [OSX](https://storage.googleapis.com/kubernetes-helm/helm-vX.Y.Z-darwin-amd64.tar.gz)
-- [Linux](https://storage.googleapis.com/kubernetes-helm/helm-vX.Y.Z-linux-amd64.tar.gz)
-- [Windows](https://storage.googleapis.com/kubernetes-helm/helm-vX.Y.Z-windows-amd64.tar.gz)
-
-Once you have the client installed, upgrade Tiller with `helm init --upgrade`.
-
-The [Quickstart Guide](https://docs.helm.sh/using_helm/#quickstart-guide) will get you going from there. For **upgrade instructions** or detailed installation notes, check the [install guide](https://docs.helm.sh/using_helm/#installing-helm). You can also use a [script to install](https://raw.githubusercontent.com/kubernetes/helm/master/scripts/get) on any system with `bash`.
-
-## What's Next
-
-- vX.Y.Z+1 will contain only bug fixes.
-- vX.Y+1.Z is the next feature release. This release will focus on ...
-
-## Changelog
-
-- chore(*): bump version to v2.7.0 08c1144f5eb3e3b636d9775617287cc26e53dba4 (Adam Reese)
-- fix circle not building tags f4f932fabd197f7e6d608c8672b33a483b4b76fa (Matthew Fisher)
-
- -

The changelog at the bottom of the release notes can be generated with this command:

- -
PREVIOUS_RELEASE=vX.Y.Z
-git log --no-merges --pretty=format:'- %s %H (%aN)' $RELEASE_NAME $PREVIOUS_RELEASE
-
- -

Once finished, go into GitHub and edit the release notes for the tagged release with the notes written here.

- -

9. Evangelize

- -

Congratulations! You’re done. Go grab yourself a $DRINK_OF_CHOICE. You’ve earned it.

- -

After enjoying a nice $DRINK_OF_CHOICE, go forth and announce the glad tidings of the new release in Slack and on Twitter. You should also notify any key partners in the helm community such as the homebrew formula maintainers, the owners of incubator projects (e.g. ChartMuseum) and any other interested parties.

- -

Optionally, write a blog post about the new release and showcase some of the new features on there!

- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/securing_installation/index.html b/docs.helm.sh/rootfs/public/securing_installation/index.html deleted file mode 100644 index e7cc639e87..0000000000 --- a/docs.helm.sh/rootfs/public/securing_installation/index.html +++ /dev/null @@ -1,1433 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
- - - -
- - - -
-
 
-
-

- - -

Securing your Helm Installation

- -

Helm is a powerful and flexible package-management and operations tool for Kubernetes. Installing it using the default installation command – helm init – quickly and easily installs Tiller, the server-side component with which Helm corresponds.

- -

This default installation applies no security configurations, however. It’s completely appropriate to use this type of installation when you are working against a cluster with no or very few security concerns, such as local development with Minikube or with a cluster that is well-secured in a private network with no data-sharing or no other users or teams. If this is the case, then the default installation is fine, but remember: With great power comes great responsibility. Always use due diligence when deciding to use the default installation.

- -

Who Needs Security Configurations?

- -

For the following types of clusters we strongly recommend that you apply the proper security configurations to Helm and Tiller to ensure the safety of the cluster, the data in it, and the network to which it is connected.

- -
    -
  • Clusters that are exposed to uncontrolled network environments: either untrusted network actors can access the cluster, or untrusted applications that can access the network environment.
  • -
  • Clusters that are for many people to use – multitenant clusters – as a shared environment
  • -
  • Clusters that have access to or use high-value data or networks of any type
  • -
- -

Often, environments like these are referred to as production grade or production quality because the damage done to any company by misuse of the cluster can be profound for either customers, the company itself, or both. Once the risk of damage becomes high enough, you need to ensure the integrity of your cluster no matter what the actual risk.

- -

To configure your installation properly for your environment, you must:

- -
    -
  • Understand the security context of your cluster
  • -
  • Choose the Best Practices you should apply to your helm installation
  • -
- -

The following assumes you have a Kubernetes configuration file (a kubeconfig file) or one was given to you to access a cluster.

- -

Understanding the Security Context of your Cluster

- -

helm init installs Tiller into the cluster in the kube-system namespace and without any RBAC rules applied. This is appropriate for local development and other private scenarios because it enables you to be productive immediately. It also enables you to continue running Helm with existing Kubernetes clusters that do not have role-based access control (RBAC) support until you can move your workloads to a more recent Kubernetes version.

- -

There are four main areas to consider when securing a tiller installation:

- -
    -
  1. Role-based access control, or RBAC
  2. -
  3. Tiller’s gRPC endpoint and its usage by Helm
  4. -
  5. Tiller release information
  6. -
  7. Helm charts
  8. -
- -

RBAC

- -

Recent versions of Kubernetes employ a role-based access control (or RBAC) system (as do modern operating systems) to help mitigate the damage that can done if credentials are misused or bugs exist. Even where an identity is hijacked, the identity has only so many permissions to a controlled space. This effectively adds a layer of security to limit the scope of any attack with that identity.

- -

Helm and Tiller are designed to install, remove, and modify logical applications that can contain many services interacting together. As a result, often its usefulness involves cluster-wide operations, which in a multitenant cluster means that great care must be taken with access to a cluster-wide Tiller installation to prevent improper activity.

- -

Specific users and teams – developers, operators, system and network administrators – will need their own portion of the cluster in which they can use Helm and Tiller without risking other portions of the cluster. This means using a Kubernetes cluster with RBAC enabled and Tiller configured to enforce them. For more information about using RBAC in Kubernetes, see Using RBAC Authorization.

- -

Tiller and User Permissions

- -

Tiller in its current form does not provide a way to map user credentials to specific permissions within Kubernetes. When Tiller is running inside of the cluster, it operates with the permissions of its service account. If no service account name is supplied to Tiller, it runs with the default service account for that namespace. This means that all Tiller operations on that server are executed using the Tiller pod’s credentials and permissions.

- -

To properly limit what Tiller itself can do, the standard Kubernetes RBAC mechanisms must be attached to Tiller, including Roles and RoleBindings that place explicit limits on what things a Tiller instance can install, and where.

- -

This situation may change in the future. While the community has several methods that might address this, at the moment performing actions using the rights of the client, instead of the rights of Tiller, is contingent upon the outcome of the Pod Identity Working Group, which has taken on the task of solving the problem in a general way.

- -

The Tiller gRPC Endpoint and TLS

- -

In the default installation the gRPC endpoint that Tiller offers is available inside the cluster (not external to the cluster) without authentication configuration applied. Without applying authentication, any process in the cluster can use the gRPC endpoint to perform operations inside the cluster. In a local or secured private cluster, this enables rapid usage and is normal. (When running outside the cluster, Helm authenticates through the Kubernetes API server to reach Tiller, leveraging existing Kubernetes authentication support.)

- -

Shared and production clusters – for the most part – should use Helm 2.7.2 at a minimum and configure TLS for each the Tiller gRPC endpoint to ensure that within the cluster usage of gRPC endpoints is only for the properly authenticated identity for that endpoint. Doing so enables any number of Tiller instances to be deployed in any number of namespaces and yet no unauthenticated usage of any gRPC endpoint is possible. Finally, usage of Helm init with the --tiller-tls-verify option to install Tiller with TLS enabled and to verify remote certificates, and other Helm commands should use the --tls with all other commands.

- -

For more information about the proper steps to configure Tiller and use Helm properly with TLS configured, see Using SSL between Helm and Tiller.

- -

When Helm clients are connecting from outside of the cluster, the security between the Helm client and the API server is managed by Kubernetes itself. You may want to ensure that this link is secure. Note that if you are using the TLS configuration recommended above, not even the Kubernetes API server has access to the unencrypted messages between the client and Tiller.

- -

Tiller’s Release Information

- -

For historical reasons, Tiller stores its release information in ConfigMaps. We suggest changing the default to Secrets.

- -

Secrets are the Kubernetes accepted mechanism for saving configuration data that is considered sensitive. While secrets don’t themselves offer many protections, Kubernetes cluster management software often treats them differently than other objects. Thus, we suggest using secrets to store releases.

- -

Enabling this feature currently requires setting the --storage=secret flag in the tiller-deploy deployment. This entails directly modifying the deployment or using helm init --override=..., as no helm init flag is currently available to do this for you. For more information, see Using –override.

- -

Thinking about Charts

- -

Because of the relative longevity of Helm, the Helm chart ecosystem evolved without the immediate concern for cluster-wide control, and especially in the developer space this makes complete sense. However, charts are a kind of package that not only installs containers you may or may not have validated yourself, but it may also install into more than one namespace.

- -

As with all shared software, in a controlled or shared environment you must validate all software you install yourself before you install it. If you have secured Tiller with TLS and have installed it with permissions to only one or a subset of namespaces, some charts may fail to install – but in these environments, that is exactly what you want. If you need to use the chart, you may have to work with the creator or modify it yourself in order to use it securely in a mulitenant cluster with proper RBAC rules applied. The helm template command renders the chart locally and displays the output.

- -

Once vetted, you can use Helm’s provenance tools to ensure the provenance and integrity of charts that you use.

- -

gRPC Tools and Secured Tiller Configurations

- -

Many very useful tools use the gRPC interface directly, and having been built against the default installation – which provides cluster-wide access – may fail once security configurations have been applied. RBAC policies are controlled by you or by the cluster operator, and either can be adjusted for the tool, or the tool can be configured to work properly within the constraints of specific RBAC policies applied to Tiller. The same may need to be done if the gRPC endpoint is secured: the tools need their own secure TLS configuration in order to use a specific Tiller instance. The combination of RBAC policies and a secured gRPC endpoint configured in conjunction with gRPC tools enables you to control your cluster environment as you should.

- -

Best Practices for Securing Helm and Tiller

- -

The following guidelines reiterate the Best Practices for securing Helm and Tiller and using them correctly.

- -
    -
  1. Create a cluster with RBAC enabled
  2. -
  3. Configure each Tiller gRPC endpoint to use a separate TLS certificate
  4. -
  5. Release information should be a Kubernetes Secret
  6. -
  7. Install one Tiller per user, team, or other organizational entity with the --service-account flag, Roles, and RoleBindings
  8. -
  9. Use the --tiller-tls-verify option with helm init and the --tls flag with other Helm commands to enforce verification
  10. -
- -

If these steps are followed, an example helm init command might look something like this:

- -
$ helm init \ 
-–tiller-tls \ 
-–tiller-tls-verify \ 
-–tiller-tls-ca-cert=ca.pem \ 
-–tiller-tls-cert=cert.pem \ 
-–tiller-tls-key=key.pem \ 
-–service-account=accountname  
-
- -

This command will start Tiller with both strong authentication over gRPC, and a service account to which RBAC policies have been applied.

- -
-
 
-
-
- - -
- - - -
-
- - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/sitemap.xml b/docs.helm.sh/rootfs/public/sitemap.xml deleted file mode 100644 index c7eb71e498..0000000000 --- a/docs.helm.sh/rootfs/public/sitemap.xml +++ /dev/null @@ -1,377 +0,0 @@ - - - - - https://docs.helm.sh/architecture/ - - - - https://docs.helm.sh/chart_best_practices/readme/ - - - - https://docs.helm.sh/chart_best_practices/conventions/ - - - - https://docs.helm.sh/chart_best_practices/labels/ - - - - https://docs.helm.sh/chart_best_practices/pods/ - - - - https://docs.helm.sh/chart_best_practices/rbac/ - - - - https://docs.helm.sh/chart_best_practices/requirements/ - - - - https://docs.helm.sh/chart_best_practices/templates/ - - - - https://docs.helm.sh/chart_best_practices/third_party_resources/ - - - - https://docs.helm.sh/chart_best_practices/values/ - - - - https://docs.helm.sh/chart_repository/ - - - - https://docs.helm.sh/chart_repository_faq/ - - - - https://docs.helm.sh/chart_repository_sync_example/ - - - - https://docs.helm.sh/chart_template_guide/ - - - - https://docs.helm.sh/chart_tests/ - - - - https://docs.helm.sh/charts/ - - - - https://docs.helm.sh/charts_hooks/ - - - - https://docs.helm.sh/charts_tips_and_tricks/ - - - - https://docs.helm.sh/developers/ - - - - https://docs.helm.sh/developing_charts/ - - - - https://docs.helm.sh/examples/readme/ - - - - https://docs.helm.sh/examples/alpine/readme/ - - - - https://docs.helm.sh/examples/nginx/readme/ - - - - https://docs.helm.sh/glossary/ - - - - https://docs.helm.sh/helm/helm/ - - - - https://docs.helm.sh/helm/helm_completion/ - - - - https://docs.helm.sh/helm/helm_create/ - - - - https://docs.helm.sh/helm/helm_delete/ - - - - https://docs.helm.sh/helm/helm_dependency/ - - - - https://docs.helm.sh/helm/helm_dependency_build/ - - - - https://docs.helm.sh/helm/helm_dependency_list/ - - - - https://docs.helm.sh/helm/helm_dependency_update/ - - - - https://docs.helm.sh/helm/helm_fetch/ - - - - https://docs.helm.sh/helm/helm_get/ - - - - https://docs.helm.sh/helm/helm_get_hooks/ - - - - https://docs.helm.sh/helm/helm_get_manifest/ - - - - https://docs.helm.sh/helm/helm_get_values/ - - - - https://docs.helm.sh/helm/helm_history/ - - - - https://docs.helm.sh/helm/helm_home/ - - - - https://docs.helm.sh/helm/helm_init/ - - - - https://docs.helm.sh/helm/helm_inspect/ - - - - https://docs.helm.sh/helm/helm_inspect_chart/ - - - - https://docs.helm.sh/helm/helm_inspect_values/ - - - - https://docs.helm.sh/helm/helm_install/ - - - - https://docs.helm.sh/helm/helm_lint/ - - - - https://docs.helm.sh/helm/helm_list/ - - - - https://docs.helm.sh/helm/helm_package/ - - - - https://docs.helm.sh/helm/helm_plugin/ - - - - https://docs.helm.sh/helm/helm_plugin_install/ - - - - https://docs.helm.sh/helm/helm_plugin_list/ - - - - https://docs.helm.sh/helm/helm_plugin_remove/ - - - - https://docs.helm.sh/helm/helm_plugin_update/ - - - - https://docs.helm.sh/helm/helm_repo/ - - - - https://docs.helm.sh/helm/helm_repo_add/ - - - - https://docs.helm.sh/helm/helm_repo_index/ - - - - https://docs.helm.sh/helm/helm_repo_list/ - - - - https://docs.helm.sh/helm/helm_repo_remove/ - - - - https://docs.helm.sh/helm/helm_repo_update/ - - - - https://docs.helm.sh/helm/helm_reset/ - - - - https://docs.helm.sh/helm/helm_rollback/ - - - - https://docs.helm.sh/helm/helm_search/ - - - - https://docs.helm.sh/helm/helm_serve/ - - - - https://docs.helm.sh/helm/helm_status/ - - - - https://docs.helm.sh/helm/helm_template/ - - - - https://docs.helm.sh/helm/helm_test/ - - - - https://docs.helm.sh/helm/helm_upgrade/ - - - - https://docs.helm.sh/helm/helm_verify/ - - - - https://docs.helm.sh/helm/helm_version/ - - - - https://docs.helm.sh/history/ - - - - https://docs.helm.sh/install/ - - - - https://docs.helm.sh/install_faq/ - - - - https://docs.helm.sh/kubernetes_distros/ - - - - https://docs.helm.sh/plugins/ - - - - https://docs.helm.sh/provenance/ - - - - https://docs.helm.sh/quickstart/ - - - - https://docs.helm.sh/rbac/ - - - - https://docs.helm.sh/related/ - - - - https://docs.helm.sh/release-checklist/ - - - - https://docs.helm.sh/securing_installation/ - - - - https://docs.helm.sh/tiller_ssl/ - - - - https://docs.helm.sh/using_helm/ - - - - https://docs.helm.sh/using_helm/ - - - - https://docs.helm.sh/categories/ - 0 - - - - https://docs.helm.sh/chart_best_practices/ - 0 - - - - https://docs.helm.sh/chart_template_guide/ - 0 - - - - https://docs.helm.sh/developing_charts/ - 0 - - - - https://docs.helm.sh/examples/ - 0 - - - - https://docs.helm.sh/helm/ - 0 - - - - https://docs.helm.sh/ - 0 - - - - https://docs.helm.sh/tags/ - 0 - - - - https://docs.helm.sh/using_helm/ - 0 - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/src/css/styles.min.css b/docs.helm.sh/rootfs/public/src/css/styles.min.css deleted file mode 100644 index 0f2b61cc5f..0000000000 --- a/docs.helm.sh/rootfs/public/src/css/styles.min.css +++ /dev/null @@ -1,5 +0,0 @@ -/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */.antialiased,.fa,body,html{-moz-osx-font-smoothing:grayscale}.clearfix:after,.row .row.collapse:after,.row .row:after,.row:after,[class*=block-grid-]:after{clear:both}img,textarea[rows]{height:auto}.inline-list,.inline-list>li,.top-bar ul{list-style:none}h1,h2,h3,h4,h5,h6,p{text-rendering:optimizeLegibility}.button,.vevent abbr,a,button{text-decoration:none}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}b,optgroup,strong{font-weight:700}dfn{font-style:italic}mark{background:#ff0;color:#000}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0;max-width:100%;-ms-interpolation-mode:bicubic}svg:not(:root){overflow:hidden}figure{margin:1em 40px}pre,textarea{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}.button,button,input,select{line-height:normal}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}legend{border:0;padding:0}table{border-collapse:collapse;border-spacing:0}meta.foundation-version{font-family:\/5.5.3/}meta.foundation-mq-small{font-family:"/only screen/";width:0}meta.foundation-mq-small-only{font-family:"/only screen and (max-width: 40em)/";width:0}meta.foundation-mq-medium{font-family:"/only screen and (min-width:40.0625em)/";width:40.0625em}meta.foundation-mq-medium-only{font-family:"/only screen and (min-width:40.0625em) and (max-width:64em)/";width:40.0625em}meta.foundation-mq-large{font-family:"/only screen and (min-width:64.0625em)/";width:64.0625em}meta.foundation-mq-large-only{font-family:"/only screen and (min-width:64.0625em) and (max-width:90em)/";width:64.0625em}meta.foundation-mq-xlarge{font-family:"/only screen and (min-width:90.0625em)/";width:90.0625em}meta.foundation-mq-xlarge-only{font-family:"/only screen and (min-width:90.0625em) and (max-width:120em)/";width:90.0625em}meta.foundation-mq-xxlarge{font-family:"/only screen and (min-width:120.0625em)/";width:120.0625em}.row,select{width:100%}meta.foundation-data-attribute-namespace{font-family:false}.button,body,button{font-family:Helvetica Neue,Helvetica,Roboto,Arial,sans-serif;font-weight:400;position:relative}*,:after,:before{box-sizing:border-box}body,html{font-size:100%}body{color:#222;cursor:auto;font-style:normal;line-height:1.5}.button,a:hover,button{cursor:pointer}#map_canvas embed,#map_canvas img,#map_canvas object,.map_canvas embed,.map_canvas img,.map_canvas object,.mqa-display embed,.mqa-display img,.mqa-display object{max-width:none!important}.left{float:left!important}.right{float:right!important}.clearfix:after,.clearfix:before{content:" ";display:table}.hide{display:none}.row .row.collapse:after,.row .row.collapse:before,.row .row:after,.row .row:before,.row:after,.row:before,[class*=block-grid-]:after,[class*=block-grid-]:before{content:" ";display:table}.invisible{visibility:hidden}.antialiased{-webkit-font-smoothing:antialiased}img{display:inline-block;vertical-align:middle}.row{margin:0 auto;max-width:62.5rem}.row.collapse>.column,.row.collapse>.columns{padding-left:0;padding-right:0}.row.collapse .row{margin-left:0;margin-right:0}.row .row{margin:0 -.9375rem;max-width:none;width:auto}.row .row.collapse{margin:0;max-width:none;width:auto}.column,.columns{padding-left:.9375rem;padding-right:.9375rem;width:100%;float:left}.column+.column:last-child,.column+.columns:last-child,.columns+.column:last-child,.columns+.columns:last-child{float:right}.column+.column.end,.column+.columns.end,.columns+.column.end,.columns+.columns.end{float:left}@media only screen{.column,.columns,.small-pull-0,.small-pull-1,.small-pull-2,.small-pull-3,.small-pull-4,.small-pull-5,.small-pull-6,.small-pull-7,.small-pull-8,.small-pull-9,.small-pull-10,.small-pull-11,.small-push-0,.small-push-1,.small-push-2,.small-push-3,.small-push-4,.small-push-5,.small-push-7,.small-push-8,.small-push-9,.small-push-10,.small-push-11{position:relative}.small-push-0{left:0;right:auto}.small-pull-0{right:0;left:auto}.small-push-1{left:8.33333%;right:auto}.small-pull-1{right:8.33333%;left:auto}.small-push-2{left:16.66667%;right:auto}.small-pull-2{right:16.66667%;left:auto}.small-push-3{left:25%;right:auto}.small-pull-3{right:25%;left:auto}.small-push-4{left:33.33333%;right:auto}.small-pull-4{right:33.33333%;left:auto}.small-push-5{left:41.66667%;right:auto}.small-pull-5{right:41.66667%;left:auto}.small-push-6{position:relative;left:50%;right:auto}.small-pull-6{right:50%;left:auto}.small-push-7{left:58.33333%;right:auto}.small-pull-7{right:58.33333%;left:auto}.small-push-8{left:66.66667%;right:auto}.small-pull-8{right:66.66667%;left:auto}.small-push-9{left:75%;right:auto}.small-pull-9{right:75%;left:auto}.small-push-10{left:83.33333%;right:auto}.small-pull-10{right:83.33333%;left:auto}.small-push-11{left:91.66667%;right:auto}.small-pull-11{right:91.66667%;left:auto}.column,.columns{padding-left:.9375rem;padding-right:.9375rem;float:left}.small-1{width:8.33333%}.small-2{width:16.66667%}.small-3{width:25%}.small-4{width:33.33333%}.small-5{width:41.66667%}.small-6{width:50%}.small-7{width:58.33333%}.small-8{width:66.66667%}.small-9{width:75%}.small-10{width:83.33333%}.small-11{width:91.66667%}.small-12{width:100%}.small-offset-0{margin-left:0!important}.small-offset-1{margin-left:8.33333%!important}.small-offset-2{margin-left:16.66667%!important}.small-offset-3{margin-left:25%!important}.small-offset-4{margin-left:33.33333%!important}.small-offset-5{margin-left:41.66667%!important}.small-offset-6{margin-left:50%!important}.small-offset-7{margin-left:58.33333%!important}.small-offset-8{margin-left:66.66667%!important}.small-offset-9{margin-left:75%!important}.small-offset-10{margin-left:83.33333%!important}.small-offset-11{margin-left:91.66667%!important}.small-reset-order{float:left;left:auto;margin-left:0;margin-right:0;right:auto}.column.small-centered,.columns.small-centered{margin-left:auto;margin-right:auto;float:none}.column.small-uncentered,.columns.small-uncentered{float:left;margin-left:0;margin-right:0}.column.small-centered:last-child,.columns.small-centered:last-child{float:none}.column.small-uncentered:last-child,.columns.small-uncentered:last-child{float:left}.column.small-uncentered.opposite,.columns.small-uncentered.opposite{float:right}.row.small-collapse>.column,.row.small-collapse>.columns{padding-left:0;padding-right:0}.row.small-collapse .row{margin-left:0;margin-right:0}.row.small-uncollapse>.column,.row.small-uncollapse>.columns{padding-left:.9375rem;padding-right:.9375rem;float:left}}@media only screen and (min-width:40.0625em){.medium-pull-0,.medium-pull-1,.medium-pull-2,.medium-pull-3,.medium-pull-4,.medium-pull-5,.medium-pull-6,.medium-pull-7,.medium-pull-8,.medium-pull-9,.medium-pull-10,.medium-pull-11,.medium-push-0,.medium-push-1,.medium-push-2,.medium-push-3,.medium-push-4,.medium-push-5,.medium-push-6,.medium-push-7,.medium-push-8,.medium-push-9,.medium-push-10,.medium-push-11,.pull-0,.pull-1,.pull-2,.pull-3,.pull-4,.pull-5,.pull-6,.pull-7,.pull-8,.pull-9,.pull-10,.pull-11,.push-0,.push-1,.push-2,.push-3,.push-4,.push-5,.push-6,.push-7,.push-8,.push-9,.push-10,.push-11{position:relative}.medium-push-0{left:0;right:auto}.medium-pull-0{right:0;left:auto}.medium-push-1{left:8.33333%;right:auto}.medium-pull-1{right:8.33333%;left:auto}.medium-push-2{left:16.66667%;right:auto}.medium-pull-2{right:16.66667%;left:auto}.medium-push-3{left:25%;right:auto}.medium-pull-3{right:25%;left:auto}.medium-push-4{left:33.33333%;right:auto}.medium-pull-4{right:33.33333%;left:auto}.medium-push-5{left:41.66667%;right:auto}.medium-pull-5{right:41.66667%;left:auto}.medium-push-6{left:50%;right:auto}.medium-pull-6{right:50%;left:auto}.medium-push-7{left:58.33333%;right:auto}.medium-pull-7{right:58.33333%;left:auto}.medium-push-8{left:66.66667%;right:auto}.medium-pull-8{right:66.66667%;left:auto}.medium-push-9{left:75%;right:auto}.medium-pull-9{right:75%;left:auto}.medium-push-10{left:83.33333%;right:auto}.medium-pull-10{right:83.33333%;left:auto}.medium-push-11{left:91.66667%;right:auto}.medium-pull-11{right:91.66667%;left:auto}.column,.columns{position:relative;padding-left:.9375rem;padding-right:.9375rem;float:left}.medium-1{width:8.33333%}.medium-2{width:16.66667%}.medium-3{width:25%}.medium-4{width:33.33333%}.medium-5{width:41.66667%}.medium-6{width:50%}.medium-7{width:58.33333%}.medium-8{width:66.66667%}.medium-9{width:75%}.medium-10{width:83.33333%}.medium-11{width:91.66667%}.medium-12{width:100%}.medium-offset-0{margin-left:0!important}.medium-offset-1{margin-left:8.33333%!important}.medium-offset-2{margin-left:16.66667%!important}.medium-offset-3{margin-left:25%!important}.medium-offset-4{margin-left:33.33333%!important}.medium-offset-5{margin-left:41.66667%!important}.medium-offset-6{margin-left:50%!important}.medium-offset-7{margin-left:58.33333%!important}.medium-offset-8{margin-left:66.66667%!important}.medium-offset-9{margin-left:75%!important}.medium-offset-10{margin-left:83.33333%!important}.medium-offset-11{margin-left:91.66667%!important}.medium-reset-order{float:left;left:auto;margin-left:0;margin-right:0;right:auto}.column.medium-centered,.columns.medium-centered{margin-left:auto;margin-right:auto;float:none}.column.medium-uncentered,.columns.medium-uncentered{float:left;margin-left:0;margin-right:0}.column.medium-centered:last-child,.columns.medium-centered:last-child{float:none}.column.medium-uncentered:last-child,.columns.medium-uncentered:last-child{float:left}.column.medium-uncentered.opposite,.columns.medium-uncentered.opposite{float:right}.row.medium-collapse>.column,.row.medium-collapse>.columns{padding-left:0;padding-right:0}.row.medium-collapse .row{margin-left:0;margin-right:0}.row.medium-uncollapse>.column,.row.medium-uncollapse>.columns{padding-left:.9375rem;padding-right:.9375rem;float:left}.push-0{left:0;right:auto}.pull-0{right:0;left:auto}.push-1{left:8.33333%;right:auto}.pull-1{right:8.33333%;left:auto}.push-2{left:16.66667%;right:auto}.pull-2{right:16.66667%;left:auto}.push-3{left:25%;right:auto}.pull-3{right:25%;left:auto}.push-4{left:33.33333%;right:auto}.pull-4{right:33.33333%;left:auto}.push-5{left:41.66667%;right:auto}.pull-5{right:41.66667%;left:auto}.push-6{left:50%;right:auto}.pull-6{right:50%;left:auto}.push-7{left:58.33333%;right:auto}.pull-7{right:58.33333%;left:auto}.push-8{left:66.66667%;right:auto}.pull-8{right:66.66667%;left:auto}.push-9{left:75%;right:auto}.pull-9{right:75%;left:auto}.push-10{left:83.33333%;right:auto}.pull-10{right:83.33333%;left:auto}.push-11{left:91.66667%;right:auto}.pull-11{right:91.66667%;left:auto}}@media only screen and (min-width:64.0625em){.large-pull-0,.large-pull-1,.large-pull-2,.large-pull-3,.large-pull-4,.large-pull-5,.large-pull-6,.large-pull-7,.large-pull-8,.large-pull-9,.large-pull-10,.large-pull-11,.large-push-0,.large-push-1,.large-push-2,.large-push-3,.large-push-4,.large-push-5,.large-push-6,.large-push-7,.large-push-8,.large-push-9,.large-push-10,.large-push-11,.pull-0,.pull-1,.pull-2,.pull-3,.pull-4,.pull-5,.pull-6,.pull-7,.pull-8,.pull-9,.pull-10,.pull-11,.push-0,.push-1,.push-2,.push-3,.push-4,.push-5,.push-6,.push-7,.push-8,.push-9,.push-10,.push-11{position:relative}.large-push-0{left:0;right:auto}.large-pull-0{right:0;left:auto}.large-push-1{left:8.33333%;right:auto}.large-pull-1{right:8.33333%;left:auto}.large-push-2{left:16.66667%;right:auto}.large-pull-2{right:16.66667%;left:auto}.large-push-3{left:25%;right:auto}.large-pull-3{right:25%;left:auto}.large-push-4{left:33.33333%;right:auto}.large-pull-4{right:33.33333%;left:auto}.large-push-5{left:41.66667%;right:auto}.large-pull-5{right:41.66667%;left:auto}.large-push-6{left:50%;right:auto}.large-pull-6{right:50%;left:auto}.large-push-7{left:58.33333%;right:auto}.large-pull-7{right:58.33333%;left:auto}.large-push-8{left:66.66667%;right:auto}.large-pull-8{right:66.66667%;left:auto}.large-push-9{left:75%;right:auto}.large-pull-9{right:75%;left:auto}.large-push-10{left:83.33333%;right:auto}.large-pull-10{right:83.33333%;left:auto}.large-push-11{left:91.66667%;right:auto}.large-pull-11{right:91.66667%;left:auto}.column,.columns{position:relative;padding-left:.9375rem;padding-right:.9375rem;float:left}.large-1{width:8.33333%}.large-2{width:16.66667%}.large-3{width:25%}.large-4{width:33.33333%}.large-5{width:41.66667%}.large-6{width:50%}.large-7{width:58.33333%}.large-8{width:66.66667%}.large-9{width:75%}.large-10{width:83.33333%}.large-11{width:91.66667%}.large-12{width:100%}.large-offset-0{margin-left:0!important}.large-offset-1{margin-left:8.33333%!important}.large-offset-2{margin-left:16.66667%!important}.large-offset-3{margin-left:25%!important}.large-offset-4{margin-left:33.33333%!important}.large-offset-5{margin-left:41.66667%!important}.large-offset-6{margin-left:50%!important}.large-offset-7{margin-left:58.33333%!important}.large-offset-8{margin-left:66.66667%!important}.large-offset-9{margin-left:75%!important}.large-offset-10{margin-left:83.33333%!important}.large-offset-11{margin-left:91.66667%!important}.large-reset-order{float:left;left:auto;margin-left:0;margin-right:0;right:auto}.column.large-centered,.columns.large-centered{margin-left:auto;margin-right:auto;float:none}.column.large-uncentered,.columns.large-uncentered{float:left;margin-left:0;margin-right:0}.column.large-centered:last-child,.columns.large-centered:last-child{float:none}.column.large-uncentered:last-child,.columns.large-uncentered:last-child{float:left}.column.large-uncentered.opposite,.columns.large-uncentered.opposite{float:right}.row.large-collapse>.column,.row.large-collapse>.columns{padding-left:0;padding-right:0}.row.large-collapse .row{margin-left:0;margin-right:0}.row.large-uncollapse>.column,.row.large-uncollapse>.columns{padding-left:.9375rem;padding-right:.9375rem;float:left}.push-0{left:0;right:auto}.pull-0{right:0;left:auto}.push-1{left:8.33333%;right:auto}.pull-1{right:8.33333%;left:auto}.push-2{left:16.66667%;right:auto}.pull-2{right:16.66667%;left:auto}.push-3{left:25%;right:auto}.pull-3{right:25%;left:auto}.push-4{left:33.33333%;right:auto}.pull-4{right:33.33333%;left:auto}.push-5{left:41.66667%;right:auto}.pull-5{right:41.66667%;left:auto}.push-6{left:50%;right:auto}.pull-6{right:50%;left:auto}.push-7{left:58.33333%;right:auto}.pull-7{right:58.33333%;left:auto}.push-8{left:66.66667%;right:auto}.pull-8{right:66.66667%;left:auto}.push-9{left:75%;right:auto}.pull-9{right:75%;left:auto}.push-10{left:83.33333%;right:auto}.pull-10{right:83.33333%;left:auto}.push-11{left:91.66667%;right:auto}.pull-11{right:91.66667%;left:auto}}[class*=block-grid-]{display:block;padding:0;margin:0 -.625rem}[class*=block-grid-]>li{display:block;float:left;height:auto;padding:0 .625rem 1.25rem}@media only screen{.small-block-grid-1>li{list-style:none;width:100%}.small-block-grid-1>li:nth-of-type(1n){clear:none}.small-block-grid-1>li:nth-of-type(1n+1){clear:both}.small-block-grid-2>li{list-style:none;width:50%}.small-block-grid-2>li:nth-of-type(1n){clear:none}.small-block-grid-2>li:nth-of-type(odd){clear:both}.small-block-grid-3>li{list-style:none;width:33.33333%}.small-block-grid-3>li:nth-of-type(1n){clear:none}.small-block-grid-3>li:nth-of-type(3n+1){clear:both}.small-block-grid-4>li{list-style:none;width:25%}.small-block-grid-4>li:nth-of-type(1n){clear:none}.small-block-grid-4>li:nth-of-type(4n+1){clear:both}.small-block-grid-5>li{list-style:none;width:20%}.small-block-grid-5>li:nth-of-type(1n){clear:none}.small-block-grid-5>li:nth-of-type(5n+1){clear:both}.small-block-grid-6>li{list-style:none;width:16.66667%}.small-block-grid-6>li:nth-of-type(1n){clear:none}.small-block-grid-6>li:nth-of-type(6n+1){clear:both}.small-block-grid-7>li{list-style:none;width:14.28571%}.small-block-grid-7>li:nth-of-type(1n){clear:none}.small-block-grid-7>li:nth-of-type(7n+1){clear:both}.small-block-grid-8>li{list-style:none;width:12.5%}.small-block-grid-8>li:nth-of-type(1n){clear:none}.small-block-grid-8>li:nth-of-type(8n+1){clear:both}.small-block-grid-9>li{list-style:none;width:11.11111%}.small-block-grid-9>li:nth-of-type(1n){clear:none}.small-block-grid-9>li:nth-of-type(9n+1){clear:both}.small-block-grid-10>li{list-style:none;width:10%}.small-block-grid-10>li:nth-of-type(1n){clear:none}.small-block-grid-10>li:nth-of-type(10n+1){clear:both}.small-block-grid-11>li{list-style:none;width:9.09091%}.small-block-grid-11>li:nth-of-type(1n){clear:none}.small-block-grid-11>li:nth-of-type(11n+1){clear:both}.small-block-grid-12>li{list-style:none;width:8.33333%}.small-block-grid-12>li:nth-of-type(1n){clear:none}.small-block-grid-12>li:nth-of-type(12n+1){clear:both}}@media only screen and (min-width:40.0625em){.medium-block-grid-1>li{list-style:none;width:100%}.medium-block-grid-1>li:nth-of-type(1n){clear:none}.medium-block-grid-1>li:nth-of-type(1n+1){clear:both}.medium-block-grid-2>li{list-style:none;width:50%}.medium-block-grid-2>li:nth-of-type(1n){clear:none}.medium-block-grid-2>li:nth-of-type(odd){clear:both}.medium-block-grid-3>li{list-style:none;width:33.33333%}.medium-block-grid-3>li:nth-of-type(1n){clear:none}.medium-block-grid-3>li:nth-of-type(3n+1){clear:both}.medium-block-grid-4>li{list-style:none;width:25%}.medium-block-grid-4>li:nth-of-type(1n){clear:none}.medium-block-grid-4>li:nth-of-type(4n+1){clear:both}.medium-block-grid-5>li{list-style:none;width:20%}.medium-block-grid-5>li:nth-of-type(1n){clear:none}.medium-block-grid-5>li:nth-of-type(5n+1){clear:both}.medium-block-grid-6>li{list-style:none;width:16.66667%}.medium-block-grid-6>li:nth-of-type(1n){clear:none}.medium-block-grid-6>li:nth-of-type(6n+1){clear:both}.medium-block-grid-7>li{list-style:none;width:14.28571%}.medium-block-grid-7>li:nth-of-type(1n){clear:none}.medium-block-grid-7>li:nth-of-type(7n+1){clear:both}.medium-block-grid-8>li{list-style:none;width:12.5%}.medium-block-grid-8>li:nth-of-type(1n){clear:none}.medium-block-grid-8>li:nth-of-type(8n+1){clear:both}.medium-block-grid-9>li{list-style:none;width:11.11111%}.medium-block-grid-9>li:nth-of-type(1n){clear:none}.medium-block-grid-9>li:nth-of-type(9n+1){clear:both}.medium-block-grid-10>li{list-style:none;width:10%}.medium-block-grid-10>li:nth-of-type(1n){clear:none}.medium-block-grid-10>li:nth-of-type(10n+1){clear:both}.medium-block-grid-11>li{list-style:none;width:9.09091%}.medium-block-grid-11>li:nth-of-type(1n){clear:none}.medium-block-grid-11>li:nth-of-type(11n+1){clear:both}.medium-block-grid-12>li{list-style:none;width:8.33333%}.medium-block-grid-12>li:nth-of-type(1n){clear:none}.medium-block-grid-12>li:nth-of-type(12n+1){clear:both}.button,button{display:inline-block}}@media only screen and (min-width:64.0625em){.large-block-grid-1>li{list-style:none;width:100%}.large-block-grid-1>li:nth-of-type(1n){clear:none}.large-block-grid-1>li:nth-of-type(1n+1){clear:both}.large-block-grid-2>li{list-style:none;width:50%}.large-block-grid-2>li:nth-of-type(1n){clear:none}.large-block-grid-2>li:nth-of-type(odd){clear:both}.large-block-grid-3>li{list-style:none;width:33.33333%}.large-block-grid-3>li:nth-of-type(1n){clear:none}.large-block-grid-3>li:nth-of-type(3n+1){clear:both}.large-block-grid-4>li{list-style:none;width:25%}.large-block-grid-4>li:nth-of-type(1n){clear:none}.large-block-grid-4>li:nth-of-type(4n+1){clear:both}.large-block-grid-5>li{list-style:none;width:20%}.large-block-grid-5>li:nth-of-type(1n){clear:none}.large-block-grid-5>li:nth-of-type(5n+1){clear:both}.large-block-grid-6>li{list-style:none;width:16.66667%}.large-block-grid-6>li:nth-of-type(1n){clear:none}.large-block-grid-6>li:nth-of-type(6n+1){clear:both}.large-block-grid-7>li{list-style:none;width:14.28571%}.large-block-grid-7>li:nth-of-type(1n){clear:none}.large-block-grid-7>li:nth-of-type(7n+1){clear:both}.large-block-grid-8>li{list-style:none;width:12.5%}.large-block-grid-8>li:nth-of-type(1n){clear:none}.large-block-grid-8>li:nth-of-type(8n+1){clear:both}.large-block-grid-9>li{list-style:none;width:11.11111%}.large-block-grid-9>li:nth-of-type(1n){clear:none}.large-block-grid-9>li:nth-of-type(9n+1){clear:both}.large-block-grid-10>li{list-style:none;width:10%}.large-block-grid-10>li:nth-of-type(1n){clear:none}.large-block-grid-10>li:nth-of-type(10n+1){clear:both}.large-block-grid-11>li{list-style:none;width:9.09091%}.large-block-grid-11>li:nth-of-type(1n){clear:none}.large-block-grid-11>li:nth-of-type(11n+1){clear:both}.large-block-grid-12>li{list-style:none;width:8.33333%}.large-block-grid-12>li:nth-of-type(1n){clear:none}.large-block-grid-12>li:nth-of-type(12n+1){clear:both}}.button,button{-webkit-appearance:none;-moz-appearance:none;border-radius:0;margin:0 0 1.25rem;text-align:center;display:inline-block;padding:1rem 2rem 1.0625rem;font-size:1rem;background-color:#008cba;border:0 solid #007095;color:#fff;transition:background-color .3s ease-out}.button:focus,.button:hover,button:focus,button:hover{background-color:#007095;color:#fff}.button.secondary,button.secondary{background-color:#e7e7e7;border-color:#b9b9b9;color:#333}.button.secondary:focus,.button.secondary:hover,button.secondary:focus,button.secondary:hover{background-color:#b9b9b9;color:#333}.button.success,button.success{background-color:#43ac6a;border-color:#368a55;color:#fff}.button.success:focus,.button.success:hover,button.success:focus,button.success:hover{background-color:#368a55;color:#fff}.button.alert,button.alert{background-color:#f04124;border-color:#cf2a0e;color:#fff}.button.alert:focus,.button.alert:hover,button.alert:focus,button.alert:hover{background-color:#cf2a0e;color:#fff}.button.warning,button.warning{background-color:#f08a24;border-color:#cf6e0e;color:#fff}.button.warning:focus,.button.warning:hover,button.warning:focus,button.warning:hover{background-color:#cf6e0e;color:#fff}.button.info,button.info{background-color:#a0d3e8;border-color:#61b6d9;color:#333}.button.info:focus,.button.info:hover,button.info:focus,button.info:hover{background-color:#61b6d9;color:#fff}.button.large,button.large{padding:1.125rem 2.25rem 1.1875rem;font-size:1.25rem}.button.small,button.small{padding:.875rem 1.75rem .9375rem;font-size:.8125rem}.button.tiny,button.tiny{padding:.625rem 1.25rem .6875rem;font-size:.6875rem}.button.expand,button.expand{padding:1rem 1rem 1.0625rem;font-size:1rem;width:100%}label,select{font-size:.875rem}.button.left-align,button.left-align{text-align:left;text-indent:.75rem}.button.right-align,button.right-align{text-align:right;padding-right:.75rem}.button.radius,button.radius{border-radius:3px}.button.round,button.round{border-radius:1000px}.button.disabled,.button[disabled],button.disabled,button[disabled]{background-color:#008cba;border-color:#007095;color:#fff;box-shadow:none;cursor:default;opacity:.7}.button.disabled:focus,.button.disabled:hover,.button[disabled]:focus,.button[disabled]:hover,button.disabled:focus,button.disabled:hover,button[disabled]:focus,button[disabled]:hover{color:#fff;background-color:#008cba}.button.disabled.secondary,.button[disabled].secondary,button.disabled.secondary,button[disabled].secondary{background-color:#e7e7e7;border-color:#b9b9b9;color:#333;box-shadow:none;cursor:default;opacity:.7}.button.disabled.secondary:focus,.button.disabled.secondary:hover,.button[disabled].secondary:focus,.button[disabled].secondary:hover,button.disabled.secondary:focus,button.disabled.secondary:hover,button[disabled].secondary:focus,button[disabled].secondary:hover{color:#333;background-color:#e7e7e7}.button.disabled.success,.button[disabled].success,button.disabled.success,button[disabled].success{background-color:#43ac6a;border-color:#368a55;color:#fff;box-shadow:none;cursor:default;opacity:.7}.button.disabled.success:focus,.button.disabled.success:hover,.button[disabled].success:focus,.button[disabled].success:hover,button.disabled.success:focus,button.disabled.success:hover,button[disabled].success:focus,button[disabled].success:hover{color:#fff;background-color:#43ac6a}.button.disabled.alert,.button[disabled].alert,button.disabled.alert,button[disabled].alert{background-color:#f04124;border-color:#cf2a0e;color:#fff;box-shadow:none;cursor:default;opacity:.7}.button.disabled.alert:focus,.button.disabled.alert:hover,.button[disabled].alert:focus,.button[disabled].alert:hover,button.disabled.alert:focus,button.disabled.alert:hover,button[disabled].alert:focus,button[disabled].alert:hover{color:#fff;background-color:#f04124}.button.disabled.warning,.button[disabled].warning,button.disabled.warning,button[disabled].warning{background-color:#f08a24;border-color:#cf6e0e;color:#fff;box-shadow:none;cursor:default;opacity:.7}.button.disabled.warning:focus,.button.disabled.warning:hover,.button[disabled].warning:focus,.button[disabled].warning:hover,button.disabled.warning:focus,button.disabled.warning:hover,button[disabled].warning:focus,button[disabled].warning:hover{color:#fff;background-color:#f08a24}.button.disabled.info,.button[disabled].info,button.disabled.info,button[disabled].info{background-color:#a0d3e8;border-color:#61b6d9;color:#333;box-shadow:none;cursor:default;opacity:.7}.button.disabled.info:focus,.button.disabled.info:hover,.button[disabled].info:focus,.button[disabled].info:hover,button.disabled.info:focus,button.disabled.info:hover,button[disabled].info:focus,button[disabled].info:hover{color:#fff;background-color:#a0d3e8}button::-moz-focus-inner{border:0;padding:0}.inline-list>li,.inline-list>li>*,.postfix,.prefix,label{display:block}.inline-list{overflow:hidden;padding:0;margin:0 0 1.0625rem -1.375rem}.inline-list>li{float:left;margin-left:1.375rem}form .row .row{margin:0 -.5rem}form .row .row .column,form .row .row .columns{padding:0 .5rem}form .row .row.collapse{margin:0}form .row .row.collapse .column,form .row .row.collapse .columns{padding:0}form .row .row.collapse input{-webkit-border-bottom-right-radius:0;-webkit-border-top-right-radius:0;border-bottom-right-radius:0;border-top-right-radius:0}form .row input.column,form .row input.columns,form .row textarea.column,form .row textarea.columns{padding-left:.5rem}label{color:#4d4d4d;cursor:pointer;font-weight:400;line-height:1.5;margin-bottom:0}input[type=checkbox],input[type=file],input[type=radio],label.inline,select{margin:0 0 1rem}label.right{float:none!important;text-align:right}label.inline{padding:.5625rem 0}label small{text-transform:capitalize;color:#676767}.postfix,.prefix{border-style:solid;border-width:1px;overflow:visible;padding-bottom:0;padding-top:0;position:relative;text-align:center;width:100%;z-index:2}.postfix.button,.prefix.button{border:none;text-align:center;padding:0}.prefix.button.radius{border-radius:3px 0 0 3px;-webkit-border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px}.postfix.button.radius{border-radius:0 3px 3px 0;-webkit-border-bottom-right-radius:3px;-webkit-border-top-right-radius:3px}.prefix.button.round{border-radius:1000px 0 0 1000px;-webkit-border-bottom-left-radius:1000px;-webkit-border-top-left-radius:1000px}.postfix.button.round{border-radius:0 1000px 1000px 0;-webkit-border-bottom-right-radius:1000px;-webkit-border-top-right-radius:1000px}label.prefix,span.prefix{background:#f2f2f2;border-right:none;color:#333;border-color:#ccc}label.postfix,span.postfix{background:#f2f2f2;border-left:none;color:#333;border-color:#ccc}fieldset[disabled] input:not([type]),fieldset[disabled] input[type=color],fieldset[disabled] input[type=date],fieldset[disabled] input[type=datetime-local],fieldset[disabled] input[type=datetime],fieldset[disabled] input[type=email],fieldset[disabled] input[type=month],fieldset[disabled] input[type=number],fieldset[disabled] input[type=password],fieldset[disabled] input[type=search],fieldset[disabled] input[type=tel],fieldset[disabled] input[type=text],fieldset[disabled] input[type=time],fieldset[disabled] input[type=url],fieldset[disabled] input[type=week],fieldset[disabled] textarea,input:not([type]):disabled,input:not([type])[disabled],input:not([type])[readonly],input[type=color]:disabled,input[type=color][disabled],input[type=color][readonly],input[type=date]:disabled,input[type=date][disabled],input[type=date][readonly],input[type=datetime-local]:disabled,input[type=datetime-local][disabled],input[type=datetime-local][readonly],input[type=datetime]:disabled,input[type=datetime][disabled],input[type=datetime][readonly],input[type=email]:disabled,input[type=email][disabled],input[type=email][readonly],input[type=month]:disabled,input[type=month][disabled],input[type=month][readonly],input[type=number]:disabled,input[type=number][disabled],input[type=number][readonly],input[type=password]:disabled,input[type=password][disabled],input[type=password][readonly],input[type=search]:disabled,input[type=search][disabled],input[type=search][readonly],input[type=tel]:disabled,input[type=tel][disabled],input[type=tel][readonly],input[type=text]:disabled,input[type=text][disabled],input[type=text][readonly],input[type=time]:disabled,input[type=time][disabled],input[type=time][readonly],input[type=url]:disabled,input[type=url][disabled],input[type=url][readonly],input[type=week]:disabled,input[type=week][disabled],input[type=week][readonly],select:disabled,textarea:disabled,textarea[disabled],textarea[readonly]{background-color:#ddd;cursor:default}input:not([type]),input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],textarea{-webkit-appearance:none;-moz-appearance:none;border-radius:0;background-color:#fff;border:1px solid #ccc;box-shadow:inset 0 1px 2px rgba(0,0,0,.1);color:rgba(0,0,0,.75);display:block;font-family:inherit;font-size:.875rem;height:2.3125rem;margin:0 0 1rem;padding:.5rem;width:100%;box-sizing:border-box;transition:border-color .15s linear,background .15s linear}input:not([type]):focus,input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus,textarea:focus{background:#fafafa;border-color:#999;outline:0}input:not([type]).radius,input[type=color].radius,input[type=date].radius,input[type=datetime-local].radius,input[type=datetime].radius,input[type=email].radius,input[type=month].radius,input[type=number].radius,input[type=password].radius,input[type=search].radius,input[type=tel].radius,input[type=text].radius,input[type=time].radius,input[type=url].radius,input[type=week].radius,textarea.radius{border-radius:3px}form .row .prefix-radius.row.collapse button,form .row .prefix-radius.row.collapse input,form .row .prefix-radius.row.collapse select,form .row .prefix-radius.row.collapse textarea{border-radius:0 3px 3px 0;-webkit-border-bottom-right-radius:3px;-webkit-border-top-right-radius:3px}form .row .postfix-radius.row.collapse button,form .row .postfix-radius.row.collapse input,form .row .postfix-radius.row.collapse select,form .row .postfix-radius.row.collapse textarea,form .row .prefix-radius.row.collapse .prefix{border-radius:3px 0 0 3px;-webkit-border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px}form .row .postfix-radius.row.collapse .postfix{border-radius:0 3px 3px 0;-webkit-border-bottom-right-radius:3px;-webkit-border-top-right-radius:3px}form .row .prefix-round.row.collapse button,form .row .prefix-round.row.collapse input,form .row .prefix-round.row.collapse select,form .row .prefix-round.row.collapse textarea{border-radius:0 1000px 1000px 0;-webkit-border-bottom-right-radius:1000px;-webkit-border-top-right-radius:1000px}form .row .postfix-round.row.collapse button,form .row .postfix-round.row.collapse input,form .row .postfix-round.row.collapse select,form .row .postfix-round.row.collapse textarea,form .row .prefix-round.row.collapse .prefix{border-radius:1000px 0 0 1000px;-webkit-border-bottom-left-radius:1000px;-webkit-border-top-left-radius:1000px}form .row .postfix-round.row.collapse .postfix{border-radius:0 1000px 1000px 0;-webkit-border-bottom-right-radius:1000px;-webkit-border-top-right-radius:1000px}input[type=submit]{-webkit-appearance:none;-moz-appearance:none;border-radius:0}textarea{min-height:50px;max-width:100%}::-webkit-input-placeholder{color:#666}:-moz-placeholder,::-moz-placeholder{color:#666}:-ms-input-placeholder{color:#666}select{-webkit-appearance:none!important;-moz-appearance:none!important;background-color:#fafafa;background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgeD0iMTJweCIgeT0iMHB4IiB3aWR0aD0iMjRweCIgaGVpZ2h0PSIzcHgiIHZpZXdCb3g9IjAgMCA2IDMiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDYgMyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHBvbHlnb24gcG9pbnRzPSI1Ljk5MiwwIDIuOTkyLDMgLTAuMDA4LDAgIi8+PC9zdmc+);background-position:100%;background-repeat:no-repeat;border:1px solid #ccc;color:rgba(0,0,0,.75);font-family:inherit;padding:.5rem;border-radius:0;height:2.3125rem}select::-ms-expand{display:none}select.radius{border-radius:3px}select:focus{background-color:#f3f3f3;border-color:#999}select[multiple]{height:auto}input[type=checkbox]+label,input[type=radio]+label{display:inline-block;margin-left:.5rem;margin-right:1rem;margin-bottom:0;vertical-align:baseline}input[type=file]{width:100%}fieldset{border:1px solid #ddd;margin:1.125rem 0;padding:1.25rem}fieldset legend{font-weight:700;margin:0 0 0 -.1875rem;padding:0 .1875rem}[data-abide] .error small.error,[data-abide] .error span.error,[data-abide] small.error,[data-abide] span.error{display:block;font-size:.75rem;font-style:italic;font-weight:400;margin-bottom:1rem;margin-top:-1px;padding:.375rem .5625rem .5625rem;background:#f04124;color:#fff}[data-abide] small.error,[data-abide] span.error{display:none}.error small.error,small.error,span.error{display:block;font-size:.75rem;margin-top:-1px;padding:.375rem .5625rem .5625rem;background:#f04124;font-weight:400;font-style:italic}small.error,span.error{margin-bottom:1rem;color:#fff}.error input,.error select,.error textarea{margin-bottom:0}.error input[type=checkbox],.error input[type=radio],.error small.error{margin-bottom:1rem}.error label,.error label.error{color:#f04124}.error small.error{color:#fff}.contain-to-grid .top-bar,.top-bar,.top-bar-section .dropdown label,.top-bar .button,.top-bar button,.top-bar form,.top-bar input,.top-bar select,.top-bar ul,input.error,select.error,textarea.error{margin-bottom:0}.error>label>small{background:0 0;color:#676767;display:inline;font-size:60%;font-style:normal;margin:0;padding:0;text-transform:capitalize}.error span.error-message{display:block}label.error{color:#f04124}meta.foundation-mq-topbar{font-family:"/only screen and (min-width:40.0625em)/";width:40.0625em}.contain-to-grid{width:100%;background:#333}.fixed{position:fixed;top:0;width:100%;z-index:99;left:0}.fixed.expanded:not(.top-bar){height:auto;max-height:100%;overflow-y:auto;width:100%}.fixed.expanded:not(.top-bar) .title-area{position:fixed;width:100%;z-index:99}.fixed.expanded:not(.top-bar) .top-bar-section{margin-top:2.8125rem;z-index:98}.top-bar{height:2.8125rem;line-height:2.8125rem;overflow:hidden;position:relative}.top-bar .row{max-width:none}.top-bar input,.top-bar select{font-size:.75rem;height:1.75rem;padding-bottom:.35rem;padding-top:.35rem}.top-bar .button,.top-bar button{font-size:.75rem;padding-bottom:.4125rem;padding-top:.4125rem}@media only screen and (max-width:40em){.top-bar .button,.top-bar button{position:relative;top:-1px}}.top-bar .title-area{margin:0;position:relative}.top-bar .name{font-size:16px;height:2.8125rem;margin:0}.top-bar .name h1,.top-bar .name h2,.top-bar .name h3,.top-bar .name h4,.top-bar .name p,.top-bar .name span{font-size:1.0625rem;line-height:2.8125rem;margin:0}.top-bar .name h1 a,.top-bar .name h2 a,.top-bar .name h3 a,.top-bar .name h4 a,.top-bar .name p a,.top-bar .name span a{color:#fff;display:block;font-weight:400;padding:0 .9375rem;width:75%}.top-bar .toggle-topbar{position:absolute;right:0;top:0}.top-bar .toggle-topbar a{color:#fff;display:block;font-size:.8125rem;font-weight:700;height:2.8125rem;line-height:2.8125rem;padding:0 .9375rem;position:relative;text-transform:uppercase}.top-bar .toggle-topbar.menu-icon{margin-top:-16px;top:50%}.top-bar .toggle-topbar.menu-icon a{color:#fff;height:34px;line-height:33px;padding:0 2.5rem 0 .9375rem;position:relative}.top-bar .toggle-topbar.menu-icon a span:after{content:"";display:block;height:0;position:absolute;margin-top:-8px;top:50%;right:.9375rem;box-shadow:0 0 0 1px #fff,0 7px 0 1px #fff,0 14px 0 1px #fff;width:16px}.top-bar-section,.top-bar-section .has-dropdown{position:relative}.top-bar .toggle-topbar.menu-icon a span:hover:after{box-shadow:0 0 0 1px "",0 7px 0 1px "",0 14px 0 1px ""}.top-bar.expanded{background:0 0;height:auto}.top-bar-section ul li,.top-bar.expanded .title-area{background:#333}.top-bar.expanded .toggle-topbar a{color:#888}.top-bar.expanded .toggle-topbar a span:after{box-shadow:0 0 0 1px #888,0 7px 0 1px #888,0 14px 0 1px #888}@media screen and (-webkit-min-device-pixel-ratio:0){.top-bar.expanded .top-bar-section .dropdown,.top-bar.expanded .top-bar-section .has-dropdown.moved>.dropdown{clip:auto}.top-bar.expanded .top-bar-section .has-dropdown:not(.moved)>ul{padding:0}}.top-bar-section{left:0;width:auto;transition:left .3s ease-out}.top-bar-section ul{display:block;font-size:16px;height:auto;margin:0;padding:0;width:100%}.top-bar-section .divider,.top-bar-section [role=separator]{border-top:1px solid #1a1a1a;clear:both;height:1px;width:100%}.top-bar-section ul li>a{color:#fff;display:block;font-family:Helvetica Neue,Helvetica,Roboto,Arial,sans-serif;font-size:.8125rem;font-weight:400;padding:12px 0 12px .9375rem;text-transform:none;width:100%}.top-bar-section ul li>a.button,.top-bar-section ul li>button{font-size:.8125rem;padding-left:.9375rem;padding-right:.9375rem}.top-bar-section ul li>a.button{background-color:#008cba;border-color:#007095;color:#fff}.top-bar-section ul li>a.button:focus,.top-bar-section ul li>a.button:hover{background-color:#007095;color:#fff}.top-bar-section ul li>a.button.secondary{background-color:#e7e7e7;border-color:#b9b9b9;color:#333}.top-bar-section ul li>a.button.secondary:focus,.top-bar-section ul li>a.button.secondary:hover{background-color:#b9b9b9;color:#333}.top-bar-section ul li>a.button.success{background-color:#43ac6a;border-color:#368a55;color:#fff}.top-bar-section ul li>a.button.success:focus,.top-bar-section ul li>a.button.success:hover{background-color:#368a55;color:#fff}.top-bar-section ul li>a.button.alert{background-color:#f04124;border-color:#cf2a0e;color:#fff}.top-bar-section ul li>a.button.alert:focus,.top-bar-section ul li>a.button.alert:hover{background-color:#cf2a0e;color:#fff}.top-bar-section ul li>a.button.warning{background-color:#f08a24;border-color:#cf6e0e;color:#fff}.top-bar-section ul li>a.button.warning:focus,.top-bar-section ul li>a.button.warning:hover{background-color:#cf6e0e;color:#fff}.top-bar-section ul li>a.button.info{background-color:#a0d3e8;border-color:#61b6d9;color:#333}.top-bar-section ul li>a.button.info:focus,.top-bar-section ul li>a.button.info:hover{background-color:#61b6d9;color:#fff}.top-bar-section ul li>button{background-color:#008cba;border-color:#007095;color:#fff}.top-bar-section ul li>button:focus,.top-bar-section ul li>button:hover{background-color:#007095;color:#fff}.top-bar-section ul li>button.secondary{background-color:#e7e7e7;border-color:#b9b9b9;color:#333}.top-bar-section ul li>button.secondary:focus,.top-bar-section ul li>button.secondary:hover{background-color:#b9b9b9;color:#333}.top-bar-section ul li>button.success{background-color:#43ac6a;border-color:#368a55;color:#fff}.top-bar-section ul li>button.success:focus,.top-bar-section ul li>button.success:hover{background-color:#368a55;color:#fff}.top-bar-section ul li>button.alert{background-color:#f04124;border-color:#cf2a0e;color:#fff}.top-bar-section ul li>button.alert:focus,.top-bar-section ul li>button.alert:hover{background-color:#cf2a0e;color:#fff}.top-bar-section ul li>button.warning{background-color:#f08a24;border-color:#cf6e0e;color:#fff}.top-bar-section ul li>button.warning:focus,.top-bar-section ul li>button.warning:hover{background-color:#cf6e0e;color:#fff}.top-bar-section ul li>button.info{background-color:#a0d3e8;border-color:#61b6d9;color:#333}.top-bar-section ul li>button.info:focus,.top-bar-section ul li>button.info:hover{background-color:#61b6d9;color:#fff}.top-bar-section ul li:hover:not(.has-form)>a{color:#fff;background:#222}.top-bar-section ul li.active>a{background:#008cba;color:#fff}.top-bar-section ul li.active>a:hover{background:#0078a0;color:#fff}.top-bar-section .has-form{padding:.9375rem}.top-bar-section .has-dropdown>a:after{border:5px inset;content:"";display:block;height:0;width:0;border-color:transparent transparent transparent hsla(0,0%,100%,.4);border-left-style:solid;margin-right:.9375rem;margin-top:-4.5px;position:absolute;top:50%;right:0}.top-bar-section .has-dropdown.moved{position:static}.top-bar-section .has-dropdown.moved>.dropdown{height:auto;overflow:visible;clip:auto;display:block;position:absolute!important;width:100%}.top-bar-section .has-dropdown.moved>a:after{display:none}.top-bar-section .dropdown{clip:rect(1px,1px,1px,1px);height:1px;overflow:hidden;position:absolute!important;width:1px;display:block;padding:0;top:0;z-index:99;left:100%}.top-bar-section .dropdown li{height:auto;width:100%}.top-bar-section .dropdown li a{font-weight:400;padding:8px .9375rem}.top-bar-section .dropdown li a.parent-link{font-weight:400}.top-bar-section .dropdown li.parent-link,.top-bar-section .dropdown li.title h5{margin-bottom:0;margin-top:0;font-size:1.125rem}.top-bar-section .dropdown li.parent-link a,.top-bar-section .dropdown li.title h5 a{color:#fff;display:block}.top-bar-section .dropdown li.parent-link a:hover,.top-bar-section .dropdown li.title h5 a:hover{background:0 0}.top-bar-section .dropdown li.has-form{padding:8px .9375rem}.top-bar-section .dropdown li .button,.top-bar-section .dropdown li button{top:auto}.top-bar-section .dropdown label{color:#777;font-size:.625rem;font-weight:700;padding:8px .9375rem 2px;text-transform:uppercase}.subheader,code,p{font-weight:400}.js-generated{display:block}@media only screen and (min-width:40.0625em){.top-bar,.top-bar.expanded{background:#333}.top-bar-section ul li,.top-bar .title-area{float:left}.top-bar{overflow:visible}.top-bar:after,.top-bar:before{content:" ";display:table}.top-bar:after{clear:both}.top-bar .toggle-topbar{display:none}.top-bar .name h1 a,.top-bar .name h2 a,.top-bar .name h3 a,.top-bar .name h4 a,.top-bar .name h5 a,.top-bar .name h6 a{width:auto}.top-bar .button,.top-bar .has-form>.button,.top-bar .has-form>button,.top-bar button,.top-bar input,.top-bar select{font-size:.875rem;height:1.75rem;position:relative;top:.53125rem}.contain-to-grid .top-bar{margin:0 auto;max-width:62.5rem}.top-bar-section{transition:none 0 0;left:0!important}.top-bar-section ul{display:inline;height:auto!important;width:auto}.top-bar-section ul li .js-generated{display:none}.top-bar-section li.hover>a:not(.button){background:#222;color:#fff}.top-bar-section li:not(.has-form) a:not(.button){background:#333;line-height:2.8125rem;padding:0 .9375rem}.top-bar-section li:not(.has-form) a:not(.button):hover{background:#222}.top-bar-section li.active:not(.has-form) a:not(.button){background:#008cba;color:#fff;line-height:2.8125rem;padding:0 .9375rem}.top-bar-section li.active:not(.has-form) a:not(.button):hover{background:#0078a0;color:#fff}.top-bar-section .has-dropdown>a{padding-right:2.1875rem!important}.top-bar-section .has-dropdown>a:after{border:5px inset;content:"";display:block;height:0;width:0;border-color:hsla(0,0%,100%,.4) transparent transparent;border-top-style:solid;margin-top:-2.5px;top:1.40625rem}.top-bar-section .has-dropdown.moved{position:relative}.top-bar-section .has-dropdown.moved>.dropdown{clip:rect(1px,1px,1px,1px);height:1px;overflow:hidden;position:absolute!important;width:1px;display:block}.top-bar-section .has-dropdown.hover>.dropdown,.top-bar-section .has-dropdown.not-click:hover>.dropdown,.top-bar-section .has-dropdown>a:focus+.dropdown{height:auto;width:auto;overflow:visible;clip:auto;display:block;position:absolute!important}.top-bar-section .has-dropdown .dropdown li.has-dropdown>a:after{border:none;content:"\00bb";top:.1875rem;right:5px}.top-bar-section .dropdown{left:0;background:0 0;min-width:100%;top:auto}.top-bar-section .dropdown li a{background:#333;color:#fff;line-height:2.8125rem;padding:12px .9375rem;white-space:nowrap}.top-bar-section .dropdown li:not(.has-form):not(.active)>a:not(.button){background:#333;color:#fff}.top-bar-section .dropdown li:not(.has-form):not(.active):hover>a:not(.button){color:#fff;background:#222}.top-bar-section .dropdown li label{background:#333;white-space:nowrap}.top-bar-section .dropdown li .dropdown{left:100%;top:0}.top-bar-section>ul>.divider,.top-bar-section>ul>[role=separator]{border-right:1px solid #4e4e4e;border-bottom:none;border-top:none;clear:none;height:2.8125rem;width:0}.top-bar-section .has-form{background:#333;height:2.8125rem;padding:0 .9375rem}.top-bar-section .right li .dropdown{left:auto;right:0}.top-bar-section .right li .dropdown li .dropdown{right:100%}.top-bar-section .left li .dropdown{right:auto;left:0}.top-bar-section .left li .dropdown li .dropdown{left:100%}.no-js .top-bar-section ul li:hover>a{background:#222;color:#fff}.no-js .top-bar-section ul li:active>a{background:#008cba;color:#fff}.no-js .top-bar-section .has-dropdown:hover>.dropdown,.no-js .top-bar-section .has-dropdown>a:focus+.dropdown{height:auto;width:auto;overflow:visible;clip:auto;display:block;position:absolute!important}}.left-small,.right-small,.tab-bar-section{top:0;position:absolute}.inner-wrap:after,hr{clear:both}.inner-wrap,.off-canvas-wrap{width:100%;position:relative}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}.text-justify{text-align:justify!important}@media only screen and (max-width:40em){.small-only-text-left{text-align:left!important}.small-only-text-right{text-align:right!important}.small-only-text-center{text-align:center!important}.small-only-text-justify{text-align:justify!important}}@media only screen{.small-text-left{text-align:left!important}.small-text-right{text-align:right!important}.small-text-center{text-align:center!important}.small-text-justify{text-align:justify!important}}@media only screen and (min-width:40.0625em) and (max-width:64em){.medium-only-text-left{text-align:left!important}.medium-only-text-right{text-align:right!important}.medium-only-text-center{text-align:center!important}.medium-only-text-justify{text-align:justify!important}}@media only screen and (min-width:40.0625em){.medium-text-left{text-align:left!important}.medium-text-right{text-align:right!important}.medium-text-center{text-align:center!important}.medium-text-justify{text-align:justify!important}}@media only screen and (min-width:64.0625em) and (max-width:90em){.large-only-text-left{text-align:left!important}.large-only-text-right{text-align:right!important}.large-only-text-center{text-align:center!important}.large-only-text-justify{text-align:justify!important}}@media only screen and (min-width:64.0625em){.large-text-left{text-align:left!important}.large-text-right{text-align:right!important}.large-text-center{text-align:center!important}.large-text-justify{text-align:justify!important}}@media only screen and (min-width:90.0625em) and (max-width:120em){.xlarge-only-text-left{text-align:left!important}.xlarge-only-text-right{text-align:right!important}.xlarge-only-text-center{text-align:center!important}.xlarge-only-text-justify{text-align:justify!important}}@media only screen and (min-width:90.0625em){.xlarge-text-left{text-align:left!important}.xlarge-text-right{text-align:right!important}.xlarge-text-center{text-align:center!important}.xlarge-text-justify{text-align:justify!important}}@media only screen and (min-width:120.0625em) and (max-width:6249999.9375em){.xxlarge-only-text-left{text-align:left!important}.xxlarge-only-text-right{text-align:right!important}.xxlarge-only-text-center{text-align:center!important}.xxlarge-only-text-justify{text-align:justify!important}}@media only screen and (min-width:120.0625em){.xxlarge-text-left{text-align:left!important}.xxlarge-text-right{text-align:right!important}.xxlarge-text-center{text-align:center!important}.xxlarge-text-justify{text-align:justify!important}}blockquote,dd,div,dl,dt,form,h1,h2,h3,h4,h5,h6,li,ol,p,pre,td,th,ul{margin:0;padding:0}a{line-height:inherit}a:focus,a:hover{color:#0078a0}a img{border:none}p{margin-bottom:1.25rem}p.lead{font-size:1.21875rem;line-height:1.6}p aside{font-size:.875rem;font-style:italic;line-height:1.35}h1,h2,h3,h4,h5,h6{color:#222;font-style:normal;line-height:1.4}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{color:#6f6f6f;font-size:60%;line-height:0}h4,h5{font-size:1.125rem}h6{font-size:1rem}.subheader{line-height:1.4;color:#6f6f6f;margin-top:.2rem;margin-bottom:.5rem}b,em,i,small,strong{line-height:inherit}hr{box-sizing:content-box;border:solid #ddd;border-width:1px 0 0;height:0;margin:1.25rem 0 1.1875rem}em,i{font-style:italic}small{font-size:60%}code{background-color:#f8f8f8;border:1px solid #dfdfdf;color:#333;font-family:Consolas,Liberation Mono,Courier,monospace;padding:.125rem .3125rem .0625rem}.vcard .fn,.vevent .summary,.vevent abbr,dl dt,ul.off-canvas-list li label{font-weight:700}dl,ol,ul{font-family:inherit;font-size:1rem;line-height:1.6;list-style-position:outside;margin-bottom:1.25rem}ul li ol,ul li ul{margin-left:1.25rem;margin-bottom:0}ul.circle,ul.disc,ul.square{margin-left:1.1rem}ul.circle li ul,ul.disc li ul,ul.square li ul{list-style:inherit}ul.square{list-style-type:square}ul.circle{list-style-type:circle}ul.disc{list-style-type:disc}.fa-ul,.no-bullet,ul.off-canvas-list{list-style-type:none}ol li ol,ol li ul{margin-left:1.25rem;margin-bottom:0}.no-bullet{margin-left:0}.no-bullet li ol,.no-bullet li ul{margin-left:1.25rem;margin-bottom:0;list-style:none}dl dt{margin-bottom:.3rem}dl dd{margin-bottom:.75rem}.vcard,blockquote{margin:0 0 1.25rem}abbr,acronym{text-transform:uppercase;font-size:90%;color:#222;cursor:help}abbr{text-transform:none}abbr[title]{border-bottom:1px dotted #ddd}blockquote{padding:.5625rem 1.25rem 0 1.1875rem;border-left:1px solid #ddd}blockquote cite{display:block;font-size:.8125rem;color:#555}blockquote cite:before{content:"\2014 \0020"}blockquote cite a,blockquote cite a:visited{color:#555}blockquote,blockquote p{line-height:1.6;color:#6f6f6f}.vcard{display:inline-block;border:1px solid #ddd;padding:.625rem .75rem}.vcard li{margin:0;display:block}.vcard .fn{font-size:.9375rem}.vevent abbr{cursor:default;border:none;padding:0 .0625rem}@media only screen and (min-width:40.0625em){h1,h2,h3,h4,h5,h6{line-height:1.4}h1{font-size:2.75rem}h2{font-size:2.3125rem}h3{font-size:1.6875rem}h4{font-size:1.4375rem}h5{font-size:1.125rem}h6{font-size:1rem}}@media print{blockquote,img,pre,tr{page-break-inside:avoid}*{background:0 0!important;color:#000!important;box-shadow:none!important;text-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{border:1px solid #999}thead{display:table-header-group}img{max-width:100%!important}@page{margin:.34in}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}}.off-canvas-wrap{-webkit-backface-visibility:hidden;overflow:hidden}.off-canvas-wrap.move-bottom,.off-canvas-wrap.move-left,.off-canvas-wrap.move-right,.off-canvas-wrap.move-top{min-height:100%;-webkit-overflow-scrolling:touch}.inner-wrap{transition:transform .5s ease}.left-small,.right-small,.tab-bar .menu-icon{height:2.8125rem;width:2.8125rem}.inner-wrap:after,.inner-wrap:before{content:" ";display:table}.tab-bar{-webkit-backface-visibility:hidden;background:#333;color:#fff;height:2.8125rem;line-height:2.8125rem;position:relative}.tab-bar h1,.tab-bar h2,.tab-bar h3,.tab-bar h4,.tab-bar h5,.tab-bar h6{color:#fff;font-weight:700;line-height:2.8125rem;margin:0}.tab-bar h1,.tab-bar h2,.tab-bar h3,.tab-bar h4{font-size:1.125rem}.left-small{border-right:1px solid #1a1a1a;left:0}.right-small{border-left:1px solid #1a1a1a;right:0}.tab-bar-section{height:2.8125rem;padding:0 .625rem;text-align:center}.tab-bar-section.left{text-align:left;left:0;right:2.8125rem}.tab-bar-section.right{text-align:right;left:2.8125rem;right:0}.fa-fw,.fa-li{text-align:center}.tab-bar-section.middle{left:2.8125rem;right:2.8125rem}.tab-bar .menu-icon{color:#fff;display:block;padding:0;position:relative;text-indent:2.1875rem;transform:translateZ(0)}.tab-bar .menu-icon span:after{content:"";display:block;height:0;position:absolute;top:50%;margin-top:-.5rem;left:.90625rem;box-shadow:0 0 0 1px #fff,0 7px 0 1px #fff,0 14px 0 1px #fff;width:1rem}.left-off-canvas-menu,.right-off-canvas-menu{-webkit-backface-visibility:hidden;background:#333;box-sizing:content-box;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar;overflow-x:hidden;overflow-y:auto;position:absolute;transition:transform .5s ease 0s;width:15.625rem;bottom:0;top:0}.tab-bar .menu-icon span:hover:after{box-shadow:0 0 0 1px #b3b3b3,0 7px 0 1px #b3b3b3,0 14px 0 1px #b3b3b3}.left-off-canvas-menu{z-index:1001;transform:translate3d(-100%,0,0);left:0}.left-off-canvas-menu *{-webkit-backface-visibility:hidden}.right-off-canvas-menu{z-index:1001;transform:translate3d(100%,0,0);right:0}.bottom-off-canvas-menu,.top-off-canvas-menu{-webkit-backface-visibility:hidden;background:#333;box-sizing:content-box;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar;overflow-x:hidden;overflow-y:auto;position:absolute;transition:transform .5s ease 0s;z-index:1001;width:100%;height:18.75rem}.right-off-canvas-menu *{-webkit-backface-visibility:hidden}.top-off-canvas-menu{bottom:0;transform:translate3d(0,-100%,0);top:0}.top-off-canvas-menu *{-webkit-backface-visibility:hidden}.bottom-off-canvas-menu{transform:translate3d(0,100%,0);bottom:0}.move-bottom .exit-off-canvas,.move-left .exit-off-canvas,.move-right .exit-off-canvas,.move-top .exit-off-canvas{z-index:1002;-webkit-backface-visibility:hidden;box-shadow:-4px 0 4px rgba(0,0,0,.5),4px 0 4px rgba(0,0,0,.5);transition:background .3s ease;-webkit-tap-highlight-color:transparent;bottom:0;display:block;left:0;position:absolute;right:0;top:0;cursor:pointer}.bottom-off-canvas-menu *{-webkit-backface-visibility:hidden}ul.off-canvas-list{margin:0;padding:0}ul.off-canvas-list li label{background:#444;border-bottom:none;border-top:1px solid #5e5e5e;color:#999;display:block;font-size:.75rem;margin:0;padding:.3rem .9375rem;text-transform:uppercase}ul.off-canvas-list li a{border-bottom:1px solid #262626;color:hsla(0,0%,100%,.7);display:block;padding:.66667rem;transition:background .3s ease}.bottom-submenu .back>a,.left-submenu .back>a,.right-submenu .back>a,.top-submenu .back>a{color:#999;font-weight:700;padding:.3rem .9375rem;border-bottom:none;border-top:1px solid #5e5e5e;text-transform:uppercase}ul.off-canvas-list li a:active,ul.off-canvas-list li a:hover{background:#242424}.move-right>.inner-wrap{transform:translate3d(15.625rem,0,0)}.move-right .exit-off-canvas{background:hsla(0,0%,100%,.2)}@media only screen and (min-width:40.0625em){.move-right .exit-off-canvas:hover{background:hsla(0,0%,100%,.05)}}.move-left>.inner-wrap{transform:translate3d(-15.625rem,0,0)}.move-left .exit-off-canvas{background:hsla(0,0%,100%,.2)}@media only screen and (min-width:40.0625em){.move-left .exit-off-canvas:hover{background:hsla(0,0%,100%,.05)}}.move-top>.inner-wrap{transform:translate3d(0,-18.75rem,0)}.move-top .exit-off-canvas{background:hsla(0,0%,100%,.2)}@media only screen and (min-width:40.0625em){.move-top .exit-off-canvas:hover{background:hsla(0,0%,100%,.05)}}.move-bottom>.inner-wrap{transform:translate3d(0,18.75rem,0)}.move-bottom .exit-off-canvas{background:hsla(0,0%,100%,.2)}@media only screen and (min-width:40.0625em){.move-bottom .exit-off-canvas:hover{background:hsla(0,0%,100%,.05)}}.offcanvas-overlap .bottom-off-canvas-menu,.offcanvas-overlap .left-off-canvas-menu,.offcanvas-overlap .right-off-canvas-menu,.offcanvas-overlap .top-off-canvas-menu{transform:none;z-index:1003}.offcanvas-overlap .exit-off-canvas{-webkit-backface-visibility:hidden;box-shadow:-4px 0 4px rgba(0,0,0,.5),4px 0 4px rgba(0,0,0,.5);cursor:pointer;transition:background .3s ease;-webkit-tap-highlight-color:transparent;background:hsla(0,0%,100%,.2);bottom:0;display:block;left:0;position:absolute;right:0;top:0;z-index:1002}@media only screen and (min-width:40.0625em){.offcanvas-overlap .exit-off-canvas:hover{background:hsla(0,0%,100%,.05)}}.offcanvas-overlap-left .right-off-canvas-menu{transform:none;z-index:1003}.offcanvas-overlap-left .exit-off-canvas{-webkit-backface-visibility:hidden;box-shadow:-4px 0 4px rgba(0,0,0,.5),4px 0 4px rgba(0,0,0,.5);cursor:pointer;transition:background .3s ease;-webkit-tap-highlight-color:transparent;background:hsla(0,0%,100%,.2);bottom:0;display:block;left:0;position:absolute;right:0;top:0;z-index:1002}@media only screen and (min-width:40.0625em){.offcanvas-overlap-left .exit-off-canvas:hover{background:hsla(0,0%,100%,.05)}}.offcanvas-overlap-right .left-off-canvas-menu{transform:none;z-index:1003}.offcanvas-overlap-right .exit-off-canvas{-webkit-backface-visibility:hidden;box-shadow:-4px 0 4px rgba(0,0,0,.5),4px 0 4px rgba(0,0,0,.5);cursor:pointer;transition:background .3s ease;-webkit-tap-highlight-color:transparent;background:hsla(0,0%,100%,.2);bottom:0;display:block;left:0;position:absolute;right:0;top:0;z-index:1002}@media only screen and (min-width:40.0625em){.offcanvas-overlap-right .exit-off-canvas:hover{background:hsla(0,0%,100%,.05)}}.offcanvas-overlap-top .bottom-off-canvas-menu{transform:none;z-index:1003}.offcanvas-overlap-top .exit-off-canvas{-webkit-backface-visibility:hidden;box-shadow:-4px 0 4px rgba(0,0,0,.5),4px 0 4px rgba(0,0,0,.5);cursor:pointer;transition:background .3s ease;-webkit-tap-highlight-color:transparent;background:hsla(0,0%,100%,.2);bottom:0;display:block;left:0;position:absolute;right:0;top:0;z-index:1002}@media only screen and (min-width:40.0625em){.offcanvas-overlap-top .exit-off-canvas:hover{background:hsla(0,0%,100%,.05)}}.offcanvas-overlap-bottom .top-off-canvas-menu{transform:none;z-index:1003}.offcanvas-overlap-bottom .exit-off-canvas{-webkit-backface-visibility:hidden;box-shadow:-4px 0 4px rgba(0,0,0,.5),4px 0 4px rgba(0,0,0,.5);cursor:pointer;transition:background .3s ease;-webkit-tap-highlight-color:transparent;background:hsla(0,0%,100%,.2);bottom:0;display:block;left:0;position:absolute;right:0;top:0;z-index:1002}@media only screen and (min-width:40.0625em){.offcanvas-overlap-bottom .exit-off-canvas:hover{background:hsla(0,0%,100%,.05)}}.no-csstransforms .left-off-canvas-menu{left:-15.625rem}.no-csstransforms .right-off-canvas-menu{right:-15.625rem}.no-csstransforms .top-off-canvas-menu{top:-18.75rem}.no-csstransforms .bottom-off-canvas-menu{bottom:-18.75rem}.left-submenu,.right-submenu{-webkit-backface-visibility:hidden;-webkit-overflow-scrolling:touch;bottom:0;box-sizing:content-box;overflow-x:hidden;overflow-y:auto;position:absolute;top:0;width:15.625rem}.no-csstransforms .move-left>.inner-wrap{right:15.625rem}.no-csstransforms .move-right>.inner-wrap{left:15.625rem}.no-csstransforms .move-top>.inner-wrap{right:18.75rem}.no-csstransforms .move-bottom>.inner-wrap{left:18.75rem}.left-submenu{background:#333;margin:0;height:18.75rem;z-index:1002;transform:translate3d(-100%,0,0);left:0;transition:transform .5s ease}.left-submenu *{-webkit-backface-visibility:hidden}.left-submenu .back>a{background:#444;margin:0}.left-submenu .back>a:hover{background:#303030;border-bottom:none;border-top:1px solid #5e5e5e}.left-submenu .back>a:before{content:"\AB";margin-right:.5rem;display:inline}.left-submenu.move-right,.left-submenu.offcanvas-overlap,.left-submenu.offcanvas-overlap-right{transform:translateZ(0)}.right-submenu{background:#333;margin:0;transform:translate3d(100%,0,0);right:0}.bottom-submenu,.right-submenu,.top-submenu{height:18.75rem;z-index:1002;transition:transform .5s ease}.bottom-submenu,.top-submenu{-webkit-overflow-scrolling:touch;box-sizing:content-box;overflow-x:hidden;overflow-y:auto;position:absolute;top:0;bottom:0;width:100%}.bottom-submenu,.right-submenu *,.top-submenu{-webkit-backface-visibility:hidden}.right-submenu .back>a{background:#444;margin:0}.right-submenu .back>a:hover{background:#303030;border-bottom:none;border-top:1px solid #5e5e5e}.right-submenu .back>a:after{content:"\BB";margin-left:.5rem;display:inline}.right-submenu.move-left,.right-submenu.offcanvas-overlap,.right-submenu.offcanvas-overlap-left{transform:translateZ(0)}.top-submenu{background:#333;margin:0;transform:translate3d(0,-100%,0)}.top-submenu *{-webkit-backface-visibility:hidden}.top-submenu .back>a{background:#444;margin:0}.top-submenu .back>a:hover{background:#303030;border-bottom:none;border-top:1px solid #5e5e5e}.top-submenu.move-bottom,.top-submenu.offcanvas-overlap,.top-submenu.offcanvas-overlap-bottom{transform:translateZ(0)}.bottom-submenu{background:#333;margin:0;transform:translate3d(0,100%,0)}.container-full,.sidebar{box-sizing:border-box;height:100%}.sidebar a,.sidebar a .ripple span{transition:all .3s ease-in-out}.bottom-submenu *{-webkit-backface-visibility:hidden}.bottom-submenu .back>a{background:#444;margin:0}.bottom-submenu .back>a:hover{background:#303030;border-bottom:none;border-top:1px solid #5e5e5e}.bottom-submenu.move-top,.bottom-submenu.offcanvas-overlap,.bottom-submenu.offcanvas-overlap-top{transform:translateZ(0)}.left-off-canvas-menu ul.off-canvas-list li.has-submenu>a:after{content:"\BB";margin-left:.5rem;display:inline}.right-off-canvas-menu ul.off-canvas-list li.has-submenu>a:before{content:"\AB";margin-right:.5rem;display:inline}.fa.fa-pull-left,.fa.pull-left{margin-right:.3em}@media only screen{.hide-for-large,.hide-for-large-only,.hide-for-large-up,.hide-for-medium,.hide-for-medium-only,.hide-for-medium-up,.hide-for-xlarge,.hide-for-xlarge-only,.hide-for-xlarge-up,.hide-for-xxlarge,.hide-for-xxlarge-only,.hide-for-xxlarge-up,.show-for-large-down,.show-for-medium-down,.show-for-small,.show-for-small-down,.show-for-small-only,.show-for-small-up,.show-for-xlarge-down,.show-for-xxlarge-down{display:inherit!important}.hide-for-large-down,.hide-for-medium-down,.hide-for-small,.hide-for-small-down,.hide-for-small-only,.hide-for-small-up,.hide-for-xlarge-down,.hide-for-xxlarge-down,.show-for-large,.show-for-large-only,.show-for-large-up,.show-for-medium,.show-for-medium-only,.show-for-medium-up,.show-for-xlarge,.show-for-xlarge-only,.show-for-xlarge-up,.show-for-xxlarge,.show-for-xxlarge-only,.show-for-xxlarge-up{display:none!important}.hidden-for-large,.hidden-for-large-only,.hidden-for-large-up,.hidden-for-medium,.hidden-for-medium-only,.hidden-for-medium-up,.hidden-for-xlarge,.hidden-for-xlarge-only,.hidden-for-xlarge-up,.hidden-for-xxlarge,.hidden-for-xxlarge-only,.hidden-for-xxlarge-up,.visible-for-large-down,.visible-for-medium-down,.visible-for-small,.visible-for-small-down,.visible-for-small-only,.visible-for-small-up,.visible-for-xlarge-down,.visible-for-xxlarge-down{position:static!important;height:auto;width:auto;overflow:visible;clip:auto}.hidden-for-large-down,.hidden-for-medium-down,.hidden-for-small,.hidden-for-small-down,.hidden-for-small-only,.hidden-for-small-up,.hidden-for-xlarge-down,.hidden-for-xxlarge-down,.visible-for-large,.visible-for-large-only,.visible-for-large-up,.visible-for-medium,.visible-for-medium-only,.visible-for-medium-up,.visible-for-xlarge,.visible-for-xlarge-only,.visible-for-xlarge-up,.visible-for-xxlarge,.visible-for-xxlarge-only,.visible-for-xxlarge-up{clip:rect(1px,1px,1px,1px);height:1px;overflow:hidden;position:absolute!important;width:1px}table.hide-for-large,table.hide-for-large-only,table.hide-for-large-up,table.hide-for-medium,table.hide-for-medium-only,table.hide-for-medium-up,table.hide-for-xlarge,table.hide-for-xlarge-only,table.hide-for-xlarge-up,table.hide-for-xxlarge,table.hide-for-xxlarge-only,table.hide-for-xxlarge-up,table.show-for-large-down,table.show-for-medium-down,table.show-for-small,table.show-for-small-down,table.show-for-small-only,table.show-for-small-up,table.show-for-xlarge-down,table.show-for-xxlarge-down{display:table!important}thead.hide-for-large,thead.hide-for-large-only,thead.hide-for-large-up,thead.hide-for-medium,thead.hide-for-medium-only,thead.hide-for-medium-up,thead.hide-for-xlarge,thead.hide-for-xlarge-only,thead.hide-for-xlarge-up,thead.hide-for-xxlarge,thead.hide-for-xxlarge-only,thead.hide-for-xxlarge-up,thead.show-for-large-down,thead.show-for-medium-down,thead.show-for-small,thead.show-for-small-down,thead.show-for-small-only,thead.show-for-small-up,thead.show-for-xlarge-down,thead.show-for-xxlarge-down{display:table-header-group!important}tbody.hide-for-large,tbody.hide-for-large-only,tbody.hide-for-large-up,tbody.hide-for-medium,tbody.hide-for-medium-only,tbody.hide-for-medium-up,tbody.hide-for-xlarge,tbody.hide-for-xlarge-only,tbody.hide-for-xlarge-up,tbody.hide-for-xxlarge,tbody.hide-for-xxlarge-only,tbody.hide-for-xxlarge-up,tbody.show-for-large-down,tbody.show-for-medium-down,tbody.show-for-small,tbody.show-for-small-down,tbody.show-for-small-only,tbody.show-for-small-up,tbody.show-for-xlarge-down,tbody.show-for-xxlarge-down{display:table-row-group!important}tr.hide-for-large,tr.hide-for-large-only,tr.hide-for-large-up,tr.hide-for-medium,tr.hide-for-medium-only,tr.hide-for-medium-up,tr.hide-for-xlarge,tr.hide-for-xlarge-only,tr.hide-for-xlarge-up,tr.hide-for-xxlarge,tr.hide-for-xxlarge-only,tr.hide-for-xxlarge-up,tr.show-for-large-down,tr.show-for-medium-down,tr.show-for-small,tr.show-for-small-down,tr.show-for-small-only,tr.show-for-small-up,tr.show-for-xlarge-down,tr.show-for-xxlarge-down{display:table-row}td.hide-for-large,td.hide-for-large-only,td.hide-for-large-up,td.hide-for-medium,td.hide-for-medium-only,td.hide-for-medium-up,td.hide-for-xlarge,td.hide-for-xlarge-only,td.hide-for-xlarge-up,td.hide-for-xxlarge,td.hide-for-xxlarge-only,td.hide-for-xxlarge-up,td.show-for-large-down,td.show-for-medium-down,td.show-for-small,td.show-for-small-down,td.show-for-small-only,td.show-for-small-up,td.show-for-xlarge-down,td.show-for-xxlarge-down,th.hide-for-large,th.hide-for-large-only,th.hide-for-large-up,th.hide-for-medium,th.hide-for-medium-only,th.hide-for-medium-up,th.hide-for-xlarge,th.hide-for-xlarge-only,th.hide-for-xlarge-up,th.hide-for-xxlarge,th.hide-for-xxlarge-only,th.hide-for-xxlarge-up,th.show-for-large-down,th.show-for-medium-down,th.show-for-small,th.show-for-small-down,th.show-for-small-only,th.show-for-small-up,th.show-for-xlarge-down,th.show-for-xxlarge-down{display:table-cell!important}}@media only screen and (min-width:40.0625em){.hide-for-large,.hide-for-large-only,.hide-for-large-up,.hide-for-small,.hide-for-small-down,.hide-for-small-only,.hide-for-xlarge,.hide-for-xlarge-only,.hide-for-xlarge-up,.hide-for-xxlarge,.hide-for-xxlarge-only,.hide-for-xxlarge-up,.show-for-large-down,.show-for-medium,.show-for-medium-down,.show-for-medium-only,.show-for-medium-up,.show-for-small-up,.show-for-xlarge-down,.show-for-xxlarge-down{display:inherit!important}.hide-for-large-down,.hide-for-medium,.hide-for-medium-down,.hide-for-medium-only,.hide-for-medium-up,.hide-for-small-up,.hide-for-xlarge-down,.hide-for-xxlarge-down,.show-for-large,.show-for-large-only,.show-for-large-up,.show-for-small,.show-for-small-down,.show-for-small-only,.show-for-xlarge,.show-for-xlarge-only,.show-for-xlarge-up,.show-for-xxlarge,.show-for-xxlarge-only,.show-for-xxlarge-up{display:none!important}.hidden-for-large,.hidden-for-large-only,.hidden-for-large-up,.hidden-for-small,.hidden-for-small-down,.hidden-for-small-only,.hidden-for-xlarge,.hidden-for-xlarge-only,.hidden-for-xlarge-up,.hidden-for-xxlarge,.hidden-for-xxlarge-only,.hidden-for-xxlarge-up,.visible-for-large-down,.visible-for-medium,.visible-for-medium-down,.visible-for-medium-only,.visible-for-medium-up,.visible-for-small-up,.visible-for-xlarge-down,.visible-for-xxlarge-down{position:static!important;height:auto;width:auto;overflow:visible;clip:auto}.hidden-for-large-down,.hidden-for-medium,.hidden-for-medium-down,.hidden-for-medium-only,.hidden-for-medium-up,.hidden-for-small-up,.hidden-for-xlarge-down,.hidden-for-xxlarge-down,.visible-for-large,.visible-for-large-only,.visible-for-large-up,.visible-for-small,.visible-for-small-down,.visible-for-small-only,.visible-for-xlarge,.visible-for-xlarge-only,.visible-for-xlarge-up,.visible-for-xxlarge,.visible-for-xxlarge-only,.visible-for-xxlarge-up{clip:rect(1px,1px,1px,1px);height:1px;overflow:hidden;position:absolute!important;width:1px}table.hide-for-large,table.hide-for-large-only,table.hide-for-large-up,table.hide-for-small,table.hide-for-small-down,table.hide-for-small-only,table.hide-for-xlarge,table.hide-for-xlarge-only,table.hide-for-xlarge-up,table.hide-for-xxlarge,table.hide-for-xxlarge-only,table.hide-for-xxlarge-up,table.show-for-large-down,table.show-for-medium,table.show-for-medium-down,table.show-for-medium-only,table.show-for-medium-up,table.show-for-small-up,table.show-for-xlarge-down,table.show-for-xxlarge-down{display:table!important}thead.hide-for-large,thead.hide-for-large-only,thead.hide-for-large-up,thead.hide-for-small,thead.hide-for-small-down,thead.hide-for-small-only,thead.hide-for-xlarge,thead.hide-for-xlarge-only,thead.hide-for-xlarge-up,thead.hide-for-xxlarge,thead.hide-for-xxlarge-only,thead.hide-for-xxlarge-up,thead.show-for-large-down,thead.show-for-medium,thead.show-for-medium-down,thead.show-for-medium-only,thead.show-for-medium-up,thead.show-for-small-up,thead.show-for-xlarge-down,thead.show-for-xxlarge-down{display:table-header-group!important}tbody.hide-for-large,tbody.hide-for-large-only,tbody.hide-for-large-up,tbody.hide-for-small,tbody.hide-for-small-down,tbody.hide-for-small-only,tbody.hide-for-xlarge,tbody.hide-for-xlarge-only,tbody.hide-for-xlarge-up,tbody.hide-for-xxlarge,tbody.hide-for-xxlarge-only,tbody.hide-for-xxlarge-up,tbody.show-for-large-down,tbody.show-for-medium,tbody.show-for-medium-down,tbody.show-for-medium-only,tbody.show-for-medium-up,tbody.show-for-small-up,tbody.show-for-xlarge-down,tbody.show-for-xxlarge-down{display:table-row-group!important}tr.hide-for-large,tr.hide-for-large-only,tr.hide-for-large-up,tr.hide-for-small,tr.hide-for-small-down,tr.hide-for-small-only,tr.hide-for-xlarge,tr.hide-for-xlarge-only,tr.hide-for-xlarge-up,tr.hide-for-xxlarge,tr.hide-for-xxlarge-only,tr.hide-for-xxlarge-up,tr.show-for-large-down,tr.show-for-medium,tr.show-for-medium-down,tr.show-for-medium-only,tr.show-for-medium-up,tr.show-for-small-up,tr.show-for-xlarge-down,tr.show-for-xxlarge-down{display:table-row}td.hide-for-large,td.hide-for-large-only,td.hide-for-large-up,td.hide-for-small,td.hide-for-small-down,td.hide-for-small-only,td.hide-for-xlarge,td.hide-for-xlarge-only,td.hide-for-xlarge-up,td.hide-for-xxlarge,td.hide-for-xxlarge-only,td.hide-for-xxlarge-up,td.show-for-large-down,td.show-for-medium,td.show-for-medium-down,td.show-for-medium-only,td.show-for-medium-up,td.show-for-small-up,td.show-for-xlarge-down,td.show-for-xxlarge-down,th.hide-for-large,th.hide-for-large-only,th.hide-for-large-up,th.hide-for-small,th.hide-for-small-down,th.hide-for-small-only,th.hide-for-xlarge,th.hide-for-xlarge-only,th.hide-for-xlarge-up,th.hide-for-xxlarge,th.hide-for-xxlarge-only,th.hide-for-xxlarge-up,th.show-for-large-down,th.show-for-medium,th.show-for-medium-down,th.show-for-medium-only,th.show-for-medium-up,th.show-for-small-up,th.show-for-xlarge-down,th.show-for-xxlarge-down{display:table-cell!important}}@media only screen and (min-width:64.0625em){.hide-for-medium,.hide-for-medium-down,.hide-for-medium-only,.hide-for-small,.hide-for-small-down,.hide-for-small-only,.hide-for-xlarge,.hide-for-xlarge-only,.hide-for-xlarge-up,.hide-for-xxlarge,.hide-for-xxlarge-only,.hide-for-xxlarge-up,.show-for-large,.show-for-large-down,.show-for-large-only,.show-for-large-up,.show-for-medium-up,.show-for-small-up,.show-for-xlarge-down,.show-for-xxlarge-down{display:inherit!important}.hide-for-large,.hide-for-large-down,.hide-for-large-only,.hide-for-large-up,.hide-for-medium-up,.hide-for-small-up,.hide-for-xlarge-down,.hide-for-xxlarge-down,.show-for-medium,.show-for-medium-down,.show-for-medium-only,.show-for-small,.show-for-small-down,.show-for-small-only,.show-for-xlarge,.show-for-xlarge-only,.show-for-xlarge-up,.show-for-xxlarge,.show-for-xxlarge-only,.show-for-xxlarge-up{display:none!important}.hidden-for-medium,.hidden-for-medium-down,.hidden-for-medium-only,.hidden-for-small,.hidden-for-small-down,.hidden-for-small-only,.hidden-for-xlarge,.hidden-for-xlarge-only,.hidden-for-xlarge-up,.hidden-for-xxlarge,.hidden-for-xxlarge-only,.hidden-for-xxlarge-up,.visible-for-large,.visible-for-large-down,.visible-for-large-only,.visible-for-large-up,.visible-for-medium-up,.visible-for-small-up,.visible-for-xlarge-down,.visible-for-xxlarge-down{position:static!important;height:auto;width:auto;overflow:visible;clip:auto}.hidden-for-large,.hidden-for-large-down,.hidden-for-large-only,.hidden-for-large-up,.hidden-for-medium-up,.hidden-for-small-up,.hidden-for-xlarge-down,.hidden-for-xxlarge-down,.visible-for-medium,.visible-for-medium-down,.visible-for-medium-only,.visible-for-small,.visible-for-small-down,.visible-for-small-only,.visible-for-xlarge,.visible-for-xlarge-only,.visible-for-xlarge-up,.visible-for-xxlarge,.visible-for-xxlarge-only,.visible-for-xxlarge-up{clip:rect(1px,1px,1px,1px);height:1px;overflow:hidden;position:absolute!important;width:1px}table.hide-for-medium,table.hide-for-medium-down,table.hide-for-medium-only,table.hide-for-small,table.hide-for-small-down,table.hide-for-small-only,table.hide-for-xlarge,table.hide-for-xlarge-only,table.hide-for-xlarge-up,table.hide-for-xxlarge,table.hide-for-xxlarge-only,table.hide-for-xxlarge-up,table.show-for-large,table.show-for-large-down,table.show-for-large-only,table.show-for-large-up,table.show-for-medium-up,table.show-for-small-up,table.show-for-xlarge-down,table.show-for-xxlarge-down{display:table!important}thead.hide-for-medium,thead.hide-for-medium-down,thead.hide-for-medium-only,thead.hide-for-small,thead.hide-for-small-down,thead.hide-for-small-only,thead.hide-for-xlarge,thead.hide-for-xlarge-only,thead.hide-for-xlarge-up,thead.hide-for-xxlarge,thead.hide-for-xxlarge-only,thead.hide-for-xxlarge-up,thead.show-for-large,thead.show-for-large-down,thead.show-for-large-only,thead.show-for-large-up,thead.show-for-medium-up,thead.show-for-small-up,thead.show-for-xlarge-down,thead.show-for-xxlarge-down{display:table-header-group!important}tbody.hide-for-medium,tbody.hide-for-medium-down,tbody.hide-for-medium-only,tbody.hide-for-small,tbody.hide-for-small-down,tbody.hide-for-small-only,tbody.hide-for-xlarge,tbody.hide-for-xlarge-only,tbody.hide-for-xlarge-up,tbody.hide-for-xxlarge,tbody.hide-for-xxlarge-only,tbody.hide-for-xxlarge-up,tbody.show-for-large,tbody.show-for-large-down,tbody.show-for-large-only,tbody.show-for-large-up,tbody.show-for-medium-up,tbody.show-for-small-up,tbody.show-for-xlarge-down,tbody.show-for-xxlarge-down{display:table-row-group!important}tr.hide-for-medium,tr.hide-for-medium-down,tr.hide-for-medium-only,tr.hide-for-small,tr.hide-for-small-down,tr.hide-for-small-only,tr.hide-for-xlarge,tr.hide-for-xlarge-only,tr.hide-for-xlarge-up,tr.hide-for-xxlarge,tr.hide-for-xxlarge-only,tr.hide-for-xxlarge-up,tr.show-for-large,tr.show-for-large-down,tr.show-for-large-only,tr.show-for-large-up,tr.show-for-medium-up,tr.show-for-small-up,tr.show-for-xlarge-down,tr.show-for-xxlarge-down{display:table-row}td.hide-for-medium,td.hide-for-medium-down,td.hide-for-medium-only,td.hide-for-small,td.hide-for-small-down,td.hide-for-small-only,td.hide-for-xlarge,td.hide-for-xlarge-only,td.hide-for-xlarge-up,td.hide-for-xxlarge,td.hide-for-xxlarge-only,td.hide-for-xxlarge-up,td.show-for-large,td.show-for-large-down,td.show-for-large-only,td.show-for-large-up,td.show-for-medium-up,td.show-for-small-up,td.show-for-xlarge-down,td.show-for-xxlarge-down,th.hide-for-medium,th.hide-for-medium-down,th.hide-for-medium-only,th.hide-for-small,th.hide-for-small-down,th.hide-for-small-only,th.hide-for-xlarge,th.hide-for-xlarge-only,th.hide-for-xlarge-up,th.hide-for-xxlarge,th.hide-for-xxlarge-only,th.hide-for-xxlarge-up,th.show-for-large,th.show-for-large-down,th.show-for-large-only,th.show-for-large-up,th.show-for-medium-up,th.show-for-small-up,th.show-for-xlarge-down,th.show-for-xxlarge-down{display:table-cell!important}}@media only screen and (min-width:90.0625em){.hide-for-large,.hide-for-large-down,.hide-for-large-only,.hide-for-medium,.hide-for-medium-down,.hide-for-medium-only,.hide-for-small,.hide-for-small-down,.hide-for-small-only,.hide-for-xxlarge,.hide-for-xxlarge-only,.hide-for-xxlarge-up,.show-for-large-up,.show-for-medium-up,.show-for-small-up,.show-for-xlarge,.show-for-xlarge-down,.show-for-xlarge-only,.show-for-xlarge-up,.show-for-xxlarge-down{display:inherit!important}.hide-for-large-up,.hide-for-medium-up,.hide-for-small-up,.hide-for-xlarge,.hide-for-xlarge-down,.hide-for-xlarge-only,.hide-for-xlarge-up,.hide-for-xxlarge-down,.show-for-large,.show-for-large-down,.show-for-large-only,.show-for-medium,.show-for-medium-down,.show-for-medium-only,.show-for-small,.show-for-small-down,.show-for-small-only,.show-for-xxlarge,.show-for-xxlarge-only,.show-for-xxlarge-up{display:none!important}.hidden-for-large,.hidden-for-large-down,.hidden-for-large-only,.hidden-for-medium,.hidden-for-medium-down,.hidden-for-medium-only,.hidden-for-small,.hidden-for-small-down,.hidden-for-small-only,.hidden-for-xxlarge,.hidden-for-xxlarge-only,.hidden-for-xxlarge-up,.visible-for-large-up,.visible-for-medium-up,.visible-for-small-up,.visible-for-xlarge,.visible-for-xlarge-down,.visible-for-xlarge-only,.visible-for-xlarge-up,.visible-for-xxlarge-down{position:static!important;height:auto;width:auto;overflow:visible;clip:auto}.hidden-for-large-up,.hidden-for-medium-up,.hidden-for-small-up,.hidden-for-xlarge,.hidden-for-xlarge-down,.hidden-for-xlarge-only,.hidden-for-xlarge-up,.hidden-for-xxlarge-down,.visible-for-large,.visible-for-large-down,.visible-for-large-only,.visible-for-medium,.visible-for-medium-down,.visible-for-medium-only,.visible-for-small,.visible-for-small-down,.visible-for-small-only,.visible-for-xxlarge,.visible-for-xxlarge-only,.visible-for-xxlarge-up{clip:rect(1px,1px,1px,1px);height:1px;overflow:hidden;position:absolute!important;width:1px}table.hide-for-large,table.hide-for-large-down,table.hide-for-large-only,table.hide-for-medium,table.hide-for-medium-down,table.hide-for-medium-only,table.hide-for-small,table.hide-for-small-down,table.hide-for-small-only,table.hide-for-xxlarge,table.hide-for-xxlarge-only,table.hide-for-xxlarge-up,table.show-for-large-up,table.show-for-medium-up,table.show-for-small-up,table.show-for-xlarge,table.show-for-xlarge-down,table.show-for-xlarge-only,table.show-for-xlarge-up,table.show-for-xxlarge-down{display:table!important}thead.hide-for-large,thead.hide-for-large-down,thead.hide-for-large-only,thead.hide-for-medium,thead.hide-for-medium-down,thead.hide-for-medium-only,thead.hide-for-small,thead.hide-for-small-down,thead.hide-for-small-only,thead.hide-for-xxlarge,thead.hide-for-xxlarge-only,thead.hide-for-xxlarge-up,thead.show-for-large-up,thead.show-for-medium-up,thead.show-for-small-up,thead.show-for-xlarge,thead.show-for-xlarge-down,thead.show-for-xlarge-only,thead.show-for-xlarge-up,thead.show-for-xxlarge-down{display:table-header-group!important}tbody.hide-for-large,tbody.hide-for-large-down,tbody.hide-for-large-only,tbody.hide-for-medium,tbody.hide-for-medium-down,tbody.hide-for-medium-only,tbody.hide-for-small,tbody.hide-for-small-down,tbody.hide-for-small-only,tbody.hide-for-xxlarge,tbody.hide-for-xxlarge-only,tbody.hide-for-xxlarge-up,tbody.show-for-large-up,tbody.show-for-medium-up,tbody.show-for-small-up,tbody.show-for-xlarge,tbody.show-for-xlarge-down,tbody.show-for-xlarge-only,tbody.show-for-xlarge-up,tbody.show-for-xxlarge-down{display:table-row-group!important}tr.hide-for-large,tr.hide-for-large-down,tr.hide-for-large-only,tr.hide-for-medium,tr.hide-for-medium-down,tr.hide-for-medium-only,tr.hide-for-small,tr.hide-for-small-down,tr.hide-for-small-only,tr.hide-for-xxlarge,tr.hide-for-xxlarge-only,tr.hide-for-xxlarge-up,tr.show-for-large-up,tr.show-for-medium-up,tr.show-for-small-up,tr.show-for-xlarge,tr.show-for-xlarge-down,tr.show-for-xlarge-only,tr.show-for-xlarge-up,tr.show-for-xxlarge-down{display:table-row}td.hide-for-large,td.hide-for-large-down,td.hide-for-large-only,td.hide-for-medium,td.hide-for-medium-down,td.hide-for-medium-only,td.hide-for-small,td.hide-for-small-down,td.hide-for-small-only,td.hide-for-xxlarge,td.hide-for-xxlarge-only,td.hide-for-xxlarge-up,td.show-for-large-up,td.show-for-medium-up,td.show-for-small-up,td.show-for-xlarge,td.show-for-xlarge-down,td.show-for-xlarge-only,td.show-for-xlarge-up,td.show-for-xxlarge-down,th.hide-for-large,th.hide-for-large-down,th.hide-for-large-only,th.hide-for-medium,th.hide-for-medium-down,th.hide-for-medium-only,th.hide-for-small,th.hide-for-small-down,th.hide-for-small-only,th.hide-for-xxlarge,th.hide-for-xxlarge-only,th.hide-for-xxlarge-up,th.show-for-large-up,th.show-for-medium-up,th.show-for-small-up,th.show-for-xlarge,th.show-for-xlarge-down,th.show-for-xlarge-only,th.show-for-xlarge-up,th.show-for-xxlarge-down{display:table-cell!important}}@media only screen and (min-width:120.0625em){.hide-for-large,.hide-for-large-down,.hide-for-large-only,.hide-for-medium,.hide-for-medium-down,.hide-for-medium-only,.hide-for-small,.hide-for-small-down,.hide-for-small-only,.hide-for-xlarge,.hide-for-xlarge-down,.hide-for-xlarge-only,.show-for-large-up,.show-for-medium-up,.show-for-small-up,.show-for-xlarge-up,.show-for-xxlarge,.show-for-xxlarge-down,.show-for-xxlarge-only,.show-for-xxlarge-up{display:inherit!important}.hide-for-large-up,.hide-for-medium-up,.hide-for-small-up,.hide-for-xlarge-up,.hide-for-xxlarge,.hide-for-xxlarge-down,.hide-for-xxlarge-only,.hide-for-xxlarge-up,.show-for-large,.show-for-large-down,.show-for-large-only,.show-for-medium,.show-for-medium-down,.show-for-medium-only,.show-for-small,.show-for-small-down,.show-for-small-only,.show-for-xlarge,.show-for-xlarge-down,.show-for-xlarge-only{display:none!important}.hidden-for-large,.hidden-for-large-down,.hidden-for-large-only,.hidden-for-medium,.hidden-for-medium-down,.hidden-for-medium-only,.hidden-for-small,.hidden-for-small-down,.hidden-for-small-only,.hidden-for-xlarge,.hidden-for-xlarge-down,.hidden-for-xlarge-only,.visible-for-large-up,.visible-for-medium-up,.visible-for-small-up,.visible-for-xlarge-up,.visible-for-xxlarge,.visible-for-xxlarge-down,.visible-for-xxlarge-only,.visible-for-xxlarge-up{position:static!important;height:auto;width:auto;overflow:visible;clip:auto}.hidden-for-large-up,.hidden-for-medium-up,.hidden-for-small-up,.hidden-for-xlarge-up,.hidden-for-xxlarge,.hidden-for-xxlarge-down,.hidden-for-xxlarge-only,.hidden-for-xxlarge-up,.visible-for-large,.visible-for-large-down,.visible-for-large-only,.visible-for-medium,.visible-for-medium-down,.visible-for-medium-only,.visible-for-small,.visible-for-small-down,.visible-for-small-only,.visible-for-xlarge,.visible-for-xlarge-down,.visible-for-xlarge-only{clip:rect(1px,1px,1px,1px);height:1px;overflow:hidden;position:absolute!important;width:1px}table.hide-for-large,table.hide-for-large-down,table.hide-for-large-only,table.hide-for-medium,table.hide-for-medium-down,table.hide-for-medium-only,table.hide-for-small,table.hide-for-small-down,table.hide-for-small-only,table.hide-for-xlarge,table.hide-for-xlarge-down,table.hide-for-xlarge-only,table.show-for-large-up,table.show-for-medium-up,table.show-for-small-up,table.show-for-xlarge-up,table.show-for-xxlarge,table.show-for-xxlarge-down,table.show-for-xxlarge-only,table.show-for-xxlarge-up{display:table!important}thead.hide-for-large,thead.hide-for-large-down,thead.hide-for-large-only,thead.hide-for-medium,thead.hide-for-medium-down,thead.hide-for-medium-only,thead.hide-for-small,thead.hide-for-small-down,thead.hide-for-small-only,thead.hide-for-xlarge,thead.hide-for-xlarge-down,thead.hide-for-xlarge-only,thead.show-for-large-up,thead.show-for-medium-up,thead.show-for-small-up,thead.show-for-xlarge-up,thead.show-for-xxlarge,thead.show-for-xxlarge-down,thead.show-for-xxlarge-only,thead.show-for-xxlarge-up{display:table-header-group!important}tbody.hide-for-large,tbody.hide-for-large-down,tbody.hide-for-large-only,tbody.hide-for-medium,tbody.hide-for-medium-down,tbody.hide-for-medium-only,tbody.hide-for-small,tbody.hide-for-small-down,tbody.hide-for-small-only,tbody.hide-for-xlarge,tbody.hide-for-xlarge-down,tbody.hide-for-xlarge-only,tbody.show-for-large-up,tbody.show-for-medium-up,tbody.show-for-small-up,tbody.show-for-xlarge-up,tbody.show-for-xxlarge,tbody.show-for-xxlarge-down,tbody.show-for-xxlarge-only,tbody.show-for-xxlarge-up{display:table-row-group!important}tr.hide-for-large,tr.hide-for-large-down,tr.hide-for-large-only,tr.hide-for-medium,tr.hide-for-medium-down,tr.hide-for-medium-only,tr.hide-for-small,tr.hide-for-small-down,tr.hide-for-small-only,tr.hide-for-xlarge,tr.hide-for-xlarge-down,tr.hide-for-xlarge-only,tr.show-for-large-up,tr.show-for-medium-up,tr.show-for-small-up,tr.show-for-xlarge-up,tr.show-for-xxlarge,tr.show-for-xxlarge-down,tr.show-for-xxlarge-only,tr.show-for-xxlarge-up{display:table-row}td.hide-for-large,td.hide-for-large-down,td.hide-for-large-only,td.hide-for-medium,td.hide-for-medium-down,td.hide-for-medium-only,td.hide-for-small,td.hide-for-small-down,td.hide-for-small-only,td.hide-for-xlarge,td.hide-for-xlarge-down,td.hide-for-xlarge-only,td.show-for-large-up,td.show-for-medium-up,td.show-for-small-up,td.show-for-xlarge-up,td.show-for-xxlarge,td.show-for-xxlarge-down,td.show-for-xxlarge-only,td.show-for-xxlarge-up,th.hide-for-large,th.hide-for-large-down,th.hide-for-large-only,th.hide-for-medium,th.hide-for-medium-down,th.hide-for-medium-only,th.hide-for-small,th.hide-for-small-down,th.hide-for-small-only,th.hide-for-xlarge,th.hide-for-xlarge-down,th.hide-for-xlarge-only,th.show-for-large-up,th.show-for-medium-up,th.show-for-small-up,th.show-for-xlarge-up,th.show-for-xxlarge,th.show-for-xxlarge-down,th.show-for-xxlarge-only,th.show-for-xxlarge-up{display:table-cell!important}}.hide-for-portrait,.show-for-landscape{display:inherit!important}.hide-for-landscape,.show-for-portrait{display:none!important}table.hide-for-landscape,table.show-for-portrait{display:table!important}thead.hide-for-landscape,thead.show-for-portrait{display:table-header-group!important}tbody.hide-for-landscape,tbody.show-for-portrait{display:table-row-group!important}tr.hide-for-landscape,tr.show-for-portrait{display:table-row!important}td.hide-for-landscape,td.show-for-portrait,th.hide-for-landscape,th.show-for-portrait{display:table-cell!important}@media only screen and (orientation:landscape){.hide-for-portrait,.show-for-landscape{display:inherit!important}.hide-for-landscape,.show-for-portrait{display:none!important}table.hide-for-portrait,table.show-for-landscape{display:table!important}thead.hide-for-portrait,thead.show-for-landscape{display:table-header-group!important}tbody.hide-for-portrait,tbody.show-for-landscape{display:table-row-group!important}tr.hide-for-portrait,tr.show-for-landscape{display:table-row!important}td.hide-for-portrait,td.show-for-landscape,th.hide-for-portrait,th.show-for-landscape{display:table-cell!important}}@media only screen and (orientation:portrait){.hide-for-landscape,.show-for-portrait{display:inherit!important}.hide-for-portrait,.show-for-landscape{display:none!important}table.hide-for-landscape,table.show-for-portrait{display:table!important}thead.hide-for-landscape,thead.show-for-portrait{display:table-header-group!important}tbody.hide-for-landscape,tbody.show-for-portrait{display:table-row-group!important}tr.hide-for-landscape,tr.show-for-portrait{display:table-row!important}td.hide-for-landscape,td.show-for-portrait,th.hide-for-landscape,th.show-for-portrait{display:table-cell!important}}.show-for-touch{display:none!important}.hide-for-touch,.touch .show-for-touch{display:inherit!important}.touch .hide-for-touch{display:none!important}.touch table.show-for-touch,table.hide-for-touch{display:table!important}.touch thead.show-for-touch,thead.hide-for-touch{display:table-header-group!important}.touch tbody.show-for-touch,tbody.hide-for-touch{display:table-row-group!important}.touch tr.show-for-touch,tr.hide-for-touch{display:table-row!important}.touch td.show-for-touch,.touch th.show-for-touch,td.hide-for-touch,th.hide-for-touch{display:table-cell!important}.show-for-sr,.show-on-focus{clip:rect(1px,1px,1px,1px);height:1px;overflow:hidden;position:absolute!important;width:1px}.show-on-focus:active,.show-on-focus:focus{position:static!important;height:auto;width:auto;overflow:visible;clip:auto}.print-only,.show-for-print{display:none!important}@media print{.print-only,.show-for-print{display:block!important}.hide-for-print,.hide-on-print{display:none!important}table.show-for-print{display:table!important}thead.show-for-print{display:table-header-group!important}tbody.show-for-print{display:table-row-group!important}tr.show-for-print{display:table-row!important}td.show-for-print,th.show-for-print{display:table-cell!important}}.fa,.fa-stack,.sidebar a .ripple{display:inline-block}/*! - * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome - * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) - */@font-face{font-family:FontAwesome;src:url(../fonts/fontawesome-webfont.eot?v=4.7.0);src:url(../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0) format("embedded-opentype"),url(../fonts/fontawesome-webfont.woff2?v=4.7.0) format("woff2"),url(../fonts/fontawesome-webfont.woff?v=4.7.0) format("woff"),url(../fonts/fontawesome-webfont.ttf?v=4.7.0) format("truetype"),url(../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa{font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em}.fa-ul{padding-left:0;margin-left:2.14286em}.fa.fa-pull-right,.fa.pull-right{margin-left:.3em}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right,.pull-right{float:right}.pull-left{float:left}.fa-spin{animation:a 2s infinite linear}.fa-pulse{animation:a 1s infinite steps(8)}@keyframes a{0%{transform:rotate(0)}to{transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before{content:""}.fa-check-circle:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before{content:""}.fa-arrow-circle-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}@font-face{font-family:klinic-reg;src:url(../fonts/klinicslabbook-webfont.eot);src:url(../fonts/klinicslabbook-webfont.eot?#iefix) format("embedded-opentype"),url(../fonts/klinicslabbook-webfont.woff2) format("woff2"),url(../fonts/klinicslabbook-webfont.woff) format("woff"),url(../fonts/klinicslabbook-webfont.ttf) format("truetype"),url(../fonts/klinicslabbook-webfont.svg#klinic_slabbook) format("svg");font-weight:400;font-style:normal}@font-face{font-family:klinic-bold;src:url(../fonts/klinicslabmedium-webfont.eot);src:url(../fonts/klinicslabmedium-webfont.eot?#iefix) format("embedded-opentype"),url(../fonts/klinicslabmedium-webfont.woff2) format("woff2"),url(../fonts/klinicslabmedium-webfont.woff) format("woff"),url(../fonts/klinicslabmedium-webfont.ttf) format("truetype"),url(../fonts/klinicslabmedium-webfont.svg#klinic_slabmedium) format("svg");font-weight:500;font-style:normal}.button{border-radius:.15em;font-family:klinic-bold,klinic bold,Helvetica Neue,Helvetica,Arial,sans-serif;font-weight:600;letter-spacing:.05em;-webkit-font-smoothing:antialiased;line-height:1.636;background-color:#2dafe9}.x0{font-size:10px}.x1{font-size:12px}.x2{font-size:13px}.x3{font-size:14px}.x4{font-size:15px}.x5{font-size:17.92px}.x6{font-size:20px}.x7{font-size:24px}.x8{font-size:32px}.x9{font-size:36px}.x10,h1{font-size:47.2px}h1,h2,h3,h4,h5,h6{font-family:klinic-reg,klinic,Helvetica Neue,Helvetica,Arial,sans-serif;font-weight:400;letter-spacing:.0075em;-webkit-font-smoothing:antialiased;margin-top:.83333rem;margin-bottom:.83333rem}h1,h2 .onboard-welcome,h2.onboard-welcome{color:#277a9f;font-family:klinic-bold,klinic bold,Helvetica Neue,Helvetica,Arial,sans-serif;font-weight:600;letter-spacing:.05em;-webkit-font-smoothing:antialiased}h1{text-transform:uppercase}h2{font-size:36px}h2 .onboard-welcome,h2.onboard-welcome{font-size:47.2px}h2 .onboard-tasks,h2.onboard-tasks{color:#2090cd}h2 .onboard,h2.onboard{color:#277a9f}h2 .welcome-text,h2.welcome-text{color:#277a9f;font-size:28px;font-family:klinic-reg,klinic,Helvetica Neue,Helvetica,Arial,sans-serif;font-weight:400;letter-spacing:.0075em;-webkit-font-smoothing:antialiased}.content h3,h4{font-family:klinic-bold,klinic bold,Helvetica Neue,Helvetica,Arial,sans-serif;font-weight:600;letter-spacing:.05em}h3{font-size:24px}.content h3{text-transform:uppercase;font-size:13px;color:#999}.content h3,h4{-webkit-font-smoothing:antialiased}h4{font-size:12px}.content h5,.line-chart-wrap h5,.regular-text{font-weight:400;-webkit-font-smoothing:antialiased}.content h5,.line-chart-wrap h5,.text-upper{letter-spacing:.25em;text-transform:uppercase}h4 .day,h4.day{color:#999}h5{color:#333}.content h5,.line-chart-wrap h5{font-family:klinic-reg,klinic,Helvetica Neue,Helvetica,Arial,sans-serif;font-size:12px}blockquote,dl,ol,p,ul{font-size:14px;padding-right:5%;font-family:Helvetica Neue,Helvetica,Arial,sans-serif}p{line-height:2.15;color:#666}ol,ul{margin-left:1.8rem;margin-bottom:2.5rem}ol li,ul li{margin-bottom:.5em}a{color:#2ba0d3}.regular-text{font-family:klinic-reg,klinic,Helvetica Neue,Helvetica,Arial,sans-serif;letter-spacing:.0075em}.postfix,.prefix{font-family:klinic-bold,klinic bold,Helvetica Neue,Helvetica,Arial,sans-serif;font-weight:600;border-radius:3px;text-transform:uppercase;letter-spacing:.25em;font-size:14px;height:3.3125rem;line-height:3.3125rem}.postfix,.prefix,body,html{-webkit-font-smoothing:antialiased}body,html{height:100%;padding:0;margin:0;background:url(../img/pattern-topo-sm.png),linear-gradient(170deg,#ebf7fc 5%,#fff);background:url(../img/pattern-topo-sm.png),-webkit-gradient(170deg,right top,color-stop(5%,#ebf7fc),color-stop(100%,#fff));background:url(../img/pattern-topo-sm.png),-webkit-linear-gradient(170deg,#ebf7fc 5%,#fff);background-position:static;background-attachment:fixed}.main{min-height:760px}.container-full{overflow-x:hidden;padding-left:300px;width:100%}.sidebar{width:25%;width:300px;left:0;top:0;background:#d4ebf5;z-index:700;position:fixed;overflow-y:scroll;border-right:1px solid #cfedfa}.sidebar a .ripple{margin:auto 0}.sidebar a .ripple span{display:block;margin:0 auto;background:#2090cd;width:10%;opacity:0;height:3px}.sidebar a:hover .ripple span{width:100%;opacity:1}.sidebar h1{margin:0;padding:0;text-transform:none}.sidebar h1 a{display:block;width:100%;padding:.333em 2.25rem;background-color:#fff;text-align:left}.sidebar h1 a img,.sidebar h1 a svg{display:block;fill:currentColor;transition:all .3s ease-in-out}.sidebar h1 a span{top:1em;position:absolute;font-size:1.5rem;color:#2090cd;left:6.5rem;font-family:klinic-reg,klinic,Helvetica Neue,Helvetica,Arial,sans-serif;font-weight:400;letter-spacing:.0075em;-webkit-font-smoothing:antialiased}.sidebar h1 a:hover{background:#ebf7fc}.sidebar h1 a:hover svg{color:#fff!important}.sidebar ul{margin:3.667em auto 2em;padding:0}.sidebar ul li a{display:block;padding:0 15% .25em;color:#666;line-height:1.4;text-transform:capitalize;font-size:1.5em;font-family:klinic-bold,klinic bold,Helvetica Neue,Helvetica,Arial,sans-serif;font-weight:600;-webkit-font-smoothing:antialiased;letter-spacing:.02em;transition:all .3s ease}.sidebar ul li a:hover{color:#277a9f;background:#b8dff4}.sidebar ul li a.active,.sidebar ul li a[state=open]{color:#277a9f;background:0 0}.sidebar ul li a.active .ripple span,.sidebar ul li a[state=open] .ripple span{width:100%;opacity:1;background:#4aade3}.sidebar ul li a.active:hover .ripple span,.sidebar ul li a[state=open]:hover .ripple span{background:#2090cd}.sidebar ul li a.active+ul,.sidebar ul li a[state=open]+ul{display:block}.sidebar ul li:last-child a.sidebar-nav-item:after{content:"\f08e";font-family:FontAwesome;display:inline-block;padding-left:.5em;width:1em;height:1em;color:#2dafe9;font-size:15px;opacity:.5}.sidebar ul li.toctree-l1.current ul{display:block!important}.sidebar ul li ul{margin:0;padding:.5em 0 1.25em;display:none}.sidebar ul li ul li{margin:0}.sidebar ul li ul li a{padding:.25em 0 .25em 17.5%;line-height:1;font-size:14px;border-right:4px solid transparent;color:#2dafe9;transition:all .3s ease-in-out;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-weight:700}.sidebar ul li ul li a:hover{color:#277a9f;background:#b8dff4}.sidebar ul li ul li.active a{color:#277a9f;border-right:4px solid #277a9f;background:#e6f3f9}.sidebar .sidebar-buttons{border-top:2px solid #ebf7fc;background:#d4ebf5}.sidebar .sidebar-buttons .button-wrap{width:300px;padding:.5em 10%}.sidebar .sidebar-buttons .button.expand.small{margin:.333em 0;display:block;padding-top:.5rem;padding-bottom:.575rem;background-color:#ebf7fc;color:#2090cd}.sidebar .sidebar-buttons .button.expand.small i{margin:-.05em .5em 0 -.667em;color:#2090cd;font-size:14px}.left-off-canvas-toggle .fa:before{color:#2090cd}.top-bar{perspective:800px;z-index:800;min-height:5.125em;transform-style:preserve-3d;background:#fff;border-bottom:1px solid #cfedfa}.top-bar .right{min-width:33.333%;margin-right:0;margin-top:1.75em;padding-right:3.5%}.top-bar .right li{display:inline-block}.top-bar .right li a{padding:1em}.top-bar .right li a i{padding-right:.333em}.top-bar .breadcrumb{position:absolute;top:0;left:1em;z-index:1030;line-height:1.5;font-size:14px;letter-spacing:.05em}.styleguide-footer li,.styleguide-footer p,.top-bar .breadcrumb a{font-family:klinic-reg,klinic,Helvetica Neue,Helvetica,Arial,sans-serif;letter-spacing:.0075em;-webkit-font-smoothing:antialiased;font-weight:400}.top-bar .breadcrumb a{padding:.333em 0;margin:.575em 0 .575em .5em;float:left;text-transform:capitalize;font-size:1.5rem;color:#2090cd;transition:all .3s ease-in-out}.top-bar .breadcrumb a:hover{color:#2dafe9}.top-bar .breadcrumb a:before{content:"/";display:inline-block;width:.75em;height:2em;margin:0 0 0 -.2em;color:#ccc}.top-bar .breadcrumb a:first-child:before{display:none}.left-off-canvas-toggle{z-index:1100;position:fixed;top:0;left:0}.left-off-canvas-toggle .fa{background-color:#fff;padding:1.425em .925em;color:#333}.headroom{transition:transform .2s linear;position:fixed;left:300px;right:0;top:0;z-index:1000}.headroom.headroom--pinned{transform:translateY(0);box-shadow:0 1px 3px hsla(0,0%,47%,.1)}.headroom.headroom--unpinned{transform:translateY(-100%)}.main{margin-bottom:-5em}.main.footer-expanded{margin-bottom:-11em}.styleguide-footer{min-height:5rem;overflow:hidden;position:relative;z-index:500;padding-top:1.25em;background-color:#333;border-bottom:6px solid #333;min-width:100%;transition:all .3s ease-in-out}.styleguide-footer ul{list-style:none;float:left;margin-bottom:0}.styleguide-footer ul li{display:block;margin:0}.styleguide-footer ul li a{font-weight:400}.styleguide-footer li,.styleguide-footer p{color:#999;line-height:1.7;font-size:.667rem}.styleguide-footer li a{font-size:.75rem}.styleguide-footer strong{text-transform:uppercase;letter-spacing:.25em;margin:.75rem 0 .25rem;display:block;font-weight:400}.home #helm .billboard h1,.home h3{font-family:klinic-bold,klinic bold,Helvetica Neue,Helvetica,Arial,sans-serif;letter-spacing:.05em}.styleguide-footer strong a{color:#999;cursor:pointer}.styleguide-footer a{color:#2dafe9}.styleguide-footer a:hover{border:none;text-decoration:none;color:#fff}.styleguide-footer .fa.footer-reveal{font-size:1rem;cursor:pointer;width:2em;height:2em;text-align:center;position:absolute;left:-.65em;top:.35rem;border-radius:50%;transition:all .3s ease-in-out}.styleguide-footer .fa.footer-reveal:hover{background:#262626;color:#999}.styleguide-footer p{margin-top:.75rem;color:#333}.styleguide-footer p:nth-child(2){margin-top:2.67rem;font-size:.75rem;line-height:1.5}.styleguide-footer p:nth-child(2) a{color:#2dafe9}.styleguide-footer img{margin:0;float:right;opacity:.7;transition:all .3s ease-in-out}.styleguide-footer img:hover{opacity:1}.styleguide-footer .sub-nav-social{position:absolute;right:1em;bottom:2em;text-align:right}.styleguide-footer .sub-nav-social li{display:inline-block;margin:1rem .25em;text-align:right}.styleguide-footer .sub-nav-social li a{font-size:1.5em;color:#666;width:2em;height:2em;text-align:center;background:#262626;border-radius:50%;transition:all .3s ease-in-out}.styleguide-footer .sub-nav-social li a:hover{background:#277a9f;color:#fff}.styleguide-footer .footer-extra div{display:none;opacity:0;height:0;min-height:0;overflow:hidden;transition:all .3s ease-in-out}.styleguide-footer.footer-expanded{margin-top:-11rem;min-height:11rem}.styleguide-footer.footer-expanded .footer-extra div{display:block;opacity:1;min-height:8em}.styleguide-footer.footer-expanded a.fa.footer-reveal{transform:rotate(180deg)}#contrib{padding-top:2.5rem;padding-bottom:2.5rem}.contrib-text p{color:#999;font-size:1rem;margin:0 auto;padding-left:2rem}.contrib-text p.lead{font-size:1.2rem;margin:3rem auto;position:relative;line-height:4}.contrib-text p.lead:after{content:" ";display:block;width:14%;position:absolute;bottom:0;left:43%;height:5px;background:#ccc;opacity:.25}.contrib-text p img{max-height:24px;margin:-2px 0 0 22px}.contrib-text p a{font-weight:700}.home #helm .billboard h1,.home .home-featured .panel h3,.home h3{font-weight:600;-webkit-font-smoothing:antialiased}.home,.home .home-intro-wrap{box-sizing:border-box;height:100%}.home h3{color:#f6fbfe;font-size:1.125rem}.home #helm{max-width:100%;position:relative;z-index:500}.home #helm:after{z-index:-100;display:block;height:850px;width:100%;bottom:0;position:fixed}.home #helm .billboard{background:url(../img/pattern-topo.png) 0 0;background-size:376px;padding-top:230px;position:relative;text-align:center}.home #helm .billboard h1{color:#2dafe9;font-size:2.57rem;text-transform:none}.home #helm .billboard h2{font-family:Helvetica Neue,Helvetica,Arial,sans-serif;color:#277a9f;font-size:1rem;margin-bottom:30px}.home #helm .billboard .helm-logo{position:absolute;left:5rem;top:2rem;max-width:102px}.home #helm .billboard .fa{position:absolute;font-size:2.5rem;top:4rem;right:5rem;color:#333}.home #helm .billboard .fa.fa-twitter{right:9rem;color:#2ba0d3;transition:all .3s ease-in-out}.home #helm .billboard .fa:hover{opacity:.7}.home #helm .billboard:after{background:url(../img/pattern-waves.png) 0 0 repeat-x;background-size:20px;bottom:0;content:"";display:block;height:6px;position:absolute;width:100%}.home #boat{height:2em}@media only screen and (min-device-width:415px){@keyframes b{0%{background-position:-150px 25%;bottom:-7px}10%,30%,50%,70%,90%{bottom:-12px}20%,40%,60%,80%{bottom:-7px}to{background-position:145% 0;bottom:-7px}}.home #boat{background:url(../img/boat.png) no-repeat;background-size:150px;height:120px;position:relative;margin-top:40px;animation:b 10s linear infinite;animation-duration:20s}}.home .home-featured{background-color:#2dafe9;padding-top:20px;padding-bottom:65px;min-height:400px}.home .home-featured .panels{width:92%;max-width:1140px;min-width:800px}.home .home-featured .panel{background-color:#fff;box-shadow:0 1px 4px #277a9f;border-radius:.25em;text-align:center;min-height:125px;color:#333}.home .home-featured .panel h3{padding:.75rem 0 .5rem;border-bottom:1px solid #ebf7fc;margin-bottom:1rem;font-size:1rem;color:#2090cd;font-family:klinic-bold,klinic bold,Helvetica Neue,Helvetica,Arial,sans-serif;letter-spacing:.02em}.home .home-featured .panel p{line-height:1.4;display:block;font-size:.925rem;padding:0 3.5% 1rem}.main .content-wrap{padding-top:1em;padding-bottom:10em;font-size:17.92px;line-height:1.5;z-index:500;position:relative;font-family:klinic-reg,klinic,Helvetica Neue,Helvetica,Arial,sans-serif;font-weight:400;letter-spacing:.0075em;-webkit-font-smoothing:antialiased}.main .content-wrap h2,.main .content-wrap h3{font-family:klinic-bold,klinic bold,Helvetica Neue,Helvetica,Arial,sans-serif;font-weight:600;-webkit-font-smoothing:antialiased}.main .content-wrap h1{text-transform:none;letter-spacing:.03em;margin-top:1em;padding-top:1.5em}.main .content-wrap article{padding:1em 0 0}.main .content-wrap article h1{font-size:32px;color:#2090cd;margin:1em 0;padding-top:3.5em}.main .content-wrap h2{color:#595959;font-size:24px;text-transform:uppercase;letter-spacing:.25em;letter-spacing:.125em;margin:0 0 .875em;padding-top:3.5em}.main .content-wrap h3{color:#333;letter-spacing:.05em;margin:1.25em 0 1.825em}.main .content-wrap h4{font-size:17.92px}.main .content-wrap p{color:#333;line-height:1.725;margin:.825rem 0 1.667rem;font-size:17.92px}.main .content-wrap p:first-child{font-size:20px;color:#333;line-height:1.636;margin-bottom:1.925rem;padding-right:7.5%}.main .content-wrap p a{padding-left:.25em;padding-right:.25em}.main .content-wrap.markdown pre,.main .content-wrap pre{background-color:#e4f3f9;color:#000;border:none;padding:.75em 1em;margin:.25em 0 2.5em;font-size:1rem}.main .content-wrap.markdown pre code,.main .content-wrap pre code{padding:0;background-color:#e4f3f9;font-size:1rem}.main .content-wrap .code-box{margin:0;width:100%;height:220px;border-bottom:3px solid #ccc;overflow:scroll}.main .content-wrap strong{letter-spacing:.0125em}.main .content-wrap code{color:#000;padding:.5em;background-color:#e4f3f9;border:none;font-size:1rem}.main .content-wrap.markdown ol,.main .content-wrap.markdown ul,.main .content-wrap ol,.main .content-wrap ul{padding:0 .25rem;margin-bottom:2em;color:#333;font-size:15px;line-height:1.7}.main .content-wrap.markdown ol li,.main .content-wrap.markdown ul li,.main .content-wrap ol li,.main .content-wrap ul li{font-size:1.125em}.main .content-wrap table{margin:1.5rem 0;border:none;width:100%}.main .content-wrap table td,.main .content-wrap table th{border:none;vertical-align:top;text-align:left;padding:.425em .75em .425em .2em;width:auto}.main .content-wrap table td{color:#333;font-size:15px}.main .content-wrap a{color:#1b79ac;background-color:#f6fbfe;transition:all .3s ease-in-out}.main .content-wrap a:hover{color:#2790be;border-bottom:2px solid #2dafe9;background:#fff}.main .content-wrap .header-link{position:absolute;left:-.4em;opacity:0;font-size:1rem;padding-top:.333em;transition:all .3s ease-in-out}.main .content-wrap .header-link:hover{border-bottom:none;background-color:transparent}.main .content-wrap h2:hover,.main .content-wrap h3:hover,.main .content-wrap h4:hover,.main .content-wrap h5:hover,.main .content-wrap h6:hover{color:#277a9f}.main .content-wrap h2:hover .header-link,.main .content-wrap h3:hover .header-link,.main .content-wrap h4:hover .header-link,.main .content-wrap h5:hover .header-link,.main .content-wrap h6:hover .header-link{opacity:1;left:-.825em}.main .content-wrap img{box-shadow:0 0 3px #ccc;padding:.5em;background-color:#fff;max-width:100%;margin-bottom:.75em}.main .content-wrap img:hover{box-shadow:0 0 4px #999}.main .content-wrap .youtube-player,.main .content-wrap embed,.main .content-wrap iframe{min-height:320px}@media only screen and (max-width:64.063em){aside.left-off-canvas-menu ul,aside.left-off-canvas-menu ul li a:hover{background:#2ba0d3!important}.home .fa,.sidebar{display:none}.container-full{padding-left:0}.left-off-canvas-toggle .fa{padding:1em 1.25em;line-height:3}.headroom{left:0}.st-default-autocomplete{width:90%!important;min-width:320px!important;left:5%!important}.home{min-height:500px}.home #helm .billboard{padding-top:180px}.home #helm .billboard .container{margin-left:5%;margin-right:5%}.home #helm .billboard h1{font-size:2rem}.main .content-wrap article h1,.main .content-wrap h1{font-size:32px}.home #helm .billboard .helm-logo{max-width:60%!important;left:20%!important}.main .content-wrap article{padding:0 0 .5em}.main .content-wrap article h2{font-size:20px}.main .content-wrap article p:first-child{padding-right:0;font-size:17.92px}aside.left-off-canvas-menu ul li{font-family:klinic-bold,klinic bold,Helvetica Neue,Helvetica,Arial,sans-serif;font-weight:600;letter-spacing:.05em;-webkit-font-smoothing:antialiased;font-size:1.25rem}aside.left-off-canvas-menu ul li a{color:#fff!important;border-bottom:none!important}aside.left-off-canvas-menu ul li a.active{color:#fff!important;background:#277a9f!important}aside.left-off-canvas-menu ul li a+ul{display:none;background:#277a9f!important;margin-left:0;padding:.5em 0 1em 1.5em}aside.left-off-canvas-menu ul li a+ul li{font-family:Helvetica Neue,Helvetica,Arial,sans-serif;letter-spacing:0;font-size:1rem;list-style:none}aside.left-off-canvas-menu ul li a+ul li a{padding:.1em .66667rem;border-bottom:none;color:#ebf7fc!important}aside.left-off-canvas-menu ul li a.active+ul{display:block}aside.left-off-canvas-menu .button-wrap{padding:.75em 5%}aside.left-off-canvas-menu .button-wrap .button{margin:.4em 0}.top-bar .breadcrumb{left:2.75rem}.top-bar .right li{display:none}.top-bar .right li:nth-child(2){display:inline-block}.top-bar .right li:nth-child(2) a{position:absolute;right:-4em;top:-.35em;font-size:1.75rem}}@media screen and (min-height:575px){.sidebar{padding-bottom:0}.sidebar .sidebar-nav{padding-bottom:180px}.sidebar .sidebar-buttons{position:fixed;bottom:0}}.section-404{position:relative;min-height:670px}.section-404 #particles-js{position:absolute;width:100%}.section-404 h1{text-transform:none;font-size:32px;letter-spacing:.05em;margin:5em 7.5% 2.5em;position:relative} -/*# sourceMappingURL=styles.min.css.map */ diff --git a/docs.helm.sh/rootfs/public/src/css/styles.min.css.map b/docs.helm.sh/rootfs/public/src/css/styles.min.css.map deleted file mode 100644 index 9120aba775..0000000000 --- a/docs.helm.sh/rootfs/public/src/css/styles.min.css.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["styles.min.css"],"names":[],"mappings":"AAAA,4EAA4E,2BAA2B,iCAAiC,CAAC,+FAA+F,UAAU,CAAC,mBAAmB,WAAW,CAAC,yCAAyC,eAAe,CAAC,oBAAoB,iCAAiC,CAAC,8BAA8B,oBAAoB,CAAC,KAAK,uBAAuB,0BAA0B,6BAA6B,CAAC,2FAA2F,aAAa,CAAC,4BAA4B,qBAAqB,uBAAuB,CAAC,sBAAsB,aAAa,QAAQ,CAAC,kBAAkB,YAAY,CAAC,EAAE,4BAA4B,CAAC,iBAAiB,SAAS,CAAC,kBAAkB,eAAe,CAAC,IAAI,iBAAiB,CAAC,KAAK,gBAAgB,UAAU,CAAC,QAAQ,cAAc,cAAc,kBAAkB,uBAAuB,CAAC,IAAI,SAAS,CAAC,IAAI,aAAa,CAAC,IAAI,SAAS,eAAe,8BAA8B,CAAC,eAAe,eAAe,CAAC,OAAO,eAAe,CAAC,aAAa,aAAa,CAAC,kBAAkB,gCAAgC,aAAa,CAAC,sCAAsC,cAAc,aAAa,QAAQ,CAAC,4BAA4B,kBAAkB,CAAC,OAAO,gBAAgB,CAAC,cAAc,mBAAmB,CAAC,oEAAoE,0BAA0B,cAAc,CAAC,sCAAsC,cAAc,CAAC,iDAAiD,SAAS,SAAS,CAAC,uCAAuC,sBAAsB,SAAS,CAAC,4FAA4F,WAAW,CAAC,+FAA+F,uBAAuB,CAAC,OAAO,SAAS,SAAS,CAAC,MAAM,yBAAyB,gBAAgB,CAAC,wBAAwB,oBAAqB,CAAC,yBAAyB,4BAA4B,OAAO,CAAC,8BAA8B,kDAAkD,OAAO,CAAC,0BAA0B,sDAAsD,eAAe,CAAC,+BAA+B,2EAA2E,eAAe,CAAC,yBAAyB,sDAAsD,eAAe,CAAC,8BAA8B,2EAA2E,eAAe,CAAC,0BAA0B,sDAAsD,eAAe,CAAC,+BAA+B,4EAA4E,eAAe,CAAC,2BAA2B,uDAAuD,gBAAgB,CAAC,YAAY,UAAU,CAAC,yCAAyC,iBAAiB,CAAC,oBAAoB,6DAA+D,gBAAgB,iBAAiB,CAAC,iBAAiB,qBAAqB,CAAC,UAAU,cAAc,CAAC,KAAK,WAAW,YAAY,kBAAkB,eAAe,CAAC,uBAAuB,cAAc,CAAC,kKAAkK,wBAAwB,CAAC,MAAM,oBAAoB,CAAC,OAAO,qBAAqB,CAAC,iCAAiC,YAAY,aAAa,CAAC,MAAM,YAAY,CAAC,kKAAkK,YAAY,aAAa,CAAC,WAAW,iBAAiB,CAAC,aAAa,kCAAkC,CAAC,IAAI,qBAAqB,qBAAqB,CAAC,KAAK,cAAc,iBAAiB,CAAC,6CAA6C,eAAe,eAAe,CAAC,mBAAmB,cAAc,cAAc,CAAC,UAAU,mBAAmB,eAAe,UAAU,CAAC,mBAAmB,SAAS,eAAe,UAAU,CAAC,iBAAiB,sBAAsB,uBAAuB,WAAW,UAAU,CAAC,gHAAgH,WAAW,CAAC,oFAAoF,UAAU,CAAC,mBAAmB,uVAAuV,iBAAiB,CAAC,cAAc,OAAO,UAAU,CAAC,cAAc,QAAQ,SAAS,CAAC,cAAc,cAAc,UAAU,CAAC,cAAc,eAAe,SAAS,CAAC,cAAc,eAAe,UAAU,CAAC,cAAc,gBAAgB,SAAS,CAAC,cAAc,SAAS,UAAU,CAAC,cAAc,UAAU,SAAS,CAAC,cAAc,eAAe,UAAU,CAAC,cAAc,gBAAgB,SAAS,CAAC,cAAc,eAAe,UAAU,CAAC,cAAc,gBAAgB,SAAS,CAAC,cAAc,kBAAkB,SAAS,UAAU,CAAC,cAAc,UAAU,SAAS,CAAC,cAAc,eAAe,UAAU,CAAC,cAAc,gBAAgB,SAAS,CAAC,cAAc,eAAe,UAAU,CAAC,cAAc,gBAAgB,SAAS,CAAC,cAAc,SAAS,UAAU,CAAC,cAAc,UAAU,SAAS,CAAC,eAAe,eAAe,UAAU,CAAC,eAAe,gBAAgB,SAAS,CAAC,eAAe,eAAe,UAAU,CAAC,eAAe,gBAAgB,SAAS,CAAC,iBAAiB,sBAAsB,uBAAuB,UAAU,CAAC,SAAS,cAAc,CAAC,SAAS,eAAe,CAAC,SAAS,SAAS,CAAC,SAAS,eAAe,CAAC,SAAS,eAAe,CAAC,SAAS,SAAS,CAAC,SAAS,eAAe,CAAC,SAAS,eAAe,CAAC,SAAS,SAAS,CAAC,UAAU,eAAe,CAAC,UAAU,eAAe,CAAC,UAAU,UAAU,CAAC,gBAAgB,uBAAuB,CAAC,gBAAgB,8BAA8B,CAAC,gBAAgB,+BAA+B,CAAC,gBAAgB,yBAAyB,CAAC,gBAAgB,+BAA+B,CAAC,gBAAgB,+BAA+B,CAAC,gBAAgB,yBAAyB,CAAC,gBAAgB,+BAA+B,CAAC,gBAAgB,+BAA+B,CAAC,gBAAgB,yBAAyB,CAAC,iBAAiB,+BAA+B,CAAC,iBAAiB,+BAA+B,CAAC,mBAAmB,WAAW,UAAU,cAAc,eAAe,UAAU,CAAC,+CAA+C,iBAAiB,kBAAkB,UAAU,CAAC,mDAAmD,WAAW,cAAc,cAAc,CAAC,qEAAqE,UAAU,CAAC,yEAAyE,UAAU,CAAC,qEAAqE,WAAW,CAAC,yDAAyD,eAAe,eAAe,CAAC,yBAAyB,cAAc,cAAc,CAAC,6DAA6D,sBAAsB,uBAAuB,UAAU,CAAC,CAAC,6CAA6C,gjBAAgjB,iBAAiB,CAAC,eAAe,OAAO,UAAU,CAAC,eAAe,QAAQ,SAAS,CAAC,eAAe,cAAc,UAAU,CAAC,eAAe,eAAe,SAAS,CAAC,eAAe,eAAe,UAAU,CAAC,eAAe,gBAAgB,SAAS,CAAC,eAAe,SAAS,UAAU,CAAC,eAAe,UAAU,SAAS,CAAC,eAAe,eAAe,UAAU,CAAC,eAAe,gBAAgB,SAAS,CAAC,eAAe,eAAe,UAAU,CAAC,eAAe,gBAAgB,SAAS,CAAC,eAAe,SAAS,UAAU,CAAC,eAAe,UAAU,SAAS,CAAC,eAAe,eAAe,UAAU,CAAC,eAAe,gBAAgB,SAAS,CAAC,eAAe,eAAe,UAAU,CAAC,eAAe,gBAAgB,SAAS,CAAC,eAAe,SAAS,UAAU,CAAC,eAAe,UAAU,SAAS,CAAC,gBAAgB,eAAe,UAAU,CAAC,gBAAgB,gBAAgB,SAAS,CAAC,gBAAgB,eAAe,UAAU,CAAC,gBAAgB,gBAAgB,SAAS,CAAC,iBAAiB,kBAAkB,sBAAsB,uBAAuB,UAAU,CAAC,UAAU,cAAc,CAAC,UAAU,eAAe,CAAC,UAAU,SAAS,CAAC,UAAU,eAAe,CAAC,UAAU,eAAe,CAAC,UAAU,SAAS,CAAC,UAAU,eAAe,CAAC,UAAU,eAAe,CAAC,UAAU,SAAS,CAAC,WAAW,eAAe,CAAC,WAAW,eAAe,CAAC,WAAW,UAAU,CAAC,iBAAiB,uBAAuB,CAAC,iBAAiB,8BAA8B,CAAC,iBAAiB,+BAA+B,CAAC,iBAAiB,yBAAyB,CAAC,iBAAiB,+BAA+B,CAAC,iBAAiB,+BAA+B,CAAC,iBAAiB,yBAAyB,CAAC,iBAAiB,+BAA+B,CAAC,iBAAiB,+BAA+B,CAAC,iBAAiB,yBAAyB,CAAC,kBAAkB,+BAA+B,CAAC,kBAAkB,+BAA+B,CAAC,oBAAoB,WAAW,UAAU,cAAc,eAAe,UAAU,CAAC,iDAAiD,iBAAiB,kBAAkB,UAAU,CAAC,qDAAqD,WAAW,cAAc,cAAc,CAAC,uEAAuE,UAAU,CAAC,2EAA2E,UAAU,CAAC,uEAAuE,WAAW,CAAC,2DAA2D,eAAe,eAAe,CAAC,0BAA0B,cAAc,cAAc,CAAC,+DAA+D,sBAAsB,uBAAuB,UAAU,CAAC,QAAQ,OAAO,UAAU,CAAC,QAAQ,QAAQ,SAAS,CAAC,QAAQ,cAAc,UAAU,CAAC,QAAQ,eAAe,SAAS,CAAC,QAAQ,eAAe,UAAU,CAAC,QAAQ,gBAAgB,SAAS,CAAC,QAAQ,SAAS,UAAU,CAAC,QAAQ,UAAU,SAAS,CAAC,QAAQ,eAAe,UAAU,CAAC,QAAQ,gBAAgB,SAAS,CAAC,QAAQ,eAAe,UAAU,CAAC,QAAQ,gBAAgB,SAAS,CAAC,QAAQ,SAAS,UAAU,CAAC,QAAQ,UAAU,SAAS,CAAC,QAAQ,eAAe,UAAU,CAAC,QAAQ,gBAAgB,SAAS,CAAC,QAAQ,eAAe,UAAU,CAAC,QAAQ,gBAAgB,SAAS,CAAC,QAAQ,SAAS,UAAU,CAAC,QAAQ,UAAU,SAAS,CAAC,SAAS,eAAe,UAAU,CAAC,SAAS,gBAAgB,SAAS,CAAC,SAAS,eAAe,UAAU,CAAC,SAAS,gBAAgB,SAAS,CAAC,CAAC,6CAA6C,whBAAwhB,iBAAiB,CAAC,cAAc,OAAO,UAAU,CAAC,cAAc,QAAQ,SAAS,CAAC,cAAc,cAAc,UAAU,CAAC,cAAc,eAAe,SAAS,CAAC,cAAc,eAAe,UAAU,CAAC,cAAc,gBAAgB,SAAS,CAAC,cAAc,SAAS,UAAU,CAAC,cAAc,UAAU,SAAS,CAAC,cAAc,eAAe,UAAU,CAAC,cAAc,gBAAgB,SAAS,CAAC,cAAc,eAAe,UAAU,CAAC,cAAc,gBAAgB,SAAS,CAAC,cAAc,SAAS,UAAU,CAAC,cAAc,UAAU,SAAS,CAAC,cAAc,eAAe,UAAU,CAAC,cAAc,gBAAgB,SAAS,CAAC,cAAc,eAAe,UAAU,CAAC,cAAc,gBAAgB,SAAS,CAAC,cAAc,SAAS,UAAU,CAAC,cAAc,UAAU,SAAS,CAAC,eAAe,eAAe,UAAU,CAAC,eAAe,gBAAgB,SAAS,CAAC,eAAe,eAAe,UAAU,CAAC,eAAe,gBAAgB,SAAS,CAAC,iBAAiB,kBAAkB,sBAAsB,uBAAuB,UAAU,CAAC,SAAS,cAAc,CAAC,SAAS,eAAe,CAAC,SAAS,SAAS,CAAC,SAAS,eAAe,CAAC,SAAS,eAAe,CAAC,SAAS,SAAS,CAAC,SAAS,eAAe,CAAC,SAAS,eAAe,CAAC,SAAS,SAAS,CAAC,UAAU,eAAe,CAAC,UAAU,eAAe,CAAC,UAAU,UAAU,CAAC,gBAAgB,uBAAuB,CAAC,gBAAgB,8BAA8B,CAAC,gBAAgB,+BAA+B,CAAC,gBAAgB,yBAAyB,CAAC,gBAAgB,+BAA+B,CAAC,gBAAgB,+BAA+B,CAAC,gBAAgB,yBAAyB,CAAC,gBAAgB,+BAA+B,CAAC,gBAAgB,+BAA+B,CAAC,gBAAgB,yBAAyB,CAAC,iBAAiB,+BAA+B,CAAC,iBAAiB,+BAA+B,CAAC,mBAAmB,WAAW,UAAU,cAAc,eAAe,UAAU,CAAC,+CAA+C,iBAAiB,kBAAkB,UAAU,CAAC,mDAAmD,WAAW,cAAc,cAAc,CAAC,qEAAqE,UAAU,CAAC,yEAAyE,UAAU,CAAC,qEAAqE,WAAW,CAAC,yDAAyD,eAAe,eAAe,CAAC,yBAAyB,cAAc,cAAc,CAAC,6DAA6D,sBAAsB,uBAAuB,UAAU,CAAC,QAAQ,OAAO,UAAU,CAAC,QAAQ,QAAQ,SAAS,CAAC,QAAQ,cAAc,UAAU,CAAC,QAAQ,eAAe,SAAS,CAAC,QAAQ,eAAe,UAAU,CAAC,QAAQ,gBAAgB,SAAS,CAAC,QAAQ,SAAS,UAAU,CAAC,QAAQ,UAAU,SAAS,CAAC,QAAQ,eAAe,UAAU,CAAC,QAAQ,gBAAgB,SAAS,CAAC,QAAQ,eAAe,UAAU,CAAC,QAAQ,gBAAgB,SAAS,CAAC,QAAQ,SAAS,UAAU,CAAC,QAAQ,UAAU,SAAS,CAAC,QAAQ,eAAe,UAAU,CAAC,QAAQ,gBAAgB,SAAS,CAAC,QAAQ,eAAe,UAAU,CAAC,QAAQ,gBAAgB,SAAS,CAAC,QAAQ,SAAS,UAAU,CAAC,QAAQ,UAAU,SAAS,CAAC,SAAS,eAAe,UAAU,CAAC,SAAS,gBAAgB,SAAS,CAAC,SAAS,eAAe,UAAU,CAAC,SAAS,gBAAgB,SAAS,CAAC,CAAC,qBAAqB,cAAc,UAAU,iBAAiB,CAAC,wBAAwB,cAAc,WAAW,YAAY,yBAAyB,CAAC,mBAAmB,uBAAuB,gBAAgB,UAAU,CAAC,uCAAuC,UAAU,CAAC,yCAAyC,UAAU,CAAC,uBAAuB,gBAAgB,SAAS,CAAC,uCAAuC,UAAU,CAAC,wCAAyC,UAAU,CAAC,uBAAuB,gBAAgB,eAAe,CAAC,uCAAuC,UAAU,CAAC,yCAAyC,UAAU,CAAC,uBAAuB,gBAAgB,SAAS,CAAC,uCAAuC,UAAU,CAAC,yCAAyC,UAAU,CAAC,uBAAuB,gBAAgB,SAAS,CAAC,uCAAuC,UAAU,CAAC,yCAAyC,UAAU,CAAC,uBAAuB,gBAAgB,eAAe,CAAC,uCAAuC,UAAU,CAAC,yCAAyC,UAAU,CAAC,uBAAuB,gBAAgB,eAAe,CAAC,uCAAuC,UAAU,CAAC,yCAAyC,UAAU,CAAC,uBAAuB,gBAAgB,WAAW,CAAC,uCAAuC,UAAU,CAAC,yCAAyC,UAAU,CAAC,uBAAuB,gBAAgB,eAAe,CAAC,uCAAuC,UAAU,CAAC,yCAAyC,UAAU,CAAC,wBAAwB,gBAAgB,SAAS,CAAC,wCAAwC,UAAU,CAAC,2CAA2C,UAAU,CAAC,wBAAwB,gBAAgB,cAAc,CAAC,wCAAwC,UAAU,CAAC,2CAA2C,UAAU,CAAC,wBAAwB,gBAAgB,cAAc,CAAC,wCAAwC,UAAU,CAAC,2CAA2C,UAAU,CAAC,CAAC,6CAA6C,wBAAwB,gBAAgB,UAAU,CAAC,wCAAwC,UAAU,CAAC,0CAA0C,UAAU,CAAC,wBAAwB,gBAAgB,SAAS,CAAC,wCAAwC,UAAU,CAAC,yCAA0C,UAAU,CAAC,wBAAwB,gBAAgB,eAAe,CAAC,wCAAwC,UAAU,CAAC,0CAA0C,UAAU,CAAC,wBAAwB,gBAAgB,SAAS,CAAC,wCAAwC,UAAU,CAAC,0CAA0C,UAAU,CAAC,wBAAwB,gBAAgB,SAAS,CAAC,wCAAwC,UAAU,CAAC,0CAA0C,UAAU,CAAC,wBAAwB,gBAAgB,eAAe,CAAC,wCAAwC,UAAU,CAAC,0CAA0C,UAAU,CAAC,wBAAwB,gBAAgB,eAAe,CAAC,wCAAwC,UAAU,CAAC,0CAA0C,UAAU,CAAC,wBAAwB,gBAAgB,WAAW,CAAC,wCAAwC,UAAU,CAAC,0CAA0C,UAAU,CAAC,wBAAwB,gBAAgB,eAAe,CAAC,wCAAwC,UAAU,CAAC,0CAA0C,UAAU,CAAC,yBAAyB,gBAAgB,SAAS,CAAC,yCAAyC,UAAU,CAAC,4CAA4C,UAAU,CAAC,yBAAyB,gBAAgB,cAAc,CAAC,yCAAyC,UAAU,CAAC,4CAA4C,UAAU,CAAC,yBAAyB,gBAAgB,cAAc,CAAC,yCAAyC,UAAU,CAAC,4CAA4C,UAAU,CAAC,eAAe,oBAAoB,CAAC,CAAC,6CAA6C,uBAAuB,gBAAgB,UAAU,CAAC,uCAAuC,UAAU,CAAC,yCAAyC,UAAU,CAAC,uBAAuB,gBAAgB,SAAS,CAAC,uCAAuC,UAAU,CAAC,wCAAyC,UAAU,CAAC,uBAAuB,gBAAgB,eAAe,CAAC,uCAAuC,UAAU,CAAC,yCAAyC,UAAU,CAAC,uBAAuB,gBAAgB,SAAS,CAAC,uCAAuC,UAAU,CAAC,yCAAyC,UAAU,CAAC,uBAAuB,gBAAgB,SAAS,CAAC,uCAAuC,UAAU,CAAC,yCAAyC,UAAU,CAAC,uBAAuB,gBAAgB,eAAe,CAAC,uCAAuC,UAAU,CAAC,yCAAyC,UAAU,CAAC,uBAAuB,gBAAgB,eAAe,CAAC,uCAAuC,UAAU,CAAC,yCAAyC,UAAU,CAAC,uBAAuB,gBAAgB,WAAW,CAAC,uCAAuC,UAAU,CAAC,yCAAyC,UAAU,CAAC,uBAAuB,gBAAgB,eAAe,CAAC,uCAAuC,UAAU,CAAC,yCAAyC,UAAU,CAAC,wBAAwB,gBAAgB,SAAS,CAAC,wCAAwC,UAAU,CAAC,2CAA2C,UAAU,CAAC,wBAAwB,gBAAgB,cAAc,CAAC,wCAAwC,UAAU,CAAC,2CAA2C,UAAU,CAAC,wBAAwB,gBAAgB,cAAc,CAAC,wCAAwC,UAAU,CAAC,2CAA2C,UAAU,CAAC,CAAC,eAAe,wBAAwB,qBAAqB,gBAAgB,AAAkC,mBAAmB,kBAAkB,qBAAqB,4BAA4B,eAAe,yBAAyB,uBAAqB,WAAW,wCAAwC,CAAC,sDAAsD,yBAAyB,UAAU,CAAC,mCAAmC,yBAAyB,qBAAqB,UAAU,CAAC,8FAA8F,yBAAyB,UAAU,CAAC,+BAA+B,yBAAyB,qBAAqB,UAAU,CAAC,sFAAsF,yBAAyB,UAAU,CAAC,2BAA2B,yBAAyB,qBAAqB,UAAU,CAAC,8EAA8E,yBAAyB,UAAU,CAAC,+BAA+B,yBAAyB,qBAAqB,UAAU,CAAC,sFAAsF,yBAAyB,UAAU,CAAC,yBAAyB,yBAAyB,qBAAqB,UAAU,CAAC,0EAA0E,yBAAyB,UAAU,CAAC,2BAA2B,mCAAmC,iBAAiB,CAAC,2BAA2B,iCAAiC,kBAAkB,CAAC,yBAAyB,iCAAiC,kBAAkB,CAAC,6BAA6B,4BAA4B,eAAe,UAAU,CAAC,aAAa,iBAAiB,CAAC,qCAAqC,gBAAgB,kBAAkB,CAAC,uCAAuC,iBAAiB,oBAAoB,CAAC,6BAA6B,iBAAiB,CAAC,2BAA2B,oBAAoB,CAAC,oEAAoE,yBAAyB,qBAAqB,WAAW,gBAAgB,eAAe,UAAU,CAAC,wLAAwL,WAAW,wBAAwB,CAAC,4GAA4G,yBAAyB,qBAAqB,WAAW,gBAAgB,eAAe,UAAU,CAAC,wQAAwQ,WAAW,wBAAwB,CAAC,oGAAoG,yBAAyB,qBAAqB,WAAW,gBAAgB,eAAe,UAAU,CAAC,wPAAwP,WAAW,wBAAwB,CAAC,4FAA4F,yBAAyB,qBAAqB,WAAW,gBAAgB,eAAe,UAAU,CAAC,wOAAwO,WAAW,wBAAwB,CAAC,oGAAoG,yBAAyB,qBAAqB,WAAW,gBAAgB,eAAe,UAAU,CAAC,wPAAwP,WAAW,wBAAwB,CAAC,wFAAwF,yBAAyB,qBAAqB,WAAW,gBAAgB,eAAe,UAAU,CAAC,gOAAgO,WAAW,wBAAwB,CAAC,yBAAyB,SAAS,SAAS,CAAC,yDAAyD,aAAa,CAAC,aAAa,gBAAgB,UAAU,8BAA8B,CAAC,gBAAgB,WAAW,oBAAoB,CAAC,eAAe,eAAe,CAAC,+CAA+C,eAAe,CAAC,wBAAwB,QAAQ,CAAC,iEAAiE,SAAS,CAAC,8BAA8B,qCAAqC,kCAAkC,6BAA6B,yBAAyB,CAAC,oGAAoG,kBAAkB,CAAC,MAAM,cAAc,eAAe,gBAAgB,gBAAgB,eAAe,CAAC,4EAA4E,eAAe,CAAC,YAAY,qBAAqB,gBAAgB,CAAC,aAAa,kBAAkB,CAAC,YAAY,0BAA0B,aAAa,CAAC,iBAAiB,mBAAmB,iBAAiB,iBAAiB,iBAAiB,cAAc,kBAAkB,kBAAkB,WAAW,SAAS,CAAC,+BAA+B,YAAY,kBAAkB,SAAS,CAAC,sBAAsB,0BAA0B,sCAAsC,kCAAkC,CAAC,uBAAuB,0BAA0B,uCAAuC,mCAAmC,CAAC,qBAAqB,gCAAgC,yCAAyC,qCAAqC,CAAC,sBAAsB,gCAAgC,0CAA0C,sCAAsC,CAAC,yBAAyB,mBAAmB,kBAAkB,WAAW,iBAAiB,CAAC,2BAA2B,mBAAmB,iBAAiB,WAAW,iBAAiB,CAAC,g5DAAg5D,sBAAsB,cAAc,CAAC,gSAAgS,wBAAwB,qBAAqB,gBAAgB,sBAAsB,AAAoC,sBAAkB,0CAA0C,sBAAsB,cAAc,oBAAoB,kBAAkB,iBAAiB,gBAAgB,cAAc,WAAW,sBAAsB,0DAA0D,CAAC,gYAAgY,mBAAmB,kBAAkB,SAAS,CAAC,gZAAgZ,iBAAiB,CAAC,qLAAqL,0BAA0B,uCAAuC,mCAAmC,CAAC,uOAAuO,0BAA0B,sCAAsC,kCAAkC,CAAC,gDAAgD,0BAA0B,uCAAuC,mCAAmC,CAAC,iLAAiL,gCAAgC,0CAA0C,sCAAsC,CAAC,kOAAkO,gCAAgC,yCAAyC,qCAAqC,CAAC,+CAA+C,gCAAgC,0CAA0C,sCAAsC,CAAC,mBAAmB,wBAAwB,qBAAqB,eAAe,CAAC,SAAS,gBAAgB,cAAc,CAAC,4BAA4B,UAAU,CAAC,AAA6B,qCAAmB,UAAU,CAAC,uBAAuB,UAAU,CAAC,OAAO,kCAAkC,+BAA+B,yBAAyB,qVAAqV,yBAAgC,4BAA4B,AAAoC,sBAAkB,sBAAsB,oBAAoB,cAAc,gBAAgB,gBAAgB,CAAC,mBAAmB,YAAY,CAAC,cAAc,iBAAiB,CAAC,aAAa,yBAAyB,iBAAiB,CAAC,iBAAiB,WAAW,CAAC,mDAAmD,qBAAqB,kBAAkB,kBAAkB,gBAAgB,uBAAuB,CAAC,iBAAiB,UAAU,CAAC,SAAS,sBAAsB,kBAAkB,eAAe,CAAC,gBAAgB,gBAAgB,uBAAuB,kBAAkB,CAAC,gHAAgH,cAAc,iBAAiB,kBAAkB,gBAAgB,mBAAmB,gBAAgB,kCAAkC,mBAAmB,UAAU,CAAC,iDAAiD,YAAY,CAAC,0CAA0C,cAAc,iBAAiB,gBAAgB,kCAAkC,mBAAmB,gBAAgB,iBAAiB,CAAC,uBAAuB,mBAAmB,UAAU,CAAC,2CAA2C,eAAe,CAAC,wEAAwE,kBAAkB,CAAC,gCAAgC,aAAa,CAAC,mBAAmB,UAAU,CAAC,sMAAsM,eAAe,CAAC,mBAAmB,eAAe,cAAc,eAAe,cAAc,kBAAkB,SAAS,UAAU,yBAAyB,CAAC,0BAA0B,aAAa,CAAC,YAAY,aAAa,CAAC,0BAA0B,sDAAsD,eAAe,CAAC,iBAAiB,WAAW,eAAe,CAAC,OAAO,eAAe,MAAM,WAAW,WAAW,MAAM,CAAC,8BAA8B,YAAY,gBAAgB,gBAAgB,UAAU,CAAC,0CAA0C,eAAe,WAAW,UAAU,CAAC,+CAA+C,qBAAqB,UAAU,CAAC,SAAS,iBAAiB,sBAAsB,gBAAgB,iBAAiB,CAAC,cAAc,cAAc,CAAC,+BAA+B,iBAAiB,eAAe,sBAAsB,kBAAkB,CAAC,iCAAiC,iBAAiB,wBAAwB,oBAAoB,CAAC,wCAAwC,iCAAiC,kBAAkB,QAAQ,CAAC,CAAC,qBAAqB,SAAS,iBAAiB,CAAC,eAAe,eAAe,iBAAiB,QAAQ,CAAC,6GAA6G,oBAAoB,sBAAsB,QAAQ,CAAC,yHAAyH,WAAW,cAAc,gBAAgB,mBAAmB,SAAS,CAAC,wBAAwB,kBAAkB,QAAQ,KAAK,CAAC,0BAA0B,WAAW,cAAc,mBAAmB,gBAAgB,iBAAiB,sBAAsB,mBAAmB,kBAAkB,wBAAwB,CAAC,kCAAkC,iBAAiB,OAAO,CAAC,oCAAoC,WAAW,YAAY,iBAAiB,4BAA4B,iBAAiB,CAAC,+CAAgD,WAAW,cAAc,SAAS,kBAAkB,gBAAgB,QAAQ,eAAe,6DAA6D,UAAU,CAAC,gDAAgD,iBAAiB,CAAC,qDAAqD,sDAAsD,CAAC,kBAAkB,eAAe,WAAW,CAAC,qDAAqD,eAAe,CAAC,mCAAmC,UAAU,CAAC,8CAA+C,4DAA4D,CAAC,qDAAqD,8GAA8G,SAAY,CAAC,gEAAgE,SAAS,CAAC,CAAC,iBAAiB,OAAO,WAAW,4BAA4B,CAAC,oBAAoB,cAAc,eAAe,YAAY,SAAS,UAAU,UAAU,CAAC,4DAA4D,6BAA6B,WAAW,WAAW,UAAU,CAAC,yBAAyB,WAAW,cAAc,6DAA+D,mBAAmB,gBAAgB,6BAA6B,oBAAoB,UAAU,CAAC,8DAA8D,mBAAmB,sBAAsB,sBAAsB,CAAC,gCAAgC,yBAAyB,qBAAqB,UAAU,CAAC,4EAA4E,yBAAyB,UAAU,CAAC,0CAA0C,yBAAyB,qBAAqB,UAAU,CAAC,gGAAgG,yBAAyB,UAAU,CAAC,wCAAwC,yBAAyB,qBAAqB,UAAU,CAAC,4FAA4F,yBAAyB,UAAU,CAAC,sCAAsC,yBAAyB,qBAAqB,UAAU,CAAC,wFAAwF,yBAAyB,UAAU,CAAC,wCAAwC,yBAAyB,qBAAqB,UAAU,CAAC,4FAA4F,yBAAyB,UAAU,CAAC,qCAAqC,yBAAyB,qBAAqB,UAAU,CAAC,sFAAsF,yBAAyB,UAAU,CAAC,8BAA8B,yBAAyB,qBAAqB,UAAU,CAAC,wEAAwE,yBAAyB,UAAU,CAAC,wCAAwC,yBAAyB,qBAAqB,UAAU,CAAC,4FAA4F,yBAAyB,UAAU,CAAC,sCAAsC,yBAAyB,qBAAqB,UAAU,CAAC,wFAAwF,yBAAyB,UAAU,CAAC,oCAAoC,yBAAyB,qBAAqB,UAAU,CAAC,oFAAoF,yBAAyB,UAAU,CAAC,sCAAsC,yBAAyB,qBAAqB,UAAU,CAAC,wFAAwF,yBAAyB,UAAU,CAAC,mCAAmC,yBAAyB,qBAAqB,UAAU,CAAC,kFAAkF,yBAAyB,UAAU,CAAC,8CAA8C,WAAW,eAAe,CAAC,gCAAgC,mBAAmB,UAAU,CAAC,sCAAsC,mBAAmB,UAAU,CAAC,2BAA2B,gBAAgB,CAAC,uCAAuC,iBAAiB,WAAW,cAAc,SAAS,QAAQ,oEAAsE,wBAAwB,sBAAsB,kBAAkB,kBAAkB,QAAQ,OAAO,CAAC,qCAAqC,eAAe,CAAC,+CAA+C,YAAY,iBAAiB,UAAU,cAAc,4BAA4B,UAAU,CAAC,6CAA6C,YAAY,CAAC,2BAA2B,2BAA2B,WAAW,gBAAgB,4BAA4B,UAAU,cAAc,UAAU,MAAM,WAAW,SAAS,CAAC,8BAA8B,YAAY,UAAU,CAAC,gCAAgC,gBAAgB,oBAAoB,CAAC,4CAA4C,eAAe,CAAC,iFAAiF,gBAAgB,aAAa,kBAAkB,CAAC,qFAAqF,WAAW,aAAa,CAAC,iGAAiG,cAAc,CAAC,uCAAuC,oBAAoB,CAAC,2EAA2E,QAAQ,CAAC,iCAAiC,WAAW,kBAAkB,gBAAgB,yBAAyB,wBAAwB,CAAC,kBAAkB,eAAe,CAAC,cAAc,aAAa,CAAC,6CAA6C,2BAA2B,eAAe,CAAC,4CAA4C,UAAU,CAAC,SAAS,gBAAgB,CAAC,+BAA+B,YAAY,aAAa,CAAC,eAAe,UAAU,CAAC,wBAAwB,YAAY,CAAC,wHAAwH,UAAU,CAAC,qHAAqH,kBAAkB,eAAe,kBAAkB,aAAa,CAAC,0BAA0B,cAAc,iBAAiB,CAAC,iBAAiB,oBAAoB,gBAAgB,CAAC,oBAAoB,eAAe,sBAAsB,UAAU,CAAC,qCAAqC,YAAY,CAAC,yCAAyC,gBAAgB,UAAU,CAAC,kDAAkD,gBAAgB,sBAAsB,kBAAkB,CAAC,wDAAwD,eAAe,CAAC,yDAAyD,mBAAmB,WAAW,sBAAsB,kBAAkB,CAAC,+DAA+D,mBAAmB,UAAU,CAAC,iCAAiC,iCAAiC,CAAC,uCAAuC,iBAAiB,WAAW,cAAc,SAAS,QAAQ,wDAA0D,uBAAuB,kBAAkB,cAAc,CAAC,qCAAqC,iBAAiB,CAAC,+CAA+C,2BAA2B,WAAW,gBAAgB,4BAA4B,UAAU,aAAa,CAAC,yJAAyJ,YAAY,WAAW,iBAAiB,UAAU,cAAc,2BAA2B,CAAC,iEAAiE,YAAY,gBAAgB,aAAa,SAAS,CAAC,2BAA2B,OAAO,eAAe,eAAe,QAAQ,CAAC,gCAAgC,gBAAgB,WAAW,sBAAsB,sBAAsB,kBAAkB,CAAC,yEAAyE,gBAAgB,UAAU,CAAC,+EAA+E,WAAW,eAAe,CAAC,oCAAoC,gBAAgB,kBAAkB,CAAC,wCAAwC,UAAU,KAAK,CAAC,kEAAkE,+BAA+B,mBAAmB,gBAAgB,WAAW,iBAAiB,OAAO,CAAC,2BAA2B,gBAAgB,iBAAiB,kBAAkB,CAAC,qCAAqC,UAAU,OAAO,CAAC,kDAAkD,UAAU,CAAC,oCAAoC,WAAW,MAAM,CAAC,iDAAiD,SAAS,CAAC,sCAAsC,gBAAgB,UAAU,CAAC,uCAAuC,mBAAmB,UAAU,CAAC,8GAA8G,YAAY,WAAW,iBAAiB,UAAU,cAAc,2BAA2B,CAAC,CAAC,0CAA0C,MAAM,iBAAiB,CAAC,qBAAqB,UAAU,CAAC,6BAA6B,WAAW,iBAAiB,CAAC,WAAW,yBAAyB,CAAC,YAAY,0BAA0B,CAAC,aAAa,2BAA2B,CAAC,cAAc,4BAA4B,CAAC,wCAAwC,sBAAsB,yBAAyB,CAAC,uBAAuB,0BAA0B,CAAC,wBAAwB,2BAA2B,CAAC,yBAAyB,4BAA4B,CAAC,CAAC,mBAAmB,iBAAiB,yBAAyB,CAAC,kBAAkB,0BAA0B,CAAC,mBAAmB,2BAA2B,CAAC,oBAAoB,4BAA4B,CAAC,CAAC,kEAAkE,uBAAuB,yBAAyB,CAAC,wBAAwB,0BAA0B,CAAC,yBAAyB,2BAA2B,CAAC,0BAA0B,4BAA4B,CAAC,CAAC,6CAA6C,kBAAkB,yBAAyB,CAAC,mBAAmB,0BAA0B,CAAC,oBAAoB,2BAA2B,CAAC,qBAAqB,4BAA4B,CAAC,CAAC,kEAAkE,sBAAsB,yBAAyB,CAAC,uBAAuB,0BAA0B,CAAC,wBAAwB,2BAA2B,CAAC,yBAAyB,4BAA4B,CAAC,CAAC,6CAA6C,iBAAiB,yBAAyB,CAAC,kBAAkB,0BAA0B,CAAC,mBAAmB,2BAA2B,CAAC,oBAAoB,4BAA4B,CAAC,CAAC,mEAAmE,uBAAuB,yBAAyB,CAAC,wBAAwB,0BAA0B,CAAC,yBAAyB,2BAA2B,CAAC,0BAA0B,4BAA4B,CAAC,CAAC,6CAA6C,kBAAkB,yBAAyB,CAAC,mBAAmB,0BAA0B,CAAC,oBAAoB,2BAA2B,CAAC,qBAAqB,4BAA4B,CAAC,CAAC,6EAA6E,wBAAwB,yBAAyB,CAAC,yBAAyB,0BAA0B,CAAC,0BAA0B,2BAA2B,CAAC,2BAA2B,4BAA4B,CAAC,CAAC,8CAA8C,mBAAmB,yBAAyB,CAAC,oBAAoB,0BAA0B,CAAC,qBAAqB,2BAA2B,CAAC,sBAAsB,4BAA4B,CAAC,CAAC,oEAAoE,SAAS,SAAS,CAAC,EAAE,mBAAmB,CAAC,gBAAgB,aAAa,CAAC,MAAM,WAAW,CAAC,EAAE,qBAAqB,CAAC,OAAO,qBAAqB,eAAe,CAAC,QAAQ,kBAAkB,kBAAkB,gBAAgB,CAAC,kBAAkB,WAAW,kBAAkB,eAAe,CAAC,sDAAsD,cAAc,cAAc,aAAa,CAAC,MAAM,kBAAkB,CAAC,GAAG,cAAc,CAAC,WAAW,gBAAgB,cAAc,iBAAiB,mBAAmB,CAAC,oBAAoB,mBAAmB,CAAC,GAAG,uBAAuB,kBAAkB,qBAAqB,SAAS,0BAA0B,CAAC,KAAK,iBAAiB,CAAC,MAAM,aAAa,CAAC,KAAK,yBAAyB,yBAAqB,AAAoC,WAAW,uDAAyD,iCAAiC,CAAC,2EAA2E,eAAe,CAAC,SAAS,oBAAoB,eAAe,gBAAgB,4BAA4B,qBAAqB,CAAC,kBAAkB,oBAAoB,eAAe,CAAC,4BAA4B,kBAAkB,CAAC,8CAA8C,kBAAkB,CAAC,UAAU,sBAAsB,CAAC,UAAU,sBAAsB,CAAC,QAAQ,oBAAoB,CAAC,qCAAqC,oBAAoB,CAAC,kBAAkB,oBAAoB,eAAe,CAAC,WAAW,aAAa,CAAC,kCAAkC,oBAAoB,gBAAgB,eAAe,CAAC,MAAM,mBAAmB,CAAC,MAAM,oBAAoB,CAAC,kBAAkB,kBAAkB,CAAC,aAAa,yBAAyB,cAAc,WAAW,WAAW,CAAC,KAAK,mBAAmB,CAAC,YAAY,6BAA6B,CAAC,WAAW,qCAAqC,0BAA0B,CAAC,gBAAgB,cAAc,mBAAmB,UAAU,CAAC,uBAAuB,qBAAqB,CAAC,4CAA4C,UAAU,CAAC,wBAAwB,gBAAgB,aAAa,CAAC,OAAO,qBAAqB,sBAAsB,sBAAsB,CAAC,UAAU,SAAS,aAAa,CAAC,WAAW,kBAAkB,CAAC,aAAa,eAAe,YAAY,kBAAkB,CAAC,6CAA6C,kBAAkB,eAAe,CAAC,GAAG,iBAAiB,CAAC,GAAG,mBAAmB,CAAC,GAAG,mBAAmB,CAAC,GAAG,mBAAmB,CAAC,GAAG,kBAAkB,CAAC,GAAG,cAAc,CAAC,CAAC,aAAa,sBAAsB,uBAAuB,CAAC,EAAE,yBAAyB,qBAAqB,0BAA0B,0BAA0B,CAAC,YAAY,yBAAyB,CAAC,cAAc,2BAA2B,CAAC,kBAAkB,4BAA4B,CAAC,4DAA4D,UAAU,CAAC,eAAe,qBAAqB,CAAC,MAAM,0BAA0B,CAAC,IAAI,wBAAwB,CAAC,MAAM,YAAY,CAAC,QAAQ,UAAU,QAAQ,CAAC,MAAM,sBAAsB,CAAC,CAAC,iBAAiB,mCAAmC,eAAe,CAAC,8GAA8G,gBAAgB,gCAAgC,CAAC,YAAY,6BAA6B,CAAC,6CAA6C,iBAAiB,eAAe,CAAC,qCAAqC,YAAY,aAAa,CAAC,SAAS,mCAAmC,gBAAgB,WAAW,iBAAiB,sBAAsB,iBAAiB,CAAC,wEAAwE,WAAW,gBAAgB,sBAAsB,QAAQ,CAAC,gDAAgD,kBAAkB,CAAC,YAAY,+BAA+B,MAAM,CAAC,aAAa,8BAA8B,OAAO,CAAC,iBAAiB,iBAAiB,kBAAkB,iBAAiB,CAAC,sBAAsB,gBAAgB,OAAO,eAAe,CAAC,uBAAuB,iBAAiB,eAAe,OAAO,CAAC,cAAc,iBAAiB,CAAC,wBAAwB,eAAe,eAAe,CAAC,oBAAoB,WAAW,cAAc,UAAU,kBAAkB,sBAAsB,uBAA4B,CAAC,+BAAgC,WAAW,cAAc,SAAS,kBAAkB,QAAQ,kBAAkB,eAAe,6DAA6D,UAAU,CAAC,6CAA6C,mCAAmC,gBAAgB,uBAAuB,iCAAiC,4CAA4C,kBAAkB,gBAAgB,kBAAkB,iCAAiC,gBAAgB,SAAS,KAAK,CAAC,qCAAqC,qEAAqE,CAAC,sBAAsB,aAAa,iCAAiC,MAAM,CAAC,wBAAwB,kCAAkC,CAAC,uBAAuB,aAAa,gCAAgC,OAAO,CAAC,6CAA6C,mCAAmC,gBAAgB,uBAAuB,iCAAiC,4CAA4C,kBAAkB,gBAAgB,kBAAkB,iCAAiC,aAAa,WAAW,eAAe,CAAC,yBAAyB,kCAAkC,CAAC,qBAAqB,SAAS,iCAAiC,KAAK,CAAC,uBAAuB,kCAAkC,CAAC,wBAAwB,gCAAgC,QAAQ,CAAC,kHAAkH,aAAa,mCAAmC,8DAA8D,+BAA+B,wCAAwC,SAAS,cAAc,OAAO,kBAAkB,QAAQ,MAAM,cAAc,CAAC,0BAA0B,kCAAkC,CAAC,mBAAmB,SAAS,SAAS,CAAC,4BAA4B,gBAAgB,mBAAmB,6BAA6B,WAAW,cAAc,iBAAiB,SAAS,uBAAuB,wBAAwB,CAAC,wBAAwB,gCAAgC,yBAA2B,cAAc,kBAAkB,8BAA8B,CAAC,0FAA0F,WAAW,gBAAgB,uBAAuB,mBAAmB,6BAA6B,wBAAwB,CAAC,6DAA6D,kBAAkB,CAAC,wBAAwB,oCAAoC,CAAC,6BAA6B,6BAA+B,CAAC,6CAA6C,mCAAmC,8BAAgC,CAAC,CAAC,uBAAuB,qCAAqC,CAAC,4BAA4B,6BAA+B,CAAC,6CAA6C,kCAAkC,8BAAgC,CAAC,CAAC,sBAAsB,oCAAoC,CAAC,2BAA2B,6BAA+B,CAAC,6CAA6C,iCAAiC,8BAAgC,CAAC,CAAC,yBAAyB,mCAAmC,CAAC,8BAA8B,6BAA+B,CAAC,6CAA6C,oCAAoC,8BAAgC,CAAC,CAAC,sKAAsK,eAAe,YAAY,CAAC,oCAAoC,mCAAmC,8DAA8D,eAAe,+BAA+B,wCAAwC,8BAAgC,SAAS,cAAc,OAAO,kBAAkB,QAAQ,MAAM,YAAY,CAAC,6CAA6C,0CAA0C,8BAAgC,CAAC,CAAC,+CAA+C,eAAe,YAAY,CAAC,yCAAyC,mCAAmC,8DAA8D,eAAe,+BAA+B,wCAAwC,8BAAgC,SAAS,cAAc,OAAO,kBAAkB,QAAQ,MAAM,YAAY,CAAC,6CAA6C,+CAA+C,8BAAgC,CAAC,CAAC,+CAA+C,eAAe,YAAY,CAAC,0CAA0C,mCAAmC,8DAA8D,eAAe,+BAA+B,wCAAwC,8BAAgC,SAAS,cAAc,OAAO,kBAAkB,QAAQ,MAAM,YAAY,CAAC,6CAA6C,gDAAgD,8BAAgC,CAAC,CAAC,+CAA+C,eAAe,YAAY,CAAC,wCAAwC,mCAAmC,8DAA8D,eAAe,+BAA+B,wCAAwC,8BAAgC,SAAS,cAAc,OAAO,kBAAkB,QAAQ,MAAM,YAAY,CAAC,6CAA6C,8CAA8C,8BAAgC,CAAC,CAAC,+CAA+C,eAAe,YAAY,CAAC,2CAA2C,mCAAmC,8DAA8D,eAAe,+BAA+B,wCAAwC,8BAAgC,SAAS,cAAc,OAAO,kBAAkB,QAAQ,MAAM,YAAY,CAAC,6CAA6C,iDAAiD,8BAAgC,CAAC,CAAC,wCAAwC,eAAe,CAAC,yCAAyC,gBAAgB,CAAC,uCAAuC,aAAa,CAAC,0CAA0C,gBAAgB,CAAC,6BAA6B,mCAAmC,iCAAiC,SAAS,uBAAuB,kBAAkB,gBAAgB,kBAAkB,MAAM,eAAe,CAAC,yCAAyC,eAAe,CAAC,0CAA0C,cAAc,CAAC,wCAAwC,cAAc,CAAC,2CAA2C,aAAa,CAAC,cAAc,gBAAgB,SAAS,gBAAgB,aAAa,iCAAiC,OAAO,6BAA6B,CAAC,gBAAgB,kCAAkC,CAAC,sBAAsB,gBAAgB,QAAQ,CAAC,4BAA4B,mBAAmB,mBAAmB,4BAA4B,CAAC,6BAA6B,cAAc,mBAAmB,cAAc,CAAC,+FAA+F,uBAA4B,CAAC,eAAe,gBAAgB,SAAS,AAA6B,gCAAgC,OAAQ,CAA8B,4CAAnG,gBAAgB,aAAa,AAAwC,6BAA6B,CAAkQ,AAAjQ,6BAA6B,iCAAiC,uBAAuB,kBAAkB,gBAAgB,kBAAkB,MAAM,AAA6B,SAAS,UAAW,CAAiE,8CAAnC,kCAAkC,CAAqD,uBAAuB,gBAAgB,QAAQ,CAAC,6BAA6B,mBAAmB,mBAAmB,4BAA4B,CAAC,6BAA6B,cAAc,kBAAkB,cAAc,CAAC,gGAAgG,uBAA4B,CAAC,aAAa,gBAAgB,SAAS,gCAAgC,CAAC,eAAe,kCAAkC,CAAC,qBAAqB,gBAAgB,QAAQ,CAAC,2BAA2B,mBAAmB,mBAAmB,4BAA4B,CAAC,8FAA8F,uBAA4B,CAAC,gBAAgB,gBAAgB,SAAS,+BAA+B,CAAC,yBAAyB,sBAAsB,WAAW,CAAC,mCAAmC,8BAA8B,CAAC,kBAAkB,kCAAkC,CAAC,wBAAwB,gBAAgB,QAAQ,CAAC,8BAA8B,mBAAmB,mBAAmB,4BAA4B,CAAC,iGAAiG,uBAA4B,CAAC,gEAAgE,cAAc,kBAAkB,cAAc,CAAC,kEAAkE,cAAc,mBAAmB,cAAc,CAAC,+BAA+B,iBAAiB,CAAC,mBAAmB,iZAAiZ,yBAAyB,CAAC,iZAAiZ,sBAAsB,CAAC,icAAic,0BAA0B,YAAY,WAAW,iBAAiB,SAAS,CAAC,qcAAqc,2BAA2B,WAAW,gBAAgB,4BAA4B,SAAS,CAAC,qfAAqf,uBAAuB,CAAC,qfAAqf,oCAAoC,CAAC,qfAAqf,iCAAiC,CAAC,ybAAyb,iBAAiB,CAAC,k3BAAk3B,4BAA4B,CAAC,CAAC,6CAA6C,iZAAiZ,yBAAyB,CAAC,iZAAiZ,sBAAsB,CAAC,icAAic,0BAA0B,YAAY,WAAW,iBAAiB,SAAS,CAAC,qcAAqc,2BAA2B,WAAW,gBAAgB,4BAA4B,SAAS,CAAC,qfAAqf,uBAAuB,CAAC,qfAAqf,oCAAoC,CAAC,qfAAqf,iCAAiC,CAAC,ybAAyb,iBAAiB,CAAC,k3BAAk3B,4BAA4B,CAAC,CAAC,6CAA6C,iZAAiZ,yBAAyB,CAAC,iZAAiZ,sBAAsB,CAAC,icAAic,0BAA0B,YAAY,WAAW,iBAAiB,SAAS,CAAC,qcAAqc,2BAA2B,WAAW,gBAAgB,4BAA4B,SAAS,CAAC,qfAAqf,uBAAuB,CAAC,qfAAqf,oCAAoC,CAAC,qfAAqf,iCAAiC,CAAC,ybAAyb,iBAAiB,CAAC,k3BAAk3B,4BAA4B,CAAC,CAAC,6CAA6C,iZAAiZ,yBAAyB,CAAC,iZAAiZ,sBAAsB,CAAC,icAAic,0BAA0B,YAAY,WAAW,iBAAiB,SAAS,CAAC,qcAAqc,2BAA2B,WAAW,gBAAgB,4BAA4B,SAAS,CAAC,qfAAqf,uBAAuB,CAAC,qfAAqf,oCAAoC,CAAC,qfAAqf,iCAAiC,CAAC,ybAAyb,iBAAiB,CAAC,k3BAAk3B,4BAA4B,CAAC,CAAC,8CAA8C,iZAAiZ,yBAAyB,CAAC,iZAAiZ,sBAAsB,CAAC,icAAic,0BAA0B,YAAY,WAAW,iBAAiB,SAAS,CAAC,qcAAqc,2BAA2B,WAAW,gBAAgB,4BAA4B,SAAS,CAAC,qfAAqf,uBAAuB,CAAC,qfAAqf,oCAAoC,CAAC,qfAAqf,iCAAiC,CAAC,ybAAyb,iBAAiB,CAAC,k3BAAk3B,4BAA4B,CAAC,CAAC,uCAAuC,yBAAyB,CAAC,uCAAuC,sBAAsB,CAAC,iDAAiD,uBAAuB,CAAC,iDAAiD,oCAAoC,CAAC,iDAAiD,iCAAiC,CAAC,2CAA2C,2BAA2B,CAAC,sFAAsF,4BAA4B,CAAC,+CAA+C,uCAAuC,yBAAyB,CAAC,uCAAuC,sBAAsB,CAAC,iDAAiD,uBAAuB,CAAC,iDAAiD,oCAAoC,CAAC,iDAAiD,iCAAiC,CAAC,2CAA2C,2BAA2B,CAAC,sFAAsF,4BAA4B,CAAC,CAAC,8CAA8C,uCAAuC,yBAAyB,CAAC,uCAAuC,sBAAsB,CAAC,iDAAiD,uBAAuB,CAAC,iDAAiD,oCAAoC,CAAC,iDAAiD,iCAAiC,CAAC,2CAA2C,2BAA2B,CAAC,sFAAsF,4BAA4B,CAAC,CAAC,gBAAgB,sBAAsB,CAAC,uCAAuC,yBAAyB,CAAC,uBAAuB,sBAAsB,CAAC,iDAAiD,uBAAuB,CAAC,iDAAiD,oCAAoC,CAAC,iDAAiD,iCAAiC,CAAC,2CAA2C,2BAA2B,CAAC,sFAAsF,4BAA4B,CAAC,4BAA4B,2BAA2B,WAAW,gBAAgB,4BAA4B,SAAS,CAAC,2CAA2C,0BAA0B,YAAY,WAAW,iBAAiB,SAAS,CAAC,4BAA4B,sBAAsB,CAAC,aAAa,4BAA4B,uBAAuB,CAAC,+BAA+B,sBAAsB,CAAC,qBAAqB,uBAAuB,CAAC,qBAAqB,oCAAoC,CAAC,qBAAqB,iCAAiC,CAAC,kBAAkB,2BAA2B,CAAC,oCAAoC,4BAA4B,CAAC,CAAC,iCAAiC,oBAAoB,CAAC;;;GAGnhyF,WAAW,wBAAwB,kDAAkD,mWAAmW,gBAAgB,iBAAiB,CAAC,IAAI,6CAA6C,kBAAkB,oBAAoB,kCAAkC,CAAC,OAAO,oBAAoB,kBAAkB,mBAAmB,CAAC,OAAO,aAAa,CAAC,OAAO,aAAa,CAAC,OAAO,aAAa,CAAC,OAAO,aAAa,CAAC,OAAO,eAAe,CAAC,OAAO,eAAe,qBAAqB,CAAC,iCAAiC,gBAAgB,CAAC,UAAU,iBAAiB,CAAC,OAAO,kBAAkB,gBAAgB,gBAAgB,YAAY,CAAC,aAAa,eAAe,CAAC,WAAW,yBAAyB,wBAAwB,kBAAkB,CAAC,cAAc,UAAU,CAAC,2BAA2B,WAAW,CAAC,WAAW,UAAU,CAAC,SAAS,8BAAoC,CAAC,UAAU,gCAAsC,CAAC,aAAmB,GAAG,mBAAmB,CAAC,GAAK,wBAAwB,CAAC,CAAC,cAAc,sEAAsE,uBAAuB,CAAC,eAAe,sEAAsE,wBAAwB,CAAC,eAAe,sEAAsE,wBAAwB,CAAC,oBAAoB,gFAAgF,oBAAqB,CAAC,kBAAkB,gFAAgF,oBAAqB,CAAC,gHAAgH,WAAW,CAAC,UAAU,kBAAkB,UAAU,WAAW,gBAAgB,qBAAqB,CAAC,0BAA0B,kBAAkB,OAAO,WAAW,iBAAiB,CAAC,aAAa,mBAAmB,CAAC,aAAa,aAAa,CAAC,YAAY,UAAU,CAAC,iBAAiB,WAAW,CAAC,iBAAiB,WAAW,CAAC,kBAAkB,WAAW,CAAC,sBAAsB,WAAW,CAAC,iBAAiB,WAAW,CAAC,gBAAgB,WAAW,CAAC,kBAAkB,WAAW,CAAC,gBAAgB,WAAW,CAAC,gBAAgB,WAAW,CAAC,oBAAoB,WAAW,CAAC,cAAc,WAAW,CAAC,mBAAmB,WAAW,CAAC,iBAAiB,WAAW,CAAC,oDAAoD,WAAW,CAAC,uBAAuB,WAAW,CAAC,wBAAwB,WAAW,CAAC,qBAAqB,WAAW,CAAC,kBAAkB,WAAW,CAAC,+BAA+B,WAAW,CAAC,mBAAmB,WAAW,CAAC,gBAAgB,WAAW,CAAC,kBAAkB,WAAW,CAAC,mBAAmB,WAAW,CAAC,gBAAgB,WAAW,CAAC,oBAAoB,WAAW,CAAC,+BAA+B,WAAW,CAAC,6BAA6B,WAAW,CAAC,iBAAiB,WAAW,CAAC,yBAAyB,WAAW,CAAC,0CAA0C,WAAW,CAAC,mBAAmB,WAAW,CAAC,oBAAoB,WAAW,CAAC,gBAAgB,WAAW,CAAC,gBAAgB,WAAW,CAAC,sBAAsB,WAAW,CAAC,sBAAsB,WAAW,CAAC,uBAAuB,WAAW,CAAC,qBAAqB,WAAW,CAAC,kBAAkB,WAAW,CAAC,mBAAmB,WAAW,CAAC,eAAe,WAAW,CAAC,gBAAgB,WAAW,CAAC,gBAAgB,WAAW,CAAC,oBAAoB,WAAW,CAAC,iBAAiB,WAAW,CAAC,kBAAkB,WAAW,CAAC,gBAAgB,WAAW,CAAC,gBAAgB,WAAW,CAAC,kBAAkB,WAAW,CAAC,uBAAuB,WAAW,CAAC,sBAAsB,WAAW,CAAC,sBAAsB,WAAW,CAAC,wBAAwB,WAAW,CAAC,uBAAuB,WAAW,CAAC,yBAAyB,WAAW,CAAC,gBAAgB,WAAW,CAAC,qCAAqC,WAAW,CAAC,kBAAkB,WAAW,CAAC,wBAAwB,WAAW,CAAC,uDAAuD,WAAW,CAAC,kBAAkB,WAAW,CAAC,sBAAsB,WAAW,CAAC,kBAAkB,WAAW,CAAC,gBAAgB,WAAW,CAAC,2CAA2C,WAAW,CAAC,0BAA0B,WAAW,CAAC,0BAA0B,WAAW,CAAC,kBAAkB,WAAW,CAAC,yBAAyB,WAAW,CAAC,yBAAyB,WAAW,CAAC,oBAAoB,WAAW,CAAC,gBAAgB,WAAW,CAAC,iBAAiB,WAAW,CAAC,gBAAgB,WAAW,CAAC,mBAAmB,WAAW,CAAC,wBAAwB,WAAW,CAAC,wBAAwB,WAAW,CAAC,iBAAiB,WAAW,CAAC,wBAAwB,WAAW,CAAC,yBAAyB,WAAW,CAAC,uBAAuB,WAAW,CAAC,wBAAwB,WAAW,CAAC,wBAAwB,WAAW,CAAC,wBAAwB,WAAW,CAAC,2BAA2B,WAAW,CAAC,uBAAuB,WAAW,CAAC,sBAAsB,WAAW,CAAC,0BAA0B,WAAW,CAAC,0BAA0B,WAAW,CAAC,eAAe,WAAW,CAAC,sBAAsB,WAAW,CAAC,uBAAuB,WAAW,CAAC,oBAAoB,WAAW,CAAC,sBAAsB,WAAW,CAAC,yCAAyC,WAAW,CAAC,kBAAkB,WAAW,CAAC,oBAAoB,WAAW,CAAC,gBAAgB,WAAW,CAAC,iBAAiB,WAAW,CAAC,oBAAoB,WAAW,CAAC,8BAA8B,WAAW,CAAC,gBAAgB,WAAW,CAAC,gBAAgB,WAAW,CAAC,gBAAgB,WAAW,CAAC,eAAe,WAAW,CAAC,qBAAqB,WAAW,CAAC,mDAAmD,WAAW,CAAC,iBAAiB,WAAW,CAAC,oBAAoB,WAAW,CAAC,kBAAkB,WAAW,CAAC,mBAAmB,WAAW,CAAC,kBAAkB,WAAW,CAAC,sBAAsB,WAAW,CAAC,wBAAwB,WAAW,CAAC,mBAAmB,WAAW,CAAC,yBAAyB,WAAW,CAAC,kBAAkB,WAAW,CAAC,uBAAuB,WAAW,CAAC,oBAAoB,WAAW,CAAC,oBAAoB,WAAW,CAAC,4CAA4C,WAAW,CAAC,0BAA0B,WAAW,CAAC,2BAA2B,WAAW,CAAC,wBAAwB,WAAW,CAAC,eAAe,WAAW,CAAC,iCAAiC,WAAW,CAAC,oBAAoB,WAAW,CAAC,uBAAuB,WAAW,CAAC,yBAAyB,WAAW,CAAC,qBAAqB,WAAW,CAAC,mBAAmB,WAAW,CAAC,oBAAoB,WAAW,CAAC,2BAA2B,WAAW,CAAC,sBAAsB,WAAW,CAAC,yBAAyB,WAAW,CAAC,mBAAmB,WAAW,CAAC,kBAAkB,WAAW,CAAC,yBAAyB,WAAW,CAAC,kBAAkB,WAAW,CAAC,mBAAmB,WAAW,CAAC,iBAAiB,WAAW,CAAC,oBAAoB,WAAW,CAAC,sBAAsB,WAAW,CAAC,wBAAwB,WAAW,CAAC,mBAAmB,WAAW,CAAC,0CAA0C,WAAW,CAAC,kBAAkB,WAAW,CAAC,kBAAkB,WAAW,CAAC,uBAAuB,WAAW,CAAC,+BAA+B,WAAW,CAAC,iBAAiB,WAAW,CAAC,oBAAoB,WAAW,CAAC,gBAAgB,WAAW,CAAC,uBAAuB,WAAW,CAAC,wBAAwB,WAAW,CAAC,uBAAuB,WAAW,CAAC,qBAAqB,WAAW,CAAC,uBAAuB,WAAW,CAAC,6BAA6B,WAAW,CAAC,8BAA8B,WAAW,CAAC,2BAA2B,WAAW,CAAC,6BAA6B,WAAW,CAAC,iBAAiB,WAAW,CAAC,kBAAkB,WAAW,CAAC,iBAAiB,WAAW,CAAC,kBAAkB,WAAW,CAAC,qBAAqB,WAAW,CAAC,sBAAsB,WAAW,CAAC,kCAAkC,WAAW,CAAC,iCAAiC,WAAW,CAAC,iBAAiB,WAAW,CAAC,iBAAiB,WAAW,CAAC,mCAAmC,WAAW,CAAC,mCAAmC,WAAW,CAAC,qBAAqB,WAAW,CAAC,oCAAoC,WAAW,CAAC,kBAAkB,WAAW,CAAC,sDAAsD,WAAW,CAAC,mBAAmB,WAAW,CAAC,mBAAmB,WAAW,CAAC,yBAAyB,WAAW,CAAC,qBAAqB,WAAW,CAAC,iBAAiB,WAAW,CAAC,iBAAiB,WAAW,CAAC,iBAAiB,WAAW,CAAC,qBAAqB,WAAW,CAAC,4BAA4B,WAAW,CAAC,8BAA8B,WAAW,CAAC,uBAAuB,WAAW,CAAC,iBAAiB,WAAW,CAAC,sBAAsB,WAAW,CAAC,oBAAoB,WAAW,CAAC,sBAAsB,WAAW,CAAC,uBAAuB,WAAW,CAAC,mBAAmB,WAAW,CAAC,oCAAoC,WAAW,CAAC,0CAA0C,WAAW,CAAC,uCAAuC,WAAW,CAAC,oBAAoB,WAAW,CAAC,oBAAoB,WAAW,CAAC,uCAAuC,WAAW,CAAC,kCAAkC,WAAW,CAAC,2CAA2C,WAAW,CAAC,qBAAqB,WAAW,CAAC,sBAAsB,WAAW,CAAC,iCAAiC,WAAW,CAAC,mBAAmB,WAAW,CAAC,oBAAoB,WAAW,CAAC,sCAAsC,WAAW,CAAC,uBAAuB,WAAW,CAAC,oBAAoB,WAAW,CAAC,0BAA0B,WAAW,CAAC,wBAAwB,WAAW,CAAC,mBAAmB,WAAW,CAAC,uBAAuB,WAAW,CAAC,oBAAoB,WAAW,CAAC,kBAAkB,WAAW,CAAC,kBAAkB,WAAW,CAAC,mBAAmB,WAAW,CAAC,uBAAuB,WAAW,CAAC,sBAAsB,WAAW,CAAC,sBAAsB,WAAW,CAAC,qBAAqB,WAAW,CAAC,kBAAkB,WAAW,CAAC,uBAAuB,WAAW,CAAC,gBAAgB,WAAW,CAAC,oBAAoB,WAAW,CAAC,uBAAuB,WAAW,CAAC,6BAA6B,WAAW,CAAC,8BAA8B,WAAW,CAAC,2BAA2B,WAAW,CAAC,6BAA6B,WAAW,CAAC,sBAAsB,WAAW,CAAC,uBAAuB,WAAW,CAAC,oBAAoB,WAAW,CAAC,sBAAsB,WAAW,CAAC,mBAAmB,WAAW,CAAC,kBAAkB,WAAW,CAAC,kBAAkB,WAAW,CAAC,0CAA0C,WAAW,CAAC,oBAAoB,WAAW,CAAC,sBAAsB,WAAW,CAAC,uBAAuB,WAAW,CAAC,mBAAmB,WAAW,CAAC,kBAAkB,WAAW,CAAC,uCAAuC,WAAW,CAAC,sBAAsB,WAAW,CAAC,oBAAoB,WAAW,CAAC,yBAAyB,WAAW,CAAC,mBAAmB,WAAW,CAAC,mBAAmB,WAAW,CAAC,iBAAiB,WAAW,CAAC,mBAAmB,WAAW,CAAC,sBAAsB,WAAW,CAAC,kBAAkB,WAAW,CAAC,0BAA0B,WAAW,CAAC,oBAAoB,WAAW,CAAC,gBAAgB,WAAW,CAAC,+CAA+C,WAAW,CAAC,4EAA4E,WAAW,CAAC,0BAA0B,WAAW,CAAC,gBAAgB,WAAW,CAAC,qBAAqB,WAAW,CAAC,0CAA0C,WAAW,CAAC,oBAAoB,WAAW,CAAC,gBAAgB,WAAW,CAAC,uBAAuB,WAAW,CAAC,uBAAuB,WAAW,CAAC,qBAAqB,WAAW,CAAC,kBAAkB,WAAW,CAAC,wBAAwB,WAAW,CAAC,sBAAsB,WAAW,CAAC,4BAA4B,WAAW,CAAC,kBAAkB,WAAW,CAAC,sBAAsB,WAAW,CAAC,6BAA6B,WAAW,CAAC,kBAAkB,WAAW,CAAC,kBAAkB,WAAW,CAAC,+BAA+B,WAAW,CAAC,gCAAgC,WAAW,CAAC,6BAA6B,WAAW,CAAC,+BAA+B,WAAW,CAAC,iBAAiB,WAAW,CAAC,gBAAgB,WAAW,CAAC,kBAAkB,WAAW,CAAC,sBAAsB,WAAW,CAAC,oBAAoB,WAAW,CAAC,sBAAsB,WAAW,CAAC,sBAAsB,WAAW,CAAC,sBAAsB,WAAW,CAAC,uBAAuB,WAAW,CAAC,kBAAkB,WAAW,CAAC,wBAAwB,WAAW,CAAC,0BAA0B,WAAW,CAAC,oBAAoB,WAAW,CAAC,sBAAsB,WAAW,CAAC,wBAAwB,WAAW,CAAC,yBAAyB,WAAW,CAAC,gCAAgC,WAAW,CAAC,wBAAwB,WAAW,CAAC,mBAAmB,WAAW,CAAC,sDAAsD,WAAW,CAAC,kDAAkD,WAAW,CAAC,wDAAwD,WAAW,CAAC,+BAA+B,WAAW,CAAC,eAAe,WAAW,CAAC,iCAAiC,WAAW,CAAC,gCAAgC,WAAW,CAAC,4DAA4D,WAAW,CAAC,kDAAkD,WAAW,CAAC,8BAA8B,WAAW,CAAC,kCAAkC,WAAW,CAAC,gBAAgB,WAAW,CAAC,qBAAqB,WAAW,CAAC,0BAA0B,WAAW,CAAC,2BAA2B,WAAW,CAAC,2BAA2B,WAAW,CAAC,4BAA4B,WAAW,CAAC,4BAA4B,WAAW,CAAC,6BAA6B,WAAW,CAAC,qBAAqB,WAAW,CAAC,uBAAuB,WAAW,CAAC,0BAA0B,WAAW,CAAC,mBAAmB,WAAW,CAAC,gBAAgB,WAAW,CAAC,uBAAuB,WAAW,CAAC,wBAAwB,WAAW,CAAC,mBAAmB,WAAW,CAAC,0BAA0B,WAAW,CAAC,qBAAqB,WAAW,CAAC,kBAAkB,WAAW,CAAC,eAAe,WAAW,CAAC,qBAAqB,WAAW,CAAC,4BAA4B,WAAW,CAAC,kBAAkB,WAAW,CAAC,yBAAyB,WAAW,CAAC,2BAA2B,WAAW,CAAC,yBAAyB,WAAW,CAAC,2BAA2B,WAAW,CAAC,4BAA4B,WAAW,CAAC,iBAAiB,WAAW,CAAC,mBAAmB,WAAW,CAAC,mBAAmB,WAAW,CAAC,iBAAiB,WAAW,CAAC,oBAAoB,WAAW,CAAC,iBAAiB,WAAW,CAAC,sBAAsB,WAAW,CAAC,kBAAkB,WAAW,CAAC,kBAAkB,WAAW,CAAC,gBAAgB,WAAW,CAAC,sCAAsC,WAAW,CAAC,iBAAiB,WAAW,CAAC,kBAAkB,WAAW,CAAC,mBAAmB,WAAW,CAAC,eAAe,WAAW,CAAC,cAAc,WAAW,CAAC,iBAAiB,WAAW,CAAC,kBAAkB,WAAW,CAAC,qBAAqB,WAAW,CAAC,0BAA0B,WAAW,CAAC,gCAAgC,WAAW,CAAC,+BAA+B,WAAW,CAAC,sDAAsD,WAAW,CAAC,wBAAwB,WAAW,CAAC,sBAAsB,WAAW,CAAC,wBAAwB,WAAW,CAAC,uCAAuC,WAAW,CAAC,yBAAyB,WAAW,CAAC,yBAAyB,WAAW,CAAC,iBAAiB,WAAW,CAAC,2BAA2B,WAAW,CAAC,qBAAqB,WAAW,CAAC,kBAAkB,WAAW,CAAC,6DAA6D,WAAW,CAAC,kDAAkD,WAAW,CAAC,iBAAiB,WAAW,CAAC,kBAAkB,WAAW,CAAC,kBAAkB,WAAW,CAAC,yBAAyB,WAAW,CAAC,8BAA8B,WAAW,CAAC,uBAAuB,WAAW,CAAC,qBAAqB,WAAW,CAAC,gBAAgB,WAAW,CAAC,yBAAyB,WAAW,CAAC,0BAA0B,WAAW,CAAC,kBAAkB,WAAW,CAAC,kBAAkB,WAAW,CAAC,oBAAoB,WAAW,CAAC,eAAe,WAAW,CAAC,oBAAoB,WAAW,CAAC,iBAAiB,WAAW,CAAC,eAAe,WAAW,CAAC,iBAAiB,WAAW,CAAC,gBAAgB,WAAW,CAAC,iBAAiB,WAAW,CAAC,mBAAmB,WAAW,CAAC,0BAA0B,WAAW,CAAC,iBAAiB,WAAW,CAAC,wBAAwB,WAAW,CAAC,mBAAmB,WAAW,CAAC,qCAAqC,WAAW,CAAC,+BAA+B,WAAW,CAAC,gBAAgB,WAAW,CAAC,mBAAmB,WAAW,CAAC,sBAAsB,WAAW,CAAC,sBAAsB,WAAW,CAAC,oBAAoB,WAAW,CAAC,sBAAsB,WAAW,CAAC,uBAAuB,WAAW,CAAC,wBAAwB,WAAW,CAAC,6BAA6B,WAAW,CAAC,0EAA0E,WAAW,CAAC,gDAAgD,WAAW,CAAC,gDAAgD,WAAW,CAAC,gDAAgD,WAAW,CAAC,uBAAuB,WAAW,CAAC,gBAAgB,WAAW,CAAC,mBAAmB,WAAW,CAAC,oBAAoB,WAAW,CAAC,wGAAwG,WAAW,CAAC,0BAA0B,WAAW,CAAC,qDAAqD,WAAW,CAAC,gCAAgC,WAAW,CAAC,sBAAsB,WAAW,CAAC,eAAe,WAAW,CAAC,2EAA2E,WAAW,CAAC,yBAAyB,WAAW,CAAC,cAAc,WAAW,CAAC,oCAAoC,WAAW,CAAC,uCAAuC,WAAW,CAAC,2CAA2C,WAAW,CAAC,mBAAmB,WAAW,CAAC,uBAAuB,WAAW,CAAC,kBAAkB,WAAW,CAAC,qBAAqB,WAAW,CAAC,mBAAmB,WAAW,CAAC,qBAAqB,WAAW,CAAC,4BAA4B,WAAW,CAAC,gBAAgB,WAAW,CAAC,6CAA6C,WAAW,CAAC,eAAe,WAAW,CAAC,sBAAsB,WAAW,CAAC,gBAAgB,WAAW,CAAC,sBAAsB,WAAW,CAAC,kBAAkB,WAAW,CAAC,gBAAgB,WAAW,CAAC,uBAAuB,WAAW,CAAC,gBAAgB,WAAW,CAAC,sBAAsB,WAAW,CAAC,kBAAkB,WAAW,CAAC,yBAAyB,WAAW,CAAC,mBAAmB,WAAW,CAAC,yBAAyB,WAAW,CAAC,uBAAuB,WAAW,CAAC,mBAAmB,WAAW,CAAC,qBAAqB,WAAW,CAAC,qBAAqB,WAAW,CAAC,sBAAsB,WAAW,CAAC,wBAAwB,WAAW,CAAC,iBAAiB,WAAW,CAAC,qBAAqB,WAAW,CAAC,cAAc,WAAW,CAAC,sBAAsB,WAAW,CAAC,uBAAuB,WAAW,CAAC,yBAAyB,WAAW,CAAC,sBAAsB,WAAW,CAAC,qBAAqB,WAAW,CAAC,sBAAsB,WAAW,CAAC,kBAAkB,WAAW,CAAC,yBAAyB,WAAW,CAAC,sBAAsB,WAAW,CAAC,qBAAqB,WAAW,CAAC,mBAAmB,WAAW,CAAC,eAAe,WAAW,CAAC,mBAAmB,WAAW,CAAC,qBAAqB,WAAW,CAAC,cAAc,WAAW,CAAC,mDAAmD,WAAW,CAAC,oBAAoB,WAAW,CAAC,sBAAsB,WAAW,CAAC,0BAA0B,WAAW,CAAC,oBAAoB,WAAW,CAAC,oBAAoB,WAAW,CAAC,mBAAmB,WAAW,CAAC,kBAAkB,WAAW,CAAC,wBAAwB,WAAW,CAAC,uBAAuB,WAAW,CAAC,oBAAoB,WAAW,CAAC,qBAAqB,WAAW,CAAC,2BAA2B,WAAW,CAAC,mBAAmB,WAAW,CAAC,gBAAgB,WAAW,CAAC,uBAAuB,WAAW,CAAC,sBAAsB,WAAW,CAAC,uBAAuB,WAAW,CAAC,qBAAqB,WAAW,CAAC,iBAAiB,WAAW,CAAC,gBAAgB,WAAW,CAAC,mBAAmB,WAAW,CAAC,2CAA2C,WAAW,CAAC,2BAA2B,WAAW,CAAC,wBAAwB,WAAW,CAAC,uBAAuB,WAAW,CAAC,sBAAsB,WAAW,CAAC,uBAAuB,WAAW,CAAC,yBAAyB,WAAW,CAAC,yBAAyB,WAAW,CAAC,kBAAkB,WAAW,CAAC,sBAAsB,WAAW,CAAC,6BAA6B,WAAW,CAAC,uBAAuB,WAAW,CAAC,oBAAoB,WAAW,CAAC,kBAAkB,WAAW,CAAC,qBAAqB,WAAW,CAAC,sBAAsB,WAAW,CAAC,gCAAgC,WAAW,CAAC,mBAAmB,WAAW,CAAC,iBAAiB,WAAW,CAAC,kBAAkB,WAAW,CAAC,kBAAkB,WAAW,CAAC,sCAAsC,WAAW,CAAC,yBAAyB,WAAW,CAAC,oBAAoB,WAAW,CAAC,wBAAwB,WAAW,CAAC,gEAAgE,WAAW,CAAC,uDAAuD,WAAW,CAAC,6CAA6C,WAAW,CAAC,gDAAgD,WAAW,CAAC,8CAA8C,WAAW,CAAC,yBAAyB,WAAW,CAAC,oBAAoB,WAAW,CAAC,wBAAwB,WAAW,CAAC,0BAA0B,WAAW,CAAC,uBAAuB,WAAW,CAAC,yBAAyB,WAAW,CAAC,kBAAkB,WAAW,CAAC,0BAA0B,WAAW,CAAC,iBAAiB,WAAW,CAAC,yBAAyB,WAAW,CAAC,uBAAuB,WAAW,CAAC,kDAAkD,WAAW,CAAC,iDAAiD,WAAW,CAAC,gDAAgD,WAAW,CAAC,qBAAqB,WAAW,CAAC,8CAA8C,WAAW,CAAC,+CAA+C,WAAW,CAAC,2BAA2B,WAAW,CAAC,yBAAyB,WAAW,CAAC,wBAAwB,WAAW,CAAC,0BAA0B,WAAW,CAAC,wBAAwB,WAAW,CAAC,qBAAqB,WAAW,CAAC,sBAAsB,WAAW,CAAC,4BAA4B,WAAW,CAAC,cAAc,WAAW,CAAC,qBAAqB,WAAW,CAAC,uBAAuB,WAAW,CAAC,yBAAyB,WAAW,CAAC,gCAAgC,WAAW,CAAC,sBAAsB,WAAW,CAAC,uBAAuB,WAAW,CAAC,kBAAkB,WAAW,CAAC,kBAAkB,WAAW,CAAC,mBAAmB,WAAW,CAAC,iBAAiB,WAAW,CAAC,6BAA6B,WAAW,CAAC,oCAAoC,WAAW,CAAC,kBAAkB,WAAW,CAAC,iBAAiB,WAAW,CAAC,kBAAkB,WAAW,CAAC,2BAA2B,WAAW,CAAC,4BAA4B,WAAW,CAAC,4BAA4B,WAAW,CAAC,4BAA4B,WAAW,CAAC,oBAAoB,WAAW,CAAC,mBAAmB,WAAW,CAAC,qBAAqB,WAAW,CAAC,iBAAiB,WAAW,CAAC,eAAe,WAAW,CAAC,sBAAsB,WAAW,CAAC,wBAAwB,WAAW,CAAC,iBAAiB,WAAW,CAAC,iBAAiB,WAAW,CAAC,qBAAqB,WAAW,CAAC,qBAAqB,WAAW,CAAC,wBAAwB,WAAW,CAAC,gBAAgB,WAAW,CAAC,2BAA2B,WAAW,CAAC,oBAAoB,WAAW,CAAC,gBAAgB,WAAW,CAAC,wBAAwB,WAAW,CAAC,eAAe,WAAW,CAAC,wBAAwB,WAAW,CAAC,oBAAoB,WAAW,CAAC,kBAAkB,WAAW,CAAC,wBAAwB,WAAW,CAAC,0BAA0B,WAAW,CAAC,uBAAuB,WAAW,CAAC,yBAAyB,WAAW,CAAC,wBAAwB,WAAW,CAAC,2BAA2B,WAAW,CAAC,mBAAmB,WAAW,CAAC,qBAAqB,WAAW,CAAC,uBAAuB,WAAW,CAAC,mBAAmB,WAAW,CAAC,kBAAkB,WAAW,CAAC,sBAAsB,WAAW,CAAC,mBAAmB,WAAW,CAAC,kBAAkB,WAAW,CAAC,4BAA4B,WAAW,CAAC,0BAA0B,WAAW,CAAC,6BAA6B,WAAW,CAAC,iBAAiB,WAAW,CAAC,6BAA6B,WAAW,CAAC,gCAAgC,WAAW,CAAC,mBAAmB,WAAW,CAAC,uCAAuC,WAAW,CAAC,2EAA2E,WAAW,CAAC,+DAA+D,WAAW,CAAC,iBAAiB,WAAW,CAAC,mBAAmB,WAAW,CAAC,4CAA4C,WAAW,CAAC,sBAAsB,WAAW,CAAC,kBAAkB,WAAW,CAAC,yBAAyB,WAAW,CAAC,oBAAoB,WAAW,CAAC,0BAA0B,WAAW,CAAC,2BAA2B,WAAW,CAAC,sBAAsB,WAAW,CAAC,uBAAuB,WAAW,CAAC,iBAAiB,WAAW,CAAC,qBAAqB,WAAW,CAAC,8DAA8D,WAAW,CAAC,sCAAsC,WAAW,CAAC,uBAAuB,WAAW,CAAC,yBAAyB,WAAW,CAAC,2BAA2B,WAAW,CAAC,kBAAkB,WAAW,CAAC,wBAAwB,WAAW,CAAC,0BAA0B,WAAW,CAAC,yCAAyC,WAAW,CAAC,6CAA6C,WAAW,CAAC,uBAAuB,WAAW,CAAC,yBAAyB,WAAW,CAAC,kBAAkB,WAAW,CAAC,oBAAoB,WAAW,CAAC,8CAA8C,WAAW,CAAC,kDAAkD,WAAW,CAAC,iBAAiB,WAAW,CAAC,0BAA0B,WAAW,CAAC,oBAAoB,WAAW,CAAC,4EAA4E,WAAW,CAAC,+DAA+D,WAAW,CAAC,qDAAqD,WAAW,CAAC,wDAAwD,WAAW,CAAC,sDAAsD,WAAW,CAAC,kBAAkB,WAAW,CAAC,kDAAkD,WAAW,CAAC,mBAAmB,WAAW,CAAC,2BAA2B,WAAW,CAAC,2BAA2B,WAAW,CAAC,0BAA0B,WAAW,CAAC,mDAAmD,WAAW,CAAC,uDAAuD,WAAW,CAAC,oBAAoB,WAAW,CAAC,gBAAgB,WAAW,CAAC,gBAAgB,WAAW,CAAC,gBAAgB,WAAW,CAAC,mBAAmB,WAAW,CAAC,mBAAmB,WAAW,CAAC,qBAAqB,WAAW,CAAC,uBAAuB,WAAW,CAAC,uBAAuB,WAAW,CAAC,sBAAsB,WAAW,CAAC,kBAAkB,WAAW,CAAC,SAAS,kBAAkB,UAAU,WAAW,UAAU,YAAY,gBAAgB,mBAAmB,QAAQ,CAAC,mDAAmD,gBAAgB,WAAW,YAAY,SAAS,iBAAiB,SAAS,CAAC,WAAW,uBAAuB,6CAA6C,uUAAuU,gBAAgB,iBAAiB,CAAC,WAAW,wBAAwB,+CAA+C,mVAAmV,gBAAgB,iBAAiB,CAAC,QAAQ,oBAAoB,8EAAkF,gBAAgB,qBAAqB,mCAAmC,kBAAkB,wBAAwB,CAAC,IAAI,cAAc,CAAC,IAAI,cAAc,CAAC,IAAI,cAAc,CAAC,IAAI,cAAc,CAAC,IAAI,cAAc,CAAC,IAAI,iBAAiB,CAAC,IAAI,cAAc,CAAC,IAAI,cAAc,CAAC,IAAI,cAAc,CAAC,IAAI,cAAc,CAAC,QAAQ,gBAAgB,CAAC,kBAAkB,wEAA0E,gBAAgB,uBAAuB,mCAAmC,qBAAqB,uBAAuB,CAAC,0CAA0C,cAAc,8EAAkF,gBAAgB,qBAAqB,kCAAkC,CAAC,GAAG,wBAAwB,CAAC,GAAG,cAAc,CAAC,uCAAuC,gBAAgB,CAAC,mCAAmC,aAAa,CAAC,uBAAuB,aAAa,CAAC,iCAAiC,cAAc,eAAe,wEAA0E,gBAAgB,uBAAuB,kCAAkC,CAAC,eAAe,8EAAkF,gBAAgB,oBAAoB,CAAC,GAAG,cAAc,CAAC,YAAY,yBAAyB,AAAmC,eAAe,UAAU,CAAC,eAA7D,kCAAmC,CAA+E,AAArD,GAAG,cAAe,CAAmC,8CAA8C,gBAAgB,kCAAkC,CAAC,4CAA4C,qBAAqB,wBAAwB,CAAC,eAAe,UAAU,CAAC,GAAG,UAAU,CAAC,gCAAgC,wEAA0E,cAAc,CAAC,sBAAsB,eAAe,iBAAiB,qDAAuD,CAAC,EAAE,iBAAiB,UAAU,CAAC,MAAM,mBAAmB,oBAAoB,CAAC,YAAY,kBAAkB,CAAC,EAAE,aAAa,CAAC,cAAc,wEAA0E,sBAAsB,CAAC,iBAAiB,8EAAkF,gBAAgB,AAAmC,kBAAkB,yBAAyB,qBAAqB,eAAe,iBAAiB,qBAAqB,CAAC,2BAAzJ,kCAAmC,CAA4iB,AAAtb,UAA6C,YAAY,UAAU,SAAS,mFAAwF,2HAA2H,2FAAgG,2BAA2B,2BAA2B,CAAC,MAAM,gBAAgB,CAAC,gBAAgB,kBAAkB,mBAAmB,UAAU,CAAC,SAAS,UAAU,YAAY,OAAO,MAAM,mBAAmB,YAAY,eAAe,kBAAkB,8BAA8B,CAAC,mBAAmB,aAAa,CAAC,wBAAwB,cAAc,cAAc,mBAAmB,UAAU,UAAU,UAAU,CAAC,8BAA8B,WAAW,SAAS,CAAC,YAAY,SAAS,UAAU,mBAAmB,CAAC,cAAc,cAAc,WAAW,uBAAuB,sBAAsB,eAAe,CAAC,oCAAoC,cAAc,kBAAkB,8BAA8B,CAAC,mBAAmB,QAAQ,kBAAkB,iBAAiB,cAAc,YAAY,wEAA0E,gBAAgB,uBAAuB,kCAAkC,CAAC,oBAAoB,kBAAkB,CAAC,wBAAwB,oBAAoB,CAAC,YAAY,wBAAwB,SAAS,CAAC,iBAAiB,cAAc,oBAAoB,WAAW,gBAAgB,0BAA0B,gBAAgB,8EAAkF,gBAAgB,mCAAmC,qBAAqB,uBAA6C,CAAC,uBAAuB,cAAc,kBAAkB,CAAC,qDAAqD,cAAc,cAAc,CAAC,+EAA+E,WAAW,UAAU,kBAAkB,CAAC,2FAA2F,kBAAkB,CAAC,2DAA2D,aAAa,CAAC,mDAAmD,gBAAgB,wBAAwB,qBAAqB,kBAAkB,UAAU,WAAW,cAAc,eAAe,UAAU,CAAC,qCAAqC,uBAAuB,CAAC,kBAAkB,SAAS,sBAAsB,YAAY,CAAC,qBAAqB,QAAQ,CAAC,uBAAuB,4BAA4B,cAAc,eAAe,mCAAmC,cAAc,+BAA+B,sDAAwD,eAAe,CAAC,6BAA6B,cAAc,kBAAkB,CAAC,8BAA8B,cAAc,+BAA+B,kBAAkB,CAAC,0BAA0B,6BAA6B,kBAAkB,CAAC,uCAAuC,YAAY,gBAAgB,CAAC,+CAA+C,gBAAgB,cAAc,kBAAkB,uBAAuB,yBAAyB,aAAa,CAAC,iDAAiD,6BAA6B,cAAc,cAAc,CAAC,mCAAmC,aAAa,CAAC,SAAS,kBAAkB,YAAY,mBAAmB,4BAA4B,gBAAgB,+BAA+B,CAAC,gBAAgB,kBAAkB,eAAe,kBAAkB,kBAAkB,CAAC,mBAAmB,oBAAoB,CAAC,qBAAqB,WAAW,CAAC,uBAAuB,oBAAoB,CAAC,qBAAqB,kBAAkB,MAAM,SAAS,aAAa,gBAAgB,eAAe,oBAAoB,CAAC,kEAAkE,wEAA0E,uBAAuB,mCAAmC,eAAe,CAAC,uBAAuB,iBAAiB,4BAA4B,WAAW,0BAA0B,iBAAiB,cAAc,8BAA8B,CAAC,6BAA6B,aAAa,CAAC,8BAA8B,YAAY,qBAAqB,YAAY,WAAW,mBAAmB,UAAU,CAAC,0CAA0C,YAAY,CAAC,wBAAwB,aAAa,eAAe,MAAM,MAAM,CAAC,4BAA4B,sBAAsB,uBAAuB,UAAU,CAAC,UAAU,gCAAgC,eAAe,WAAW,QAAQ,MAAM,YAAY,CAAC,2BAA2B,wBAAwB,sCAAyC,CAAC,6BAA6B,2BAA2B,CAAC,MAAM,kBAAkB,CAAC,sBAAsB,mBAAmB,CAAC,mBAAmB,gBAAgB,gBAAgB,kBAAkB,YAAY,mBAAmB,sBAAsB,6BAA6B,eAAe,8BAA8B,CAAC,sBAAsB,gBAAgB,WAAW,eAAe,CAAC,yBAAyB,cAAc,QAAQ,CAAC,2BAA2B,eAAe,CAAC,2CAA2C,WAAW,gBAAgB,iBAAiB,CAAC,wBAAwB,gBAAgB,CAAC,0BAA0B,yBAAyB,qBAAqB,uBAAuB,cAAc,eAAe,CAAC,mCAAmC,8EAAkF,oBAAoB,CAAC,4BAA4B,WAAW,cAAc,CAAC,qBAAqB,aAAa,CAAC,2BAA2B,YAAY,qBAAqB,UAAU,CAAC,qCAAqC,eAAe,eAAe,UAAU,WAAW,kBAAkB,kBAAkB,YAAY,WAAW,kBAAkB,8BAA8B,CAAC,2CAA2C,mBAAmB,UAAU,CAAC,qBAAqB,kBAAkB,UAAU,CAAC,kCAAkC,mBAAmB,iBAAiB,eAAe,CAAC,oCAAoC,aAAa,CAAC,uBAAuB,SAAS,YAAY,WAAW,8BAA8B,CAAC,6BAA6B,SAAS,CAAC,mCAAmC,kBAAkB,UAAU,WAAW,gBAAgB,CAAC,sCAAsC,qBAAqB,kBAAkB,gBAAgB,CAAC,wCAAwC,gBAAgB,WAAW,UAAU,WAAW,kBAAkB,mBAAmB,kBAAkB,8BAA8B,CAAC,8CAA8C,mBAAmB,UAAU,CAAC,qCAAqC,aAAa,UAAU,SAAS,aAAa,gBAAgB,8BAA8B,CAAC,mCAAmC,kBAAkB,gBAAgB,CAAC,qDAAqD,cAAc,UAAU,cAAc,CAAC,sDAAsD,wBAAwB,CAAC,SAAS,mBAAmB,qBAAqB,CAAC,gBAAgB,WAAW,eAAe,cAAc,iBAAiB,CAAC,qBAAqB,iBAAiB,iBAAiB,kBAAkB,aAAa,CAAC,2BAA2B,YAAY,cAAc,UAAU,kBAAkB,SAAS,SAAS,WAAW,gBAAgB,WAAW,CAAC,oBAAoB,gBAAgB,oBAAoB,CAAC,kBAAkB,eAAe,CAAC,kEAAkE,gBAAgB,kCAAkC,CAAC,6BAA6B,sBAAsB,WAAW,CAAC,SAAS,cAAc,kBAAkB,CAAC,YAAY,eAAe,kBAAkB,WAAW,CAAC,kBAAkB,aAAa,cAAc,aAAa,WAAW,SAAS,cAAc,CAAC,uBAAuB,4CAAiD,sBAAsB,kBAAkB,kBAAkB,iBAAiB,CAAC,0BAA0B,cAAc,kBAAkB,mBAAmB,CAAC,0BAA0B,sDAAwD,cAAc,eAAe,kBAAkB,CAAC,kCAAkC,kBAAkB,UAAU,SAAS,eAAe,CAAC,2BAA2B,kBAAkB,iBAAiB,SAAS,WAAW,UAAU,CAAC,sCAAsC,WAAW,cAAc,8BAA8B,CAAC,iCAAiC,UAAU,CAAC,6BAA6B,sDAA2D,qBAAqB,SAAS,WAAW,cAAc,WAAW,kBAAkB,UAAU,CAAC,YAAY,UAAU,CAAC,gDAAgD,aAAwB,GAAG,+BAA+B,WAAW,CAAC,oBAAoB,YAAY,CAAC,gBAAgB,WAAW,CAAC,GAAK,2BAA2B,WAAW,CAAC,CAAC,YAAY,0CAA0C,sBAAsB,aAAa,kBAAkB,gBAAgB,gCAA2C,sBAAsB,CAAC,CAAC,qBAAqB,yBAAyB,iBAAiB,oBAAoB,gBAAgB,CAAC,6BAA6B,UAAU,iBAAiB,eAAe,CAAC,4BAA4B,sBAAsB,6BAA6B,oBAAoB,kBAAkB,iBAAiB,UAAU,CAAC,+BAA+B,uBAAuB,gCAAgC,mBAAmB,eAAe,cAAc,8EAAkF,oBAAoB,CAAC,8BAA8B,gBAAgB,cAAc,kBAAkB,mBAAmB,CAAC,oBAAoB,gBAAgB,oBAAoB,kBAAkB,gBAAgB,YAAY,kBAAkB,wEAA0E,gBAAgB,uBAAuB,kCAAkC,CAAC,8CAA8C,8EAAkF,gBAAgB,kCAAkC,CAAC,uBAAuB,oBAAoB,qBAAqB,eAAe,iBAAiB,CAAC,4BAA4B,eAAe,CAAC,+BAA+B,eAAe,cAAc,aAAa,iBAAiB,CAAC,uBAAuB,cAAc,eAAe,yBAAyB,qBAAqB,sBAAsB,kBAAkB,iBAAiB,CAAC,uBAAuB,WAAW,qBAAqB,uBAAuB,CAAC,uBAAuB,iBAAiB,CAAC,sBAAsB,WAAW,kBAAkB,0BAA0B,iBAAiB,CAAC,kCAAkC,eAAe,WAAW,kBAAkB,uBAAuB,kBAAkB,CAAC,wBAAwB,mBAAmB,mBAAmB,CAAC,yDAAyD,yBAAyB,WAAW,YAAY,kBAAkB,qBAAqB,cAAc,CAAC,mEAAmE,UAAU,yBAAyB,cAAc,CAAC,8BAA8B,SAAS,WAAW,aAAa,6BAA6B,eAAe,CAAC,2BAA2B,sBAAsB,CAAC,yBAAyB,WAAW,aAAa,yBAAyB,YAAY,cAAc,CAAC,8GAA8G,iBAAiB,kBAAkB,WAAW,eAAe,eAAe,CAAC,0HAA0H,iBAAiB,CAAC,0BAA0B,gBAAgB,YAAY,UAAU,CAAC,0DAA0D,YAAY,mBAAmB,gBAAgB,iCAAiC,UAAU,CAAC,6BAA6B,WAAW,cAAc,CAAC,sBAAsB,cAAc,yBAAyB,8BAA8B,CAAC,4BAA4B,cAAc,gCAAgC,eAAe,CAAC,iCAAiC,kBAAkB,WAAW,UAAU,eAAe,mBAAmB,8BAA8B,CAAC,uCAAuC,mBAAmB,4BAA4B,CAAC,iJAAiJ,aAAa,CAAC,kNAAkN,UAAU,YAAY,CAAC,wBAAwB,wBAAwB,aAAa,sBAAsB,eAAe,mBAAmB,CAAC,8BAA8B,uBAAuB,CAAC,yFAAyF,gBAAgB,CAAC,4CAA4C,uEAAuE,4BAA4B,CAAC,mBAAmB,YAAY,CAAC,gBAAgB,cAAc,CAAC,4BAA4B,mBAAmB,aAAa,CAAC,UAAU,MAAM,CAAC,yBAAyB,oBAAoB,0BAA0B,iBAAiB,CAAC,MAAM,gBAAgB,CAAC,uBAAuB,iBAAiB,CAAC,kCAAkC,eAAe,eAAe,CAAC,0BAA0B,cAAc,CAAC,sDAAsD,cAAc,CAAC,kCAAkC,wBAAwB,kBAAkB,CAAC,4BAA4B,gBAAgB,CAAC,+BAA+B,cAAc,CAAC,0CAA0C,gBAAgB,iBAAiB,CAAC,iCAAiC,8EAAkF,gBAAgB,qBAAqB,mCAAmC,iBAAiB,CAAC,mCAAmC,qBAAqB,4BAA4B,CAAC,0CAA0C,qBAAqB,4BAA4B,CAAC,sCAAsC,aAAa,6BAA6B,cAAc,wBAAwB,CAAC,yCAAyC,sDAAwD,iBAAiB,eAAe,eAAe,CAAC,2CAA2C,uBAAuB,mBAAmB,uBAAuB,CAAC,6CAA6C,aAAa,CAAC,wCAAwC,gBAAgB,CAAC,gDAAgD,aAAa,CAAC,qBAAqB,YAAY,CAAC,mBAAmB,YAAY,CAAC,gCAAgC,oBAAoB,CAAC,kCAAkC,kBAAkB,WAAW,WAAW,iBAAiB,CAAC,CAAC,qCAAqC,SAAS,gBAAgB,CAAC,sBAAsB,oBAAoB,CAAC,0BAA0B,eAAe,QAAQ,CAAC,CAAC,aAAa,kBAAkB,gBAAgB,CAAC,2BAA2B,kBAAkB,UAAU,CAAC,gBAAgB,oBAAoB,eAAe,qBAAqB,sBAAsB,iBAAiB,CAAC","file":"styles.min.css","sourcesContent":["/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */.antialiased,.fa,body,html{-moz-osx-font-smoothing:grayscale}.clearfix:after,.row .row.collapse:after,.row .row:after,.row:after,[class*=block-grid-]:after{clear:both}img,textarea[rows]{height:auto}.inline-list,.inline-list>li,.top-bar ul{list-style:none}h1,h2,h3,h4,h5,h6,p{text-rendering:optimizeLegibility}.button,.vevent abbr,a,button{text-decoration:none}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}b,optgroup,strong{font-weight:700}dfn{font-style:italic}mark{background:#ff0;color:#000}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0;max-width:100%;-ms-interpolation-mode:bicubic}svg:not(:root){overflow:hidden}figure{margin:1em 40px}pre,textarea{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}.button,button,input,select{line-height:normal}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}legend{border:0;padding:0}table{border-collapse:collapse;border-spacing:0}meta.foundation-version{font-family:\"/5.5.3/\"}meta.foundation-mq-small{font-family:\"/only screen/\";width:0}meta.foundation-mq-small-only{font-family:\"/only screen and (max-width: 40em)/\";width:0}meta.foundation-mq-medium{font-family:\"/only screen and (min-width:40.0625em)/\";width:40.0625em}meta.foundation-mq-medium-only{font-family:\"/only screen and (min-width:40.0625em) and (max-width:64em)/\";width:40.0625em}meta.foundation-mq-large{font-family:\"/only screen and (min-width:64.0625em)/\";width:64.0625em}meta.foundation-mq-large-only{font-family:\"/only screen and (min-width:64.0625em) and (max-width:90em)/\";width:64.0625em}meta.foundation-mq-xlarge{font-family:\"/only screen and (min-width:90.0625em)/\";width:90.0625em}meta.foundation-mq-xlarge-only{font-family:\"/only screen and (min-width:90.0625em) and (max-width:120em)/\";width:90.0625em}meta.foundation-mq-xxlarge{font-family:\"/only screen and (min-width:120.0625em)/\";width:120.0625em}.row,select{width:100%}meta.foundation-data-attribute-namespace{font-family:false}.button,body,button{font-family:\"Helvetica Neue\",Helvetica,Roboto,Arial,sans-serif;font-weight:400;position:relative}*,:after,:before{box-sizing:border-box}body,html{font-size:100%}body{color:#222;cursor:auto;font-style:normal;line-height:1.5}.button,a:hover,button{cursor:pointer}#map_canvas embed,#map_canvas img,#map_canvas object,.map_canvas embed,.map_canvas img,.map_canvas object,.mqa-display embed,.mqa-display img,.mqa-display object{max-width:none!important}.left{float:left!important}.right{float:right!important}.clearfix:after,.clearfix:before{content:\" \";display:table}.hide{display:none}.row .row.collapse:after,.row .row.collapse:before,.row .row:after,.row .row:before,.row:after,.row:before,[class*=block-grid-]:after,[class*=block-grid-]:before{content:\" \";display:table}.invisible{visibility:hidden}.antialiased{-webkit-font-smoothing:antialiased}img{display:inline-block;vertical-align:middle}.row{margin:0 auto;max-width:62.5rem}.row.collapse>.column,.row.collapse>.columns{padding-left:0;padding-right:0}.row.collapse .row{margin-left:0;margin-right:0}.row .row{margin:0 -.9375rem;max-width:none;width:auto}.row .row.collapse{margin:0;max-width:none;width:auto}.column,.columns{padding-left:.9375rem;padding-right:.9375rem;width:100%;float:left}.column+.column:last-child,.column+.columns:last-child,.columns+.column:last-child,.columns+.columns:last-child{float:right}.column+.column.end,.column+.columns.end,.columns+.column.end,.columns+.columns.end{float:left}@media only screen{.column,.columns,.small-pull-0,.small-pull-1,.small-pull-10,.small-pull-11,.small-pull-2,.small-pull-3,.small-pull-4,.small-pull-5,.small-pull-6,.small-pull-7,.small-pull-8,.small-pull-9,.small-push-0,.small-push-1,.small-push-10,.small-push-11,.small-push-2,.small-push-3,.small-push-4,.small-push-5,.small-push-7,.small-push-8,.small-push-9{position:relative}.small-push-0{left:0;right:auto}.small-pull-0{right:0;left:auto}.small-push-1{left:8.33333%;right:auto}.small-pull-1{right:8.33333%;left:auto}.small-push-2{left:16.66667%;right:auto}.small-pull-2{right:16.66667%;left:auto}.small-push-3{left:25%;right:auto}.small-pull-3{right:25%;left:auto}.small-push-4{left:33.33333%;right:auto}.small-pull-4{right:33.33333%;left:auto}.small-push-5{left:41.66667%;right:auto}.small-pull-5{right:41.66667%;left:auto}.small-push-6{position:relative;left:50%;right:auto}.small-pull-6{right:50%;left:auto}.small-push-7{left:58.33333%;right:auto}.small-pull-7{right:58.33333%;left:auto}.small-push-8{left:66.66667%;right:auto}.small-pull-8{right:66.66667%;left:auto}.small-push-9{left:75%;right:auto}.small-pull-9{right:75%;left:auto}.small-push-10{left:83.33333%;right:auto}.small-pull-10{right:83.33333%;left:auto}.small-push-11{left:91.66667%;right:auto}.small-pull-11{right:91.66667%;left:auto}.column,.columns{padding-left:.9375rem;padding-right:.9375rem;float:left}.small-1{width:8.33333%}.small-2{width:16.66667%}.small-3{width:25%}.small-4{width:33.33333%}.small-5{width:41.66667%}.small-6{width:50%}.small-7{width:58.33333%}.small-8{width:66.66667%}.small-9{width:75%}.small-10{width:83.33333%}.small-11{width:91.66667%}.small-12{width:100%}.small-offset-0{margin-left:0!important}.small-offset-1{margin-left:8.33333%!important}.small-offset-2{margin-left:16.66667%!important}.small-offset-3{margin-left:25%!important}.small-offset-4{margin-left:33.33333%!important}.small-offset-5{margin-left:41.66667%!important}.small-offset-6{margin-left:50%!important}.small-offset-7{margin-left:58.33333%!important}.small-offset-8{margin-left:66.66667%!important}.small-offset-9{margin-left:75%!important}.small-offset-10{margin-left:83.33333%!important}.small-offset-11{margin-left:91.66667%!important}.small-reset-order{float:left;left:auto;margin-left:0;margin-right:0;right:auto}.column.small-centered,.columns.small-centered{margin-left:auto;margin-right:auto;float:none}.column.small-uncentered,.columns.small-uncentered{float:left;margin-left:0;margin-right:0}.column.small-centered:last-child,.columns.small-centered:last-child{float:none}.column.small-uncentered:last-child,.columns.small-uncentered:last-child{float:left}.column.small-uncentered.opposite,.columns.small-uncentered.opposite{float:right}.row.small-collapse>.column,.row.small-collapse>.columns{padding-left:0;padding-right:0}.row.small-collapse .row{margin-left:0;margin-right:0}.row.small-uncollapse>.column,.row.small-uncollapse>.columns{padding-left:.9375rem;padding-right:.9375rem;float:left}}@media only screen and (min-width:40.0625em){.medium-pull-0,.medium-pull-1,.medium-pull-10,.medium-pull-11,.medium-pull-2,.medium-pull-3,.medium-pull-4,.medium-pull-5,.medium-pull-6,.medium-pull-7,.medium-pull-8,.medium-pull-9,.medium-push-0,.medium-push-1,.medium-push-10,.medium-push-11,.medium-push-2,.medium-push-3,.medium-push-4,.medium-push-5,.medium-push-6,.medium-push-7,.medium-push-8,.medium-push-9,.pull-0,.pull-1,.pull-10,.pull-11,.pull-2,.pull-3,.pull-4,.pull-5,.pull-6,.pull-7,.pull-8,.pull-9,.push-0,.push-1,.push-10,.push-11,.push-2,.push-3,.push-4,.push-5,.push-6,.push-7,.push-8,.push-9{position:relative}.medium-push-0{left:0;right:auto}.medium-pull-0{right:0;left:auto}.medium-push-1{left:8.33333%;right:auto}.medium-pull-1{right:8.33333%;left:auto}.medium-push-2{left:16.66667%;right:auto}.medium-pull-2{right:16.66667%;left:auto}.medium-push-3{left:25%;right:auto}.medium-pull-3{right:25%;left:auto}.medium-push-4{left:33.33333%;right:auto}.medium-pull-4{right:33.33333%;left:auto}.medium-push-5{left:41.66667%;right:auto}.medium-pull-5{right:41.66667%;left:auto}.medium-push-6{left:50%;right:auto}.medium-pull-6{right:50%;left:auto}.medium-push-7{left:58.33333%;right:auto}.medium-pull-7{right:58.33333%;left:auto}.medium-push-8{left:66.66667%;right:auto}.medium-pull-8{right:66.66667%;left:auto}.medium-push-9{left:75%;right:auto}.medium-pull-9{right:75%;left:auto}.medium-push-10{left:83.33333%;right:auto}.medium-pull-10{right:83.33333%;left:auto}.medium-push-11{left:91.66667%;right:auto}.medium-pull-11{right:91.66667%;left:auto}.column,.columns{position:relative;padding-left:.9375rem;padding-right:.9375rem;float:left}.medium-1{width:8.33333%}.medium-2{width:16.66667%}.medium-3{width:25%}.medium-4{width:33.33333%}.medium-5{width:41.66667%}.medium-6{width:50%}.medium-7{width:58.33333%}.medium-8{width:66.66667%}.medium-9{width:75%}.medium-10{width:83.33333%}.medium-11{width:91.66667%}.medium-12{width:100%}.medium-offset-0{margin-left:0!important}.medium-offset-1{margin-left:8.33333%!important}.medium-offset-2{margin-left:16.66667%!important}.medium-offset-3{margin-left:25%!important}.medium-offset-4{margin-left:33.33333%!important}.medium-offset-5{margin-left:41.66667%!important}.medium-offset-6{margin-left:50%!important}.medium-offset-7{margin-left:58.33333%!important}.medium-offset-8{margin-left:66.66667%!important}.medium-offset-9{margin-left:75%!important}.medium-offset-10{margin-left:83.33333%!important}.medium-offset-11{margin-left:91.66667%!important}.medium-reset-order{float:left;left:auto;margin-left:0;margin-right:0;right:auto}.column.medium-centered,.columns.medium-centered{margin-left:auto;margin-right:auto;float:none}.column.medium-uncentered,.columns.medium-uncentered{float:left;margin-left:0;margin-right:0}.column.medium-centered:last-child,.columns.medium-centered:last-child{float:none}.column.medium-uncentered:last-child,.columns.medium-uncentered:last-child{float:left}.column.medium-uncentered.opposite,.columns.medium-uncentered.opposite{float:right}.row.medium-collapse>.column,.row.medium-collapse>.columns{padding-left:0;padding-right:0}.row.medium-collapse .row{margin-left:0;margin-right:0}.row.medium-uncollapse>.column,.row.medium-uncollapse>.columns{padding-left:.9375rem;padding-right:.9375rem;float:left}.push-0{left:0;right:auto}.pull-0{right:0;left:auto}.push-1{left:8.33333%;right:auto}.pull-1{right:8.33333%;left:auto}.push-2{left:16.66667%;right:auto}.pull-2{right:16.66667%;left:auto}.push-3{left:25%;right:auto}.pull-3{right:25%;left:auto}.push-4{left:33.33333%;right:auto}.pull-4{right:33.33333%;left:auto}.push-5{left:41.66667%;right:auto}.pull-5{right:41.66667%;left:auto}.push-6{left:50%;right:auto}.pull-6{right:50%;left:auto}.push-7{left:58.33333%;right:auto}.pull-7{right:58.33333%;left:auto}.push-8{left:66.66667%;right:auto}.pull-8{right:66.66667%;left:auto}.push-9{left:75%;right:auto}.pull-9{right:75%;left:auto}.push-10{left:83.33333%;right:auto}.pull-10{right:83.33333%;left:auto}.push-11{left:91.66667%;right:auto}.pull-11{right:91.66667%;left:auto}}@media only screen and (min-width:64.0625em){.large-pull-0,.large-pull-1,.large-pull-10,.large-pull-11,.large-pull-2,.large-pull-3,.large-pull-4,.large-pull-5,.large-pull-6,.large-pull-7,.large-pull-8,.large-pull-9,.large-push-0,.large-push-1,.large-push-10,.large-push-11,.large-push-2,.large-push-3,.large-push-4,.large-push-5,.large-push-6,.large-push-7,.large-push-8,.large-push-9,.pull-0,.pull-1,.pull-10,.pull-11,.pull-2,.pull-3,.pull-4,.pull-5,.pull-6,.pull-7,.pull-8,.pull-9,.push-0,.push-1,.push-10,.push-11,.push-2,.push-3,.push-4,.push-5,.push-6,.push-7,.push-8,.push-9{position:relative}.large-push-0{left:0;right:auto}.large-pull-0{right:0;left:auto}.large-push-1{left:8.33333%;right:auto}.large-pull-1{right:8.33333%;left:auto}.large-push-2{left:16.66667%;right:auto}.large-pull-2{right:16.66667%;left:auto}.large-push-3{left:25%;right:auto}.large-pull-3{right:25%;left:auto}.large-push-4{left:33.33333%;right:auto}.large-pull-4{right:33.33333%;left:auto}.large-push-5{left:41.66667%;right:auto}.large-pull-5{right:41.66667%;left:auto}.large-push-6{left:50%;right:auto}.large-pull-6{right:50%;left:auto}.large-push-7{left:58.33333%;right:auto}.large-pull-7{right:58.33333%;left:auto}.large-push-8{left:66.66667%;right:auto}.large-pull-8{right:66.66667%;left:auto}.large-push-9{left:75%;right:auto}.large-pull-9{right:75%;left:auto}.large-push-10{left:83.33333%;right:auto}.large-pull-10{right:83.33333%;left:auto}.large-push-11{left:91.66667%;right:auto}.large-pull-11{right:91.66667%;left:auto}.column,.columns{position:relative;padding-left:.9375rem;padding-right:.9375rem;float:left}.large-1{width:8.33333%}.large-2{width:16.66667%}.large-3{width:25%}.large-4{width:33.33333%}.large-5{width:41.66667%}.large-6{width:50%}.large-7{width:58.33333%}.large-8{width:66.66667%}.large-9{width:75%}.large-10{width:83.33333%}.large-11{width:91.66667%}.large-12{width:100%}.large-offset-0{margin-left:0!important}.large-offset-1{margin-left:8.33333%!important}.large-offset-2{margin-left:16.66667%!important}.large-offset-3{margin-left:25%!important}.large-offset-4{margin-left:33.33333%!important}.large-offset-5{margin-left:41.66667%!important}.large-offset-6{margin-left:50%!important}.large-offset-7{margin-left:58.33333%!important}.large-offset-8{margin-left:66.66667%!important}.large-offset-9{margin-left:75%!important}.large-offset-10{margin-left:83.33333%!important}.large-offset-11{margin-left:91.66667%!important}.large-reset-order{float:left;left:auto;margin-left:0;margin-right:0;right:auto}.column.large-centered,.columns.large-centered{margin-left:auto;margin-right:auto;float:none}.column.large-uncentered,.columns.large-uncentered{float:left;margin-left:0;margin-right:0}.column.large-centered:last-child,.columns.large-centered:last-child{float:none}.column.large-uncentered:last-child,.columns.large-uncentered:last-child{float:left}.column.large-uncentered.opposite,.columns.large-uncentered.opposite{float:right}.row.large-collapse>.column,.row.large-collapse>.columns{padding-left:0;padding-right:0}.row.large-collapse .row{margin-left:0;margin-right:0}.row.large-uncollapse>.column,.row.large-uncollapse>.columns{padding-left:.9375rem;padding-right:.9375rem;float:left}.push-0{left:0;right:auto}.pull-0{right:0;left:auto}.push-1{left:8.33333%;right:auto}.pull-1{right:8.33333%;left:auto}.push-2{left:16.66667%;right:auto}.pull-2{right:16.66667%;left:auto}.push-3{left:25%;right:auto}.pull-3{right:25%;left:auto}.push-4{left:33.33333%;right:auto}.pull-4{right:33.33333%;left:auto}.push-5{left:41.66667%;right:auto}.pull-5{right:41.66667%;left:auto}.push-6{left:50%;right:auto}.pull-6{right:50%;left:auto}.push-7{left:58.33333%;right:auto}.pull-7{right:58.33333%;left:auto}.push-8{left:66.66667%;right:auto}.pull-8{right:66.66667%;left:auto}.push-9{left:75%;right:auto}.pull-9{right:75%;left:auto}.push-10{left:83.33333%;right:auto}.pull-10{right:83.33333%;left:auto}.push-11{left:91.66667%;right:auto}.pull-11{right:91.66667%;left:auto}}[class*=block-grid-]{display:block;padding:0;margin:0 -.625rem}[class*=block-grid-]>li{display:block;float:left;height:auto;padding:0 .625rem 1.25rem}@media only screen{.small-block-grid-1>li{list-style:none;width:100%}.small-block-grid-1>li:nth-of-type(1n){clear:none}.small-block-grid-1>li:nth-of-type(1n+1){clear:both}.small-block-grid-2>li{list-style:none;width:50%}.small-block-grid-2>li:nth-of-type(1n){clear:none}.small-block-grid-2>li:nth-of-type(2n+1){clear:both}.small-block-grid-3>li{list-style:none;width:33.33333%}.small-block-grid-3>li:nth-of-type(1n){clear:none}.small-block-grid-3>li:nth-of-type(3n+1){clear:both}.small-block-grid-4>li{list-style:none;width:25%}.small-block-grid-4>li:nth-of-type(1n){clear:none}.small-block-grid-4>li:nth-of-type(4n+1){clear:both}.small-block-grid-5>li{list-style:none;width:20%}.small-block-grid-5>li:nth-of-type(1n){clear:none}.small-block-grid-5>li:nth-of-type(5n+1){clear:both}.small-block-grid-6>li{list-style:none;width:16.66667%}.small-block-grid-6>li:nth-of-type(1n){clear:none}.small-block-grid-6>li:nth-of-type(6n+1){clear:both}.small-block-grid-7>li{list-style:none;width:14.28571%}.small-block-grid-7>li:nth-of-type(1n){clear:none}.small-block-grid-7>li:nth-of-type(7n+1){clear:both}.small-block-grid-8>li{list-style:none;width:12.5%}.small-block-grid-8>li:nth-of-type(1n){clear:none}.small-block-grid-8>li:nth-of-type(8n+1){clear:both}.small-block-grid-9>li{list-style:none;width:11.11111%}.small-block-grid-9>li:nth-of-type(1n){clear:none}.small-block-grid-9>li:nth-of-type(9n+1){clear:both}.small-block-grid-10>li{list-style:none;width:10%}.small-block-grid-10>li:nth-of-type(1n){clear:none}.small-block-grid-10>li:nth-of-type(10n+1){clear:both}.small-block-grid-11>li{list-style:none;width:9.09091%}.small-block-grid-11>li:nth-of-type(1n){clear:none}.small-block-grid-11>li:nth-of-type(11n+1){clear:both}.small-block-grid-12>li{list-style:none;width:8.33333%}.small-block-grid-12>li:nth-of-type(1n){clear:none}.small-block-grid-12>li:nth-of-type(12n+1){clear:both}}@media only screen and (min-width:40.0625em){.medium-block-grid-1>li{list-style:none;width:100%}.medium-block-grid-1>li:nth-of-type(1n){clear:none}.medium-block-grid-1>li:nth-of-type(1n+1){clear:both}.medium-block-grid-2>li{list-style:none;width:50%}.medium-block-grid-2>li:nth-of-type(1n){clear:none}.medium-block-grid-2>li:nth-of-type(2n+1){clear:both}.medium-block-grid-3>li{list-style:none;width:33.33333%}.medium-block-grid-3>li:nth-of-type(1n){clear:none}.medium-block-grid-3>li:nth-of-type(3n+1){clear:both}.medium-block-grid-4>li{list-style:none;width:25%}.medium-block-grid-4>li:nth-of-type(1n){clear:none}.medium-block-grid-4>li:nth-of-type(4n+1){clear:both}.medium-block-grid-5>li{list-style:none;width:20%}.medium-block-grid-5>li:nth-of-type(1n){clear:none}.medium-block-grid-5>li:nth-of-type(5n+1){clear:both}.medium-block-grid-6>li{list-style:none;width:16.66667%}.medium-block-grid-6>li:nth-of-type(1n){clear:none}.medium-block-grid-6>li:nth-of-type(6n+1){clear:both}.medium-block-grid-7>li{list-style:none;width:14.28571%}.medium-block-grid-7>li:nth-of-type(1n){clear:none}.medium-block-grid-7>li:nth-of-type(7n+1){clear:both}.medium-block-grid-8>li{list-style:none;width:12.5%}.medium-block-grid-8>li:nth-of-type(1n){clear:none}.medium-block-grid-8>li:nth-of-type(8n+1){clear:both}.medium-block-grid-9>li{list-style:none;width:11.11111%}.medium-block-grid-9>li:nth-of-type(1n){clear:none}.medium-block-grid-9>li:nth-of-type(9n+1){clear:both}.medium-block-grid-10>li{list-style:none;width:10%}.medium-block-grid-10>li:nth-of-type(1n){clear:none}.medium-block-grid-10>li:nth-of-type(10n+1){clear:both}.medium-block-grid-11>li{list-style:none;width:9.09091%}.medium-block-grid-11>li:nth-of-type(1n){clear:none}.medium-block-grid-11>li:nth-of-type(11n+1){clear:both}.medium-block-grid-12>li{list-style:none;width:8.33333%}.medium-block-grid-12>li:nth-of-type(1n){clear:none}.medium-block-grid-12>li:nth-of-type(12n+1){clear:both}.button,button{display:inline-block}}@media only screen and (min-width:64.0625em){.large-block-grid-1>li{list-style:none;width:100%}.large-block-grid-1>li:nth-of-type(1n){clear:none}.large-block-grid-1>li:nth-of-type(1n+1){clear:both}.large-block-grid-2>li{list-style:none;width:50%}.large-block-grid-2>li:nth-of-type(1n){clear:none}.large-block-grid-2>li:nth-of-type(2n+1){clear:both}.large-block-grid-3>li{list-style:none;width:33.33333%}.large-block-grid-3>li:nth-of-type(1n){clear:none}.large-block-grid-3>li:nth-of-type(3n+1){clear:both}.large-block-grid-4>li{list-style:none;width:25%}.large-block-grid-4>li:nth-of-type(1n){clear:none}.large-block-grid-4>li:nth-of-type(4n+1){clear:both}.large-block-grid-5>li{list-style:none;width:20%}.large-block-grid-5>li:nth-of-type(1n){clear:none}.large-block-grid-5>li:nth-of-type(5n+1){clear:both}.large-block-grid-6>li{list-style:none;width:16.66667%}.large-block-grid-6>li:nth-of-type(1n){clear:none}.large-block-grid-6>li:nth-of-type(6n+1){clear:both}.large-block-grid-7>li{list-style:none;width:14.28571%}.large-block-grid-7>li:nth-of-type(1n){clear:none}.large-block-grid-7>li:nth-of-type(7n+1){clear:both}.large-block-grid-8>li{list-style:none;width:12.5%}.large-block-grid-8>li:nth-of-type(1n){clear:none}.large-block-grid-8>li:nth-of-type(8n+1){clear:both}.large-block-grid-9>li{list-style:none;width:11.11111%}.large-block-grid-9>li:nth-of-type(1n){clear:none}.large-block-grid-9>li:nth-of-type(9n+1){clear:both}.large-block-grid-10>li{list-style:none;width:10%}.large-block-grid-10>li:nth-of-type(1n){clear:none}.large-block-grid-10>li:nth-of-type(10n+1){clear:both}.large-block-grid-11>li{list-style:none;width:9.09091%}.large-block-grid-11>li:nth-of-type(1n){clear:none}.large-block-grid-11>li:nth-of-type(11n+1){clear:both}.large-block-grid-12>li{list-style:none;width:8.33333%}.large-block-grid-12>li:nth-of-type(1n){clear:none}.large-block-grid-12>li:nth-of-type(12n+1){clear:both}}.button,button{-webkit-appearance:none;-moz-appearance:none;border-radius:0;border-style:solid;border-width:0;margin:0 0 1.25rem;text-align:center;display:inline-block;padding:1rem 2rem 1.0625rem;font-size:1rem;background-color:#008CBA;border-color:#007095;color:#fff;transition:background-color .3s ease-out}.button:focus,.button:hover,button:focus,button:hover{background-color:#007095;color:#fff}.button.secondary,button.secondary{background-color:#e7e7e7;border-color:#b9b9b9;color:#333}.button.secondary:focus,.button.secondary:hover,button.secondary:focus,button.secondary:hover{background-color:#b9b9b9;color:#333}.button.success,button.success{background-color:#43AC6A;border-color:#368a55;color:#fff}.button.success:focus,.button.success:hover,button.success:focus,button.success:hover{background-color:#368a55;color:#fff}.button.alert,button.alert{background-color:#f04124;border-color:#cf2a0e;color:#fff}.button.alert:focus,.button.alert:hover,button.alert:focus,button.alert:hover{background-color:#cf2a0e;color:#fff}.button.warning,button.warning{background-color:#f08a24;border-color:#cf6e0e;color:#fff}.button.warning:focus,.button.warning:hover,button.warning:focus,button.warning:hover{background-color:#cf6e0e;color:#fff}.button.info,button.info{background-color:#a0d3e8;border-color:#61b6d9;color:#333}.button.info:focus,.button.info:hover,button.info:focus,button.info:hover{background-color:#61b6d9;color:#fff}.button.large,button.large{padding:1.125rem 2.25rem 1.1875rem;font-size:1.25rem}.button.small,button.small{padding:.875rem 1.75rem .9375rem;font-size:.8125rem}.button.tiny,button.tiny{padding:.625rem 1.25rem .6875rem;font-size:.6875rem}.button.expand,button.expand{padding:1rem 1rem 1.0625rem;font-size:1rem;width:100%}label,select{font-size:.875rem}.button.left-align,button.left-align{text-align:left;text-indent:.75rem}.button.right-align,button.right-align{text-align:right;padding-right:.75rem}.button.radius,button.radius{border-radius:3px}.button.round,button.round{border-radius:1000px}.button.disabled,.button[disabled],button.disabled,button[disabled]{background-color:#008CBA;border-color:#007095;color:#fff;box-shadow:none;cursor:default;opacity:.7}.button.disabled:focus,.button.disabled:hover,.button[disabled]:focus,.button[disabled]:hover,button.disabled:focus,button.disabled:hover,button[disabled]:focus,button[disabled]:hover{color:#fff;background-color:#008CBA}.button.disabled.secondary,.button[disabled].secondary,button.disabled.secondary,button[disabled].secondary{background-color:#e7e7e7;border-color:#b9b9b9;color:#333;box-shadow:none;cursor:default;opacity:.7}.button.disabled.secondary:focus,.button.disabled.secondary:hover,.button[disabled].secondary:focus,.button[disabled].secondary:hover,button.disabled.secondary:focus,button.disabled.secondary:hover,button[disabled].secondary:focus,button[disabled].secondary:hover{color:#333;background-color:#e7e7e7}.button.disabled.success,.button[disabled].success,button.disabled.success,button[disabled].success{background-color:#43AC6A;border-color:#368a55;color:#fff;box-shadow:none;cursor:default;opacity:.7}.button.disabled.success:focus,.button.disabled.success:hover,.button[disabled].success:focus,.button[disabled].success:hover,button.disabled.success:focus,button.disabled.success:hover,button[disabled].success:focus,button[disabled].success:hover{color:#fff;background-color:#43AC6A}.button.disabled.alert,.button[disabled].alert,button.disabled.alert,button[disabled].alert{background-color:#f04124;border-color:#cf2a0e;color:#fff;box-shadow:none;cursor:default;opacity:.7}.button.disabled.alert:focus,.button.disabled.alert:hover,.button[disabled].alert:focus,.button[disabled].alert:hover,button.disabled.alert:focus,button.disabled.alert:hover,button[disabled].alert:focus,button[disabled].alert:hover{color:#fff;background-color:#f04124}.button.disabled.warning,.button[disabled].warning,button.disabled.warning,button[disabled].warning{background-color:#f08a24;border-color:#cf6e0e;color:#fff;box-shadow:none;cursor:default;opacity:.7}.button.disabled.warning:focus,.button.disabled.warning:hover,.button[disabled].warning:focus,.button[disabled].warning:hover,button.disabled.warning:focus,button.disabled.warning:hover,button[disabled].warning:focus,button[disabled].warning:hover{color:#fff;background-color:#f08a24}.button.disabled.info,.button[disabled].info,button.disabled.info,button[disabled].info{background-color:#a0d3e8;border-color:#61b6d9;color:#333;box-shadow:none;cursor:default;opacity:.7}.button.disabled.info:focus,.button.disabled.info:hover,.button[disabled].info:focus,.button[disabled].info:hover,button.disabled.info:focus,button.disabled.info:hover,button[disabled].info:focus,button[disabled].info:hover{color:#fff;background-color:#a0d3e8}button::-moz-focus-inner{border:0;padding:0}.inline-list>li,.inline-list>li>*,.postfix,.prefix,label{display:block}.inline-list{overflow:hidden;padding:0;margin:0 0 1.0625rem -1.375rem}.inline-list>li{float:left;margin-left:1.375rem}form .row .row{margin:0 -.5rem}form .row .row .column,form .row .row .columns{padding:0 .5rem}form .row .row.collapse{margin:0}form .row .row.collapse .column,form .row .row.collapse .columns{padding:0}form .row .row.collapse input{-webkit-border-bottom-right-radius:0;-webkit-border-top-right-radius:0;border-bottom-right-radius:0;border-top-right-radius:0}form .row input.column,form .row input.columns,form .row textarea.column,form .row textarea.columns{padding-left:.5rem}label{color:#4d4d4d;cursor:pointer;font-weight:400;line-height:1.5;margin-bottom:0}input[type=file],input[type=checkbox],input[type=radio],label.inline,select{margin:0 0 1rem}label.right{float:none!important;text-align:right}label.inline{padding:.5625rem 0}label small{text-transform:capitalize;color:#676767}.postfix,.prefix{border-style:solid;border-width:1px;overflow:visible;padding-bottom:0;padding-top:0;position:relative;text-align:center;width:100%;z-index:2}.postfix.button,.prefix.button{border:none;text-align:center;padding:0}.prefix.button.radius{border-radius:3px 0 0 3px;-webkit-border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px}.postfix.button.radius{border-radius:0 3px 3px 0;-webkit-border-bottom-right-radius:3px;-webkit-border-top-right-radius:3px}.prefix.button.round{border-radius:1000px 0 0 1000px;-webkit-border-bottom-left-radius:1000px;-webkit-border-top-left-radius:1000px}.postfix.button.round{border-radius:0 1000px 1000px 0;-webkit-border-bottom-right-radius:1000px;-webkit-border-top-right-radius:1000px}label.prefix,span.prefix{background:#f2f2f2;border-right:none;color:#333;border-color:#ccc}label.postfix,span.postfix{background:#f2f2f2;border-left:none;color:#333;border-color:#ccc}fieldset[disabled] input:not([type]),fieldset[disabled] input[type=text],fieldset[disabled] input[type=password],fieldset[disabled] input[type=date],fieldset[disabled] input[type=datetime],fieldset[disabled] input[type=datetime-local],fieldset[disabled] input[type=month],fieldset[disabled] input[type=week],fieldset[disabled] input[type=email],fieldset[disabled] input[type=tel],fieldset[disabled] input[type=time],fieldset[disabled] input[type=url],fieldset[disabled] input[type=color],fieldset[disabled] input[type=number],fieldset[disabled] input[type=search],fieldset[disabled] textarea,input:not([type]):disabled,input:not([type])[disabled],input:not([type])[readonly],input[type=text]:disabled,input[type=text][disabled],input[type=text][readonly],input[type=password]:disabled,input[type=password][disabled],input[type=password][readonly],input[type=date]:disabled,input[type=date][disabled],input[type=date][readonly],input[type=datetime]:disabled,input[type=datetime][disabled],input[type=datetime][readonly],input[type=datetime-local]:disabled,input[type=datetime-local][disabled],input[type=datetime-local][readonly],input[type=month]:disabled,input[type=month][disabled],input[type=month][readonly],input[type=week]:disabled,input[type=week][disabled],input[type=week][readonly],input[type=email]:disabled,input[type=email][disabled],input[type=email][readonly],input[type=tel]:disabled,input[type=tel][disabled],input[type=tel][readonly],input[type=time]:disabled,input[type=time][disabled],input[type=time][readonly],input[type=url]:disabled,input[type=url][disabled],input[type=url][readonly],input[type=color]:disabled,input[type=color][disabled],input[type=color][readonly],input[type=number]:disabled,input[type=number][disabled],input[type=number][readonly],input[type=search]:disabled,input[type=search][disabled],input[type=search][readonly],select:disabled,textarea:disabled,textarea[disabled],textarea[readonly]{background-color:#ddd;cursor:default}input:not([type]),input[type=text],input[type=password],input[type=date],input[type=datetime],input[type=datetime-local],input[type=month],input[type=week],input[type=email],input[type=tel],input[type=time],input[type=url],input[type=color],input[type=number],input[type=search],textarea{-webkit-appearance:none;-moz-appearance:none;border-radius:0;background-color:#fff;border-style:solid;border-width:1px;border-color:#ccc;box-shadow:inset 0 1px 2px rgba(0,0,0,.1);color:rgba(0,0,0,.75);display:block;font-family:inherit;font-size:.875rem;height:2.3125rem;margin:0 0 1rem;padding:.5rem;width:100%;box-sizing:border-box;transition:border-color .15s linear,background .15s linear}input:not([type]):focus,input[type=text]:focus,input[type=password]:focus,input[type=date]:focus,input[type=datetime]:focus,input[type=datetime-local]:focus,input[type=month]:focus,input[type=week]:focus,input[type=email]:focus,input[type=tel]:focus,input[type=time]:focus,input[type=url]:focus,input[type=color]:focus,input[type=number]:focus,input[type=search]:focus,textarea:focus{background:#fafafa;border-color:#999;outline:0}input:not([type]).radius,input[type=text].radius,input[type=password].radius,input[type=date].radius,input[type=datetime].radius,input[type=datetime-local].radius,input[type=month].radius,input[type=week].radius,input[type=email].radius,input[type=tel].radius,input[type=time].radius,input[type=url].radius,input[type=color].radius,input[type=number].radius,input[type=search].radius,textarea.radius{border-radius:3px}form .row .prefix-radius.row.collapse button,form .row .prefix-radius.row.collapse input,form .row .prefix-radius.row.collapse select,form .row .prefix-radius.row.collapse textarea{border-radius:0 3px 3px 0;-webkit-border-bottom-right-radius:3px;-webkit-border-top-right-radius:3px}form .row .postfix-radius.row.collapse button,form .row .postfix-radius.row.collapse input,form .row .postfix-radius.row.collapse select,form .row .postfix-radius.row.collapse textarea,form .row .prefix-radius.row.collapse .prefix{border-radius:3px 0 0 3px;-webkit-border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px}form .row .postfix-radius.row.collapse .postfix{border-radius:0 3px 3px 0;-webkit-border-bottom-right-radius:3px;-webkit-border-top-right-radius:3px}form .row .prefix-round.row.collapse button,form .row .prefix-round.row.collapse input,form .row .prefix-round.row.collapse select,form .row .prefix-round.row.collapse textarea{border-radius:0 1000px 1000px 0;-webkit-border-bottom-right-radius:1000px;-webkit-border-top-right-radius:1000px}form .row .postfix-round.row.collapse button,form .row .postfix-round.row.collapse input,form .row .postfix-round.row.collapse select,form .row .postfix-round.row.collapse textarea,form .row .prefix-round.row.collapse .prefix{border-radius:1000px 0 0 1000px;-webkit-border-bottom-left-radius:1000px;-webkit-border-top-left-radius:1000px}form .row .postfix-round.row.collapse .postfix{border-radius:0 1000px 1000px 0;-webkit-border-bottom-right-radius:1000px;-webkit-border-top-right-radius:1000px}input[type=submit]{-webkit-appearance:none;-moz-appearance:none;border-radius:0}textarea{min-height:50px;max-width:100%}::-webkit-input-placeholder{color:#666}:-moz-placeholder{color:#666}::-moz-placeholder{color:#666}:-ms-input-placeholder{color:#666}select{-webkit-appearance:none!important;-moz-appearance:none!important;background-color:#FAFAFA;background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgeD0iMTJweCIgeT0iMHB4IiB3aWR0aD0iMjRweCIgaGVpZ2h0PSIzcHgiIHZpZXdCb3g9IjAgMCA2IDMiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDYgMyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHBvbHlnb24gcG9pbnRzPSI1Ljk5MiwwIDIuOTkyLDMgLTAuMDA4LDAgIi8+PC9zdmc+);background-position:100% center;background-repeat:no-repeat;border-style:solid;border-width:1px;border-color:#ccc;color:rgba(0,0,0,.75);font-family:inherit;padding:.5rem;border-radius:0;height:2.3125rem}select::-ms-expand{display:none}select.radius{border-radius:3px}select:focus{background-color:#f3f3f3;border-color:#999}select[multiple]{height:auto}input[type=checkbox]+label,input[type=radio]+label{display:inline-block;margin-left:.5rem;margin-right:1rem;margin-bottom:0;vertical-align:baseline}input[type=file]{width:100%}fieldset{border:1px solid #ddd;margin:1.125rem 0;padding:1.25rem}fieldset legend{font-weight:700;margin:0 0 0 -.1875rem;padding:0 .1875rem}[data-abide] .error small.error,[data-abide] .error span.error,[data-abide] small.error,[data-abide] span.error{display:block;font-size:.75rem;font-style:italic;font-weight:400;margin-bottom:1rem;margin-top:-1px;padding:.375rem .5625rem .5625rem;background:#f04124;color:#fff}[data-abide] small.error,[data-abide] span.error{display:none}.error small.error,small.error,span.error{display:block;font-size:.75rem;margin-top:-1px;padding:.375rem .5625rem .5625rem;background:#f04124;font-weight:400;font-style:italic}small.error,span.error{margin-bottom:1rem;color:#fff}.error input,.error select,.error textarea{margin-bottom:0}.error input[type=checkbox],.error input[type=radio],.error small.error{margin-bottom:1rem}.error label,.error label.error{color:#f04124}.error small.error{color:#fff}.contain-to-grid .top-bar,.top-bar,.top-bar .button,.top-bar button,.top-bar form,.top-bar input,.top-bar select,.top-bar ul,.top-bar-section .dropdown label,input.error,select.error,textarea.error{margin-bottom:0}.error>label>small{background:0 0;color:#676767;display:inline;font-size:60%;font-style:normal;margin:0;padding:0;text-transform:capitalize}.error span.error-message{display:block}label.error{color:#f04124}meta.foundation-mq-topbar{font-family:\"/only screen and (min-width:40.0625em)/\";width:40.0625em}.contain-to-grid{width:100%;background:#333}.fixed{position:fixed;top:0;width:100%;z-index:99;left:0}.fixed.expanded:not(.top-bar){height:auto;max-height:100%;overflow-y:auto;width:100%}.fixed.expanded:not(.top-bar) .title-area{position:fixed;width:100%;z-index:99}.fixed.expanded:not(.top-bar) .top-bar-section{margin-top:2.8125rem;z-index:98}.top-bar{height:2.8125rem;line-height:2.8125rem;overflow:hidden;position:relative}.top-bar .row{max-width:none}.top-bar input,.top-bar select{font-size:.75rem;height:1.75rem;padding-bottom:.35rem;padding-top:.35rem}.top-bar .button,.top-bar button{font-size:.75rem;padding-bottom:.4125rem;padding-top:.4125rem}@media only screen and (max-width:40em){.top-bar .button,.top-bar button{position:relative;top:-1px}}.top-bar .title-area{margin:0;position:relative}.top-bar .name{font-size:16px;height:2.8125rem;margin:0}.top-bar .name h1,.top-bar .name h2,.top-bar .name h3,.top-bar .name h4,.top-bar .name p,.top-bar .name span{font-size:1.0625rem;line-height:2.8125rem;margin:0}.top-bar .name h1 a,.top-bar .name h2 a,.top-bar .name h3 a,.top-bar .name h4 a,.top-bar .name p a,.top-bar .name span a{color:#fff;display:block;font-weight:400;padding:0 .9375rem;width:75%}.top-bar .toggle-topbar{position:absolute;right:0;top:0}.top-bar .toggle-topbar a{color:#fff;display:block;font-size:.8125rem;font-weight:700;height:2.8125rem;line-height:2.8125rem;padding:0 .9375rem;position:relative;text-transform:uppercase}.top-bar .toggle-topbar.menu-icon{margin-top:-16px;top:50%}.top-bar .toggle-topbar.menu-icon a{color:#fff;height:34px;line-height:33px;padding:0 2.5rem 0 .9375rem;position:relative}.top-bar .toggle-topbar.menu-icon a span::after{content:\"\";display:block;height:0;position:absolute;margin-top:-8px;top:50%;right:.9375rem;box-shadow:0 0 0 1px #fff,0 7px 0 1px #fff,0 14px 0 1px #fff;width:16px}.top-bar-section,.top-bar-section .has-dropdown{position:relative}.top-bar .toggle-topbar.menu-icon a span:hover:after{box-shadow:0 0 0 1px \"\",0 7px 0 1px \"\",0 14px 0 1px \"\"}.top-bar.expanded{background:0 0;height:auto}.top-bar-section ul li,.top-bar.expanded .title-area{background:#333}.top-bar.expanded .toggle-topbar a{color:#888}.top-bar.expanded .toggle-topbar a span::after{box-shadow:0 0 0 1px #888,0 7px 0 1px #888,0 14px 0 1px #888}@media screen and (-webkit-min-device-pixel-ratio:0){.top-bar.expanded .top-bar-section .dropdown,.top-bar.expanded .top-bar-section .has-dropdown.moved>.dropdown{clip:initial}.top-bar.expanded .top-bar-section .has-dropdown:not(.moved)>ul{padding:0}}.top-bar-section{left:0;width:auto;transition:left .3s ease-out}.top-bar-section ul{display:block;font-size:16px;height:auto;margin:0;padding:0;width:100%}.top-bar-section .divider,.top-bar-section [role=separator]{border-top:solid 1px #1a1a1a;clear:both;height:1px;width:100%}.top-bar-section ul li>a{color:#fff;display:block;font-family:\"Helvetica Neue\",Helvetica,Roboto,Arial,sans-serif;font-size:.8125rem;font-weight:400;padding:12px 0 12px .9375rem;text-transform:none;width:100%}.top-bar-section ul li>a.button,.top-bar-section ul li>button{font-size:.8125rem;padding-left:.9375rem;padding-right:.9375rem}.top-bar-section ul li>a.button{background-color:#008CBA;border-color:#007095;color:#fff}.top-bar-section ul li>a.button:focus,.top-bar-section ul li>a.button:hover{background-color:#007095;color:#fff}.top-bar-section ul li>a.button.secondary{background-color:#e7e7e7;border-color:#b9b9b9;color:#333}.top-bar-section ul li>a.button.secondary:focus,.top-bar-section ul li>a.button.secondary:hover{background-color:#b9b9b9;color:#333}.top-bar-section ul li>a.button.success{background-color:#43AC6A;border-color:#368a55;color:#fff}.top-bar-section ul li>a.button.success:focus,.top-bar-section ul li>a.button.success:hover{background-color:#368a55;color:#fff}.top-bar-section ul li>a.button.alert{background-color:#f04124;border-color:#cf2a0e;color:#fff}.top-bar-section ul li>a.button.alert:focus,.top-bar-section ul li>a.button.alert:hover{background-color:#cf2a0e;color:#fff}.top-bar-section ul li>a.button.warning{background-color:#f08a24;border-color:#cf6e0e;color:#fff}.top-bar-section ul li>a.button.warning:focus,.top-bar-section ul li>a.button.warning:hover{background-color:#cf6e0e;color:#fff}.top-bar-section ul li>a.button.info{background-color:#a0d3e8;border-color:#61b6d9;color:#333}.top-bar-section ul li>a.button.info:focus,.top-bar-section ul li>a.button.info:hover{background-color:#61b6d9;color:#fff}.top-bar-section ul li>button{background-color:#008CBA;border-color:#007095;color:#fff}.top-bar-section ul li>button:focus,.top-bar-section ul li>button:hover{background-color:#007095;color:#fff}.top-bar-section ul li>button.secondary{background-color:#e7e7e7;border-color:#b9b9b9;color:#333}.top-bar-section ul li>button.secondary:focus,.top-bar-section ul li>button.secondary:hover{background-color:#b9b9b9;color:#333}.top-bar-section ul li>button.success{background-color:#43AC6A;border-color:#368a55;color:#fff}.top-bar-section ul li>button.success:focus,.top-bar-section ul li>button.success:hover{background-color:#368a55;color:#fff}.top-bar-section ul li>button.alert{background-color:#f04124;border-color:#cf2a0e;color:#fff}.top-bar-section ul li>button.alert:focus,.top-bar-section ul li>button.alert:hover{background-color:#cf2a0e;color:#fff}.top-bar-section ul li>button.warning{background-color:#f08a24;border-color:#cf6e0e;color:#fff}.top-bar-section ul li>button.warning:focus,.top-bar-section ul li>button.warning:hover{background-color:#cf6e0e;color:#fff}.top-bar-section ul li>button.info{background-color:#a0d3e8;border-color:#61b6d9;color:#333}.top-bar-section ul li>button.info:focus,.top-bar-section ul li>button.info:hover{background-color:#61b6d9;color:#fff}.top-bar-section ul li:hover:not(.has-form)>a{color:#fff;background:#222}.top-bar-section ul li.active>a{background:#008CBA;color:#fff}.top-bar-section ul li.active>a:hover{background:#0078a0;color:#fff}.top-bar-section .has-form{padding:.9375rem}.top-bar-section .has-dropdown>a:after{border:5px inset;content:\"\";display:block;height:0;width:0;border-color:transparent transparent transparent rgba(255,255,255,.4);border-left-style:solid;margin-right:.9375rem;margin-top:-4.5px;position:absolute;top:50%;right:0}.top-bar-section .has-dropdown.moved{position:static}.top-bar-section .has-dropdown.moved>.dropdown{height:auto;overflow:visible;clip:auto;display:block;position:absolute!important;width:100%}.top-bar-section .has-dropdown.moved>a:after{display:none}.top-bar-section .dropdown{clip:rect(1px,1px,1px,1px);height:1px;overflow:hidden;position:absolute!important;width:1px;display:block;padding:0;top:0;z-index:99;left:100%}.top-bar-section .dropdown li{height:auto;width:100%}.top-bar-section .dropdown li a{font-weight:400;padding:8px .9375rem}.top-bar-section .dropdown li a.parent-link{font-weight:400}.top-bar-section .dropdown li.parent-link,.top-bar-section .dropdown li.title h5{margin-bottom:0;margin-top:0;font-size:1.125rem}.top-bar-section .dropdown li.parent-link a,.top-bar-section .dropdown li.title h5 a{color:#fff;display:block}.top-bar-section .dropdown li.parent-link a:hover,.top-bar-section .dropdown li.title h5 a:hover{background:0 0}.top-bar-section .dropdown li.has-form{padding:8px .9375rem}.top-bar-section .dropdown li .button,.top-bar-section .dropdown li button{top:auto}.top-bar-section .dropdown label{color:#777;font-size:.625rem;font-weight:700;padding:8px .9375rem 2px;text-transform:uppercase}.subheader,code,p{font-weight:400}.js-generated{display:block}@media only screen and (min-width:40.0625em){.top-bar,.top-bar.expanded{background:#333}.top-bar .title-area,.top-bar-section ul li{float:left}.top-bar{overflow:visible}.top-bar:after,.top-bar:before{content:\" \";display:table}.top-bar:after{clear:both}.top-bar .toggle-topbar{display:none}.top-bar .name h1 a,.top-bar .name h2 a,.top-bar .name h3 a,.top-bar .name h4 a,.top-bar .name h5 a,.top-bar .name h6 a{width:auto}.top-bar .button,.top-bar .has-form>.button,.top-bar .has-form>button,.top-bar button,.top-bar input,.top-bar select{font-size:.875rem;height:1.75rem;position:relative;top:.53125rem}.contain-to-grid .top-bar{margin:0 auto;max-width:62.5rem}.top-bar-section{transition:none 0 0;left:0!important}.top-bar-section ul{display:inline;height:auto!important;width:auto}.top-bar-section ul li .js-generated{display:none}.top-bar-section li.hover>a:not(.button){background:#222;color:#fff}.top-bar-section li:not(.has-form) a:not(.button){background:#333;line-height:2.8125rem;padding:0 .9375rem}.top-bar-section li:not(.has-form) a:not(.button):hover{background:#222}.top-bar-section li.active:not(.has-form) a:not(.button){background:#008CBA;color:#fff;line-height:2.8125rem;padding:0 .9375rem}.top-bar-section li.active:not(.has-form) a:not(.button):hover{background:#0078a0;color:#fff}.top-bar-section .has-dropdown>a{padding-right:2.1875rem!important}.top-bar-section .has-dropdown>a:after{border:5px inset;content:\"\";display:block;height:0;width:0;border-color:rgba(255,255,255,.4) transparent transparent;border-top-style:solid;margin-top:-2.5px;top:1.40625rem}.top-bar-section .has-dropdown.moved{position:relative}.top-bar-section .has-dropdown.moved>.dropdown{clip:rect(1px,1px,1px,1px);height:1px;overflow:hidden;position:absolute!important;width:1px;display:block}.top-bar-section .has-dropdown.hover>.dropdown,.top-bar-section .has-dropdown.not-click:hover>.dropdown,.top-bar-section .has-dropdown>a:focus+.dropdown{height:auto;width:auto;overflow:visible;clip:auto;display:block;position:absolute!important}.top-bar-section .has-dropdown .dropdown li.has-dropdown>a:after{border:none;content:\"\\00bb\";top:.1875rem;right:5px}.top-bar-section .dropdown{left:0;background:0 0;min-width:100%;top:auto}.top-bar-section .dropdown li a{background:#333;color:#fff;line-height:2.8125rem;padding:12px .9375rem;white-space:nowrap}.top-bar-section .dropdown li:not(.has-form):not(.active)>a:not(.button){background:#333;color:#fff}.top-bar-section .dropdown li:not(.has-form):not(.active):hover>a:not(.button){color:#fff;background:#222}.top-bar-section .dropdown li label{background:#333;white-space:nowrap}.top-bar-section .dropdown li .dropdown{left:100%;top:0}.top-bar-section>ul>.divider,.top-bar-section>ul>[role=separator]{border-right:solid 1px #4e4e4e;border-bottom:none;border-top:none;clear:none;height:2.8125rem;width:0}.top-bar-section .has-form{background:#333;height:2.8125rem;padding:0 .9375rem}.top-bar-section .right li .dropdown{left:auto;right:0}.top-bar-section .right li .dropdown li .dropdown{right:100%}.top-bar-section .left li .dropdown{right:auto;left:0}.top-bar-section .left li .dropdown li .dropdown{left:100%}.no-js .top-bar-section ul li:hover>a{background:#222;color:#fff}.no-js .top-bar-section ul li:active>a{background:#008CBA;color:#fff}.no-js .top-bar-section .has-dropdown:hover>.dropdown,.no-js .top-bar-section .has-dropdown>a:focus+.dropdown{height:auto;width:auto;overflow:visible;clip:auto;display:block;position:absolute!important}}.left-small,.right-small,.tab-bar-section{top:0;position:absolute}.inner-wrap:after,hr{clear:both}.inner-wrap,.off-canvas-wrap{width:100%;position:relative}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}.text-justify{text-align:justify!important}@media only screen and (max-width:40em){.small-only-text-left{text-align:left!important}.small-only-text-right{text-align:right!important}.small-only-text-center{text-align:center!important}.small-only-text-justify{text-align:justify!important}}@media only screen{.small-text-left{text-align:left!important}.small-text-right{text-align:right!important}.small-text-center{text-align:center!important}.small-text-justify{text-align:justify!important}}@media only screen and (min-width:40.0625em) and (max-width:64em){.medium-only-text-left{text-align:left!important}.medium-only-text-right{text-align:right!important}.medium-only-text-center{text-align:center!important}.medium-only-text-justify{text-align:justify!important}}@media only screen and (min-width:40.0625em){.medium-text-left{text-align:left!important}.medium-text-right{text-align:right!important}.medium-text-center{text-align:center!important}.medium-text-justify{text-align:justify!important}}@media only screen and (min-width:64.0625em) and (max-width:90em){.large-only-text-left{text-align:left!important}.large-only-text-right{text-align:right!important}.large-only-text-center{text-align:center!important}.large-only-text-justify{text-align:justify!important}}@media only screen and (min-width:64.0625em){.large-text-left{text-align:left!important}.large-text-right{text-align:right!important}.large-text-center{text-align:center!important}.large-text-justify{text-align:justify!important}}@media only screen and (min-width:90.0625em) and (max-width:120em){.xlarge-only-text-left{text-align:left!important}.xlarge-only-text-right{text-align:right!important}.xlarge-only-text-center{text-align:center!important}.xlarge-only-text-justify{text-align:justify!important}}@media only screen and (min-width:90.0625em){.xlarge-text-left{text-align:left!important}.xlarge-text-right{text-align:right!important}.xlarge-text-center{text-align:center!important}.xlarge-text-justify{text-align:justify!important}}@media only screen and (min-width:120.0625em) and (max-width:6249999.9375em){.xxlarge-only-text-left{text-align:left!important}.xxlarge-only-text-right{text-align:right!important}.xxlarge-only-text-center{text-align:center!important}.xxlarge-only-text-justify{text-align:justify!important}}@media only screen and (min-width:120.0625em){.xxlarge-text-left{text-align:left!important}.xxlarge-text-right{text-align:right!important}.xxlarge-text-center{text-align:center!important}.xxlarge-text-justify{text-align:justify!important}}blockquote,dd,div,dl,dt,form,h1,h2,h3,h4,h5,h6,li,ol,p,pre,td,th,ul{margin:0;padding:0}a{line-height:inherit}a:focus,a:hover{color:#0078a0}a img{border:none}p{margin-bottom:1.25rem}p.lead{font-size:1.21875rem;line-height:1.6}p aside{font-size:.875rem;font-style:italic;line-height:1.35}h1,h2,h3,h4,h5,h6{color:#222;font-style:normal;line-height:1.4}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{color:#6f6f6f;font-size:60%;line-height:0}h4,h5{font-size:1.125rem}h6{font-size:1rem}.subheader{line-height:1.4;color:#6f6f6f;margin-top:.2rem;margin-bottom:.5rem}b,em,i,small,strong{line-height:inherit}hr{box-sizing:content-box;border:solid #ddd;border-width:1px 0 0;height:0;margin:1.25rem 0 1.1875rem}em,i{font-style:italic}small{font-size:60%}code{background-color:#f8f8f8;border-color:#dfdfdf;border-style:solid;border-width:1px;color:#333;font-family:Consolas,\"Liberation Mono\",Courier,monospace;padding:.125rem .3125rem .0625rem}.vcard .fn,.vevent .summary,.vevent abbr,dl dt,ul.off-canvas-list li label{font-weight:700}dl,ol,ul{font-family:inherit;font-size:1rem;line-height:1.6;list-style-position:outside;margin-bottom:1.25rem}ul li ol,ul li ul{margin-left:1.25rem;margin-bottom:0}ul.circle,ul.disc,ul.square{margin-left:1.1rem}ul.circle li ul,ul.disc li ul,ul.square li ul{list-style:inherit}ul.square{list-style-type:square}ul.circle{list-style-type:circle}ul.disc{list-style-type:disc}.fa-ul,.no-bullet,ul.off-canvas-list{list-style-type:none}ol li ol,ol li ul{margin-left:1.25rem;margin-bottom:0}.no-bullet{margin-left:0}.no-bullet li ol,.no-bullet li ul{margin-left:1.25rem;margin-bottom:0;list-style:none}dl dt{margin-bottom:.3rem}dl dd{margin-bottom:.75rem}.vcard,blockquote{margin:0 0 1.25rem}abbr,acronym{text-transform:uppercase;font-size:90%;color:#222;cursor:help}abbr{text-transform:none}abbr[title]{border-bottom:1px dotted #ddd}blockquote{padding:.5625rem 1.25rem 0 1.1875rem;border-left:1px solid #ddd}blockquote cite{display:block;font-size:.8125rem;color:#555}blockquote cite:before{content:\"\\2014 \\0020\"}blockquote cite a,blockquote cite a:visited{color:#555}blockquote,blockquote p{line-height:1.6;color:#6f6f6f}.vcard{display:inline-block;border:1px solid #ddd;padding:.625rem .75rem}.vcard li{margin:0;display:block}.vcard .fn{font-size:.9375rem}.vevent abbr{cursor:default;border:none;padding:0 .0625rem}@media only screen and (min-width:40.0625em){h1,h2,h3,h4,h5,h6{line-height:1.4}h1{font-size:2.75rem}h2{font-size:2.3125rem}h3{font-size:1.6875rem}h4{font-size:1.4375rem}h5{font-size:1.125rem}h6{font-size:1rem}}@media print{blockquote,img,pre,tr{page-break-inside:avoid}*{background:0 0!important;color:#000!important;box-shadow:none!important;text-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:\" (\" attr(href) \")\"}abbr[title]:after{content:\" (\" attr(title) \")\"}.ir a:after,a[href^=\"javascript:\"]:after,a[href^=\"#\"]:after{content:\"\"}blockquote,pre{border:1px solid #999}thead{display:table-header-group}img{max-width:100%!important}@page{margin:.34in}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}}.off-canvas-wrap{-webkit-backface-visibility:hidden;overflow:hidden}.off-canvas-wrap.move-bottom,.off-canvas-wrap.move-left,.off-canvas-wrap.move-right,.off-canvas-wrap.move-top{min-height:100%;-webkit-overflow-scrolling:touch}.inner-wrap{transition:transform .5s ease}.left-small,.right-small,.tab-bar .menu-icon{height:2.8125rem;width:2.8125rem}.inner-wrap:after,.inner-wrap:before{content:\" \";display:table}.tab-bar{-webkit-backface-visibility:hidden;background:#333;color:#fff;height:2.8125rem;line-height:2.8125rem;position:relative}.tab-bar h1,.tab-bar h2,.tab-bar h3,.tab-bar h4,.tab-bar h5,.tab-bar h6{color:#fff;font-weight:700;line-height:2.8125rem;margin:0}.tab-bar h1,.tab-bar h2,.tab-bar h3,.tab-bar h4{font-size:1.125rem}.left-small{border-right:solid 1px #1a1a1a;left:0}.right-small{border-left:solid 1px #1a1a1a;right:0}.tab-bar-section{height:2.8125rem;padding:0 .625rem;text-align:center}.tab-bar-section.left{text-align:left;left:0;right:2.8125rem}.tab-bar-section.right{text-align:right;left:2.8125rem;right:0}.fa-fw,.fa-li{text-align:center}.tab-bar-section.middle{left:2.8125rem;right:2.8125rem}.tab-bar .menu-icon{color:#fff;display:block;padding:0;position:relative;text-indent:2.1875rem;transform:translate3d(0,0,0)}.tab-bar .menu-icon span::after{content:\"\";display:block;height:0;position:absolute;top:50%;margin-top:-.5rem;left:.90625rem;box-shadow:0 0 0 1px #fff,0 7px 0 1px #fff,0 14px 0 1px #fff;width:1rem}.left-off-canvas-menu,.right-off-canvas-menu{-webkit-backface-visibility:hidden;background:#333;box-sizing:content-box;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar;overflow-x:hidden;overflow-y:auto;position:absolute;transition:transform .5s ease 0s;width:15.625rem;bottom:0;top:0}.tab-bar .menu-icon span:hover:after{box-shadow:0 0 0 1px #b3b3b3,0 7px 0 1px #b3b3b3,0 14px 0 1px #b3b3b3}.left-off-canvas-menu{z-index:1001;transform:translate3d(-100%,0,0);left:0}.left-off-canvas-menu *{-webkit-backface-visibility:hidden}.right-off-canvas-menu{z-index:1001;transform:translate3d(100%,0,0);right:0}.bottom-off-canvas-menu,.top-off-canvas-menu{-webkit-backface-visibility:hidden;background:#333;box-sizing:content-box;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar;overflow-x:hidden;overflow-y:auto;position:absolute;transition:transform .5s ease 0s;z-index:1001;width:100%;height:18.75rem}.right-off-canvas-menu *{-webkit-backface-visibility:hidden}.top-off-canvas-menu{bottom:0;transform:translate3d(0,-100%,0);top:0}.top-off-canvas-menu *{-webkit-backface-visibility:hidden}.bottom-off-canvas-menu{transform:translate3d(0,100%,0);bottom:0}.move-bottom .exit-off-canvas,.move-left .exit-off-canvas,.move-right .exit-off-canvas,.move-top .exit-off-canvas{z-index:1002;-webkit-backface-visibility:hidden;box-shadow:-4px 0 4px rgba(0,0,0,.5),4px 0 4px rgba(0,0,0,.5);transition:background .3s ease;-webkit-tap-highlight-color:transparent;bottom:0;display:block;left:0;position:absolute;right:0;top:0;cursor:pointer}.bottom-off-canvas-menu *{-webkit-backface-visibility:hidden}ul.off-canvas-list{margin:0;padding:0}ul.off-canvas-list li label{background:#444;border-bottom:none;border-top:1px solid #5e5e5e;color:#999;display:block;font-size:.75rem;margin:0;padding:.3rem .9375rem;text-transform:uppercase}ul.off-canvas-list li a{border-bottom:1px solid #262626;color:rgba(255,255,255,.7);display:block;padding:.66667rem;transition:background .3s ease}.bottom-submenu .back>a,.left-submenu .back>a,.right-submenu .back>a,.top-submenu .back>a{color:#999;font-weight:700;padding:.3rem .9375rem;border-bottom:none;border-top:1px solid #5e5e5e;text-transform:uppercase}ul.off-canvas-list li a:active,ul.off-canvas-list li a:hover{background:#242424}.move-right>.inner-wrap{transform:translate3d(15.625rem,0,0)}.move-right .exit-off-canvas{background:rgba(255,255,255,.2)}@media only screen and (min-width:40.0625em){.move-right .exit-off-canvas:hover{background:rgba(255,255,255,.05)}}.move-left>.inner-wrap{transform:translate3d(-15.625rem,0,0)}.move-left .exit-off-canvas{background:rgba(255,255,255,.2)}@media only screen and (min-width:40.0625em){.move-left .exit-off-canvas:hover{background:rgba(255,255,255,.05)}}.move-top>.inner-wrap{transform:translate3d(0,-18.75rem,0)}.move-top .exit-off-canvas{background:rgba(255,255,255,.2)}@media only screen and (min-width:40.0625em){.move-top .exit-off-canvas:hover{background:rgba(255,255,255,.05)}}.move-bottom>.inner-wrap{transform:translate3d(0,18.75rem,0)}.move-bottom .exit-off-canvas{background:rgba(255,255,255,.2)}@media only screen and (min-width:40.0625em){.move-bottom .exit-off-canvas:hover{background:rgba(255,255,255,.05)}}.offcanvas-overlap .bottom-off-canvas-menu,.offcanvas-overlap .left-off-canvas-menu,.offcanvas-overlap .right-off-canvas-menu,.offcanvas-overlap .top-off-canvas-menu{transform:none;z-index:1003}.offcanvas-overlap .exit-off-canvas{-webkit-backface-visibility:hidden;box-shadow:-4px 0 4px rgba(0,0,0,.5),4px 0 4px rgba(0,0,0,.5);cursor:pointer;transition:background .3s ease;-webkit-tap-highlight-color:transparent;background:rgba(255,255,255,.2);bottom:0;display:block;left:0;position:absolute;right:0;top:0;z-index:1002}@media only screen and (min-width:40.0625em){.offcanvas-overlap .exit-off-canvas:hover{background:rgba(255,255,255,.05)}}.offcanvas-overlap-left .right-off-canvas-menu{transform:none;z-index:1003}.offcanvas-overlap-left .exit-off-canvas{-webkit-backface-visibility:hidden;box-shadow:-4px 0 4px rgba(0,0,0,.5),4px 0 4px rgba(0,0,0,.5);cursor:pointer;transition:background .3s ease;-webkit-tap-highlight-color:transparent;background:rgba(255,255,255,.2);bottom:0;display:block;left:0;position:absolute;right:0;top:0;z-index:1002}@media only screen and (min-width:40.0625em){.offcanvas-overlap-left .exit-off-canvas:hover{background:rgba(255,255,255,.05)}}.offcanvas-overlap-right .left-off-canvas-menu{transform:none;z-index:1003}.offcanvas-overlap-right .exit-off-canvas{-webkit-backface-visibility:hidden;box-shadow:-4px 0 4px rgba(0,0,0,.5),4px 0 4px rgba(0,0,0,.5);cursor:pointer;transition:background .3s ease;-webkit-tap-highlight-color:transparent;background:rgba(255,255,255,.2);bottom:0;display:block;left:0;position:absolute;right:0;top:0;z-index:1002}@media only screen and (min-width:40.0625em){.offcanvas-overlap-right .exit-off-canvas:hover{background:rgba(255,255,255,.05)}}.offcanvas-overlap-top .bottom-off-canvas-menu{transform:none;z-index:1003}.offcanvas-overlap-top .exit-off-canvas{-webkit-backface-visibility:hidden;box-shadow:-4px 0 4px rgba(0,0,0,.5),4px 0 4px rgba(0,0,0,.5);cursor:pointer;transition:background .3s ease;-webkit-tap-highlight-color:transparent;background:rgba(255,255,255,.2);bottom:0;display:block;left:0;position:absolute;right:0;top:0;z-index:1002}@media only screen and (min-width:40.0625em){.offcanvas-overlap-top .exit-off-canvas:hover{background:rgba(255,255,255,.05)}}.offcanvas-overlap-bottom .top-off-canvas-menu{transform:none;z-index:1003}.offcanvas-overlap-bottom .exit-off-canvas{-webkit-backface-visibility:hidden;box-shadow:-4px 0 4px rgba(0,0,0,.5),4px 0 4px rgba(0,0,0,.5);cursor:pointer;transition:background .3s ease;-webkit-tap-highlight-color:transparent;background:rgba(255,255,255,.2);bottom:0;display:block;left:0;position:absolute;right:0;top:0;z-index:1002}@media only screen and (min-width:40.0625em){.offcanvas-overlap-bottom .exit-off-canvas:hover{background:rgba(255,255,255,.05)}}.no-csstransforms .left-off-canvas-menu{left:-15.625rem}.no-csstransforms .right-off-canvas-menu{right:-15.625rem}.no-csstransforms .top-off-canvas-menu{top:-18.75rem}.no-csstransforms .bottom-off-canvas-menu{bottom:-18.75rem}.left-submenu,.right-submenu{-webkit-backface-visibility:hidden;-webkit-overflow-scrolling:touch;bottom:0;box-sizing:content-box;overflow-x:hidden;overflow-y:auto;position:absolute;top:0;width:15.625rem}.no-csstransforms .move-left>.inner-wrap{right:15.625rem}.no-csstransforms .move-right>.inner-wrap{left:15.625rem}.no-csstransforms .move-top>.inner-wrap{right:18.75rem}.no-csstransforms .move-bottom>.inner-wrap{left:18.75rem}.left-submenu{background:#333;margin:0;height:18.75rem;z-index:1002;transform:translate3d(-100%,0,0);left:0;transition:transform .5s ease}.left-submenu *{-webkit-backface-visibility:hidden}.left-submenu .back>a{background:#444;margin:0}.left-submenu .back>a:hover{background:#303030;border-bottom:none;border-top:1px solid #5e5e5e}.left-submenu .back>a:before{content:\"\\AB\";margin-right:.5rem;display:inline}.left-submenu.move-right,.left-submenu.offcanvas-overlap,.left-submenu.offcanvas-overlap-right{transform:translate3d(0,0,0)}.right-submenu{background:#333;margin:0;height:18.75rem;z-index:1002;transform:translate3d(100%,0,0);right:0;transition:transform .5s ease}.bottom-submenu,.top-submenu{-webkit-overflow-scrolling:touch;box-sizing:content-box;overflow-x:hidden;overflow-y:auto;position:absolute;top:0;height:18.75rem;z-index:1002;bottom:0;width:100%;transition:transform .5s ease;-webkit-backface-visibility:hidden}.right-submenu *{-webkit-backface-visibility:hidden}.right-submenu .back>a{background:#444;margin:0}.right-submenu .back>a:hover{background:#303030;border-bottom:none;border-top:1px solid #5e5e5e}.right-submenu .back>a:after{content:\"\\BB\";margin-left:.5rem;display:inline}.right-submenu.move-left,.right-submenu.offcanvas-overlap,.right-submenu.offcanvas-overlap-left{transform:translate3d(0,0,0)}.top-submenu{background:#333;margin:0;transform:translate3d(0,-100%,0)}.top-submenu *{-webkit-backface-visibility:hidden}.top-submenu .back>a{background:#444;margin:0}.top-submenu .back>a:hover{background:#303030;border-bottom:none;border-top:1px solid #5e5e5e}.top-submenu.move-bottom,.top-submenu.offcanvas-overlap,.top-submenu.offcanvas-overlap-bottom{transform:translate3d(0,0,0)}.bottom-submenu{background:#333;margin:0;transform:translate3d(0,100%,0)}.container-full,.sidebar{box-sizing:border-box;height:100%}.sidebar a,.sidebar a .ripple span{transition:all .3s ease-in-out}.bottom-submenu *{-webkit-backface-visibility:hidden}.bottom-submenu .back>a{background:#444;margin:0}.bottom-submenu .back>a:hover{background:#303030;border-bottom:none;border-top:1px solid #5e5e5e}.bottom-submenu.move-top,.bottom-submenu.offcanvas-overlap,.bottom-submenu.offcanvas-overlap-top{transform:translate3d(0,0,0)}.left-off-canvas-menu ul.off-canvas-list li.has-submenu>a:after{content:\"\\BB\";margin-left:.5rem;display:inline}.right-off-canvas-menu ul.off-canvas-list li.has-submenu>a:before{content:\"\\AB\";margin-right:.5rem;display:inline}.fa.fa-pull-left,.fa.pull-left{margin-right:.3em}@media only screen{.hide-for-large,.hide-for-large-only,.hide-for-large-up,.hide-for-medium,.hide-for-medium-only,.hide-for-medium-up,.hide-for-xlarge,.hide-for-xlarge-only,.hide-for-xlarge-up,.hide-for-xxlarge,.hide-for-xxlarge-only,.hide-for-xxlarge-up,.show-for-large-down,.show-for-medium-down,.show-for-small,.show-for-small-down,.show-for-small-only,.show-for-small-up,.show-for-xlarge-down,.show-for-xxlarge-down{display:inherit!important}.hide-for-large-down,.hide-for-medium-down,.hide-for-small,.hide-for-small-down,.hide-for-small-only,.hide-for-small-up,.hide-for-xlarge-down,.hide-for-xxlarge-down,.show-for-large,.show-for-large-only,.show-for-large-up,.show-for-medium,.show-for-medium-only,.show-for-medium-up,.show-for-xlarge,.show-for-xlarge-only,.show-for-xlarge-up,.show-for-xxlarge,.show-for-xxlarge-only,.show-for-xxlarge-up{display:none!important}.hidden-for-large,.hidden-for-large-only,.hidden-for-large-up,.hidden-for-medium,.hidden-for-medium-only,.hidden-for-medium-up,.hidden-for-xlarge,.hidden-for-xlarge-only,.hidden-for-xlarge-up,.hidden-for-xxlarge,.hidden-for-xxlarge-only,.hidden-for-xxlarge-up,.visible-for-large-down,.visible-for-medium-down,.visible-for-small,.visible-for-small-down,.visible-for-small-only,.visible-for-small-up,.visible-for-xlarge-down,.visible-for-xxlarge-down{position:static!important;height:auto;width:auto;overflow:visible;clip:auto}.hidden-for-large-down,.hidden-for-medium-down,.hidden-for-small,.hidden-for-small-down,.hidden-for-small-only,.hidden-for-small-up,.hidden-for-xlarge-down,.hidden-for-xxlarge-down,.visible-for-large,.visible-for-large-only,.visible-for-large-up,.visible-for-medium,.visible-for-medium-only,.visible-for-medium-up,.visible-for-xlarge,.visible-for-xlarge-only,.visible-for-xlarge-up,.visible-for-xxlarge,.visible-for-xxlarge-only,.visible-for-xxlarge-up{clip:rect(1px,1px,1px,1px);height:1px;overflow:hidden;position:absolute!important;width:1px}table.hide-for-large,table.hide-for-large-only,table.hide-for-large-up,table.hide-for-medium,table.hide-for-medium-only,table.hide-for-medium-up,table.hide-for-xlarge,table.hide-for-xlarge-only,table.hide-for-xlarge-up,table.hide-for-xxlarge,table.hide-for-xxlarge-only,table.hide-for-xxlarge-up,table.show-for-large-down,table.show-for-medium-down,table.show-for-small,table.show-for-small-down,table.show-for-small-only,table.show-for-small-up,table.show-for-xlarge-down,table.show-for-xxlarge-down{display:table!important}thead.hide-for-large,thead.hide-for-large-only,thead.hide-for-large-up,thead.hide-for-medium,thead.hide-for-medium-only,thead.hide-for-medium-up,thead.hide-for-xlarge,thead.hide-for-xlarge-only,thead.hide-for-xlarge-up,thead.hide-for-xxlarge,thead.hide-for-xxlarge-only,thead.hide-for-xxlarge-up,thead.show-for-large-down,thead.show-for-medium-down,thead.show-for-small,thead.show-for-small-down,thead.show-for-small-only,thead.show-for-small-up,thead.show-for-xlarge-down,thead.show-for-xxlarge-down{display:table-header-group!important}tbody.hide-for-large,tbody.hide-for-large-only,tbody.hide-for-large-up,tbody.hide-for-medium,tbody.hide-for-medium-only,tbody.hide-for-medium-up,tbody.hide-for-xlarge,tbody.hide-for-xlarge-only,tbody.hide-for-xlarge-up,tbody.hide-for-xxlarge,tbody.hide-for-xxlarge-only,tbody.hide-for-xxlarge-up,tbody.show-for-large-down,tbody.show-for-medium-down,tbody.show-for-small,tbody.show-for-small-down,tbody.show-for-small-only,tbody.show-for-small-up,tbody.show-for-xlarge-down,tbody.show-for-xxlarge-down{display:table-row-group!important}tr.hide-for-large,tr.hide-for-large-only,tr.hide-for-large-up,tr.hide-for-medium,tr.hide-for-medium-only,tr.hide-for-medium-up,tr.hide-for-xlarge,tr.hide-for-xlarge-only,tr.hide-for-xlarge-up,tr.hide-for-xxlarge,tr.hide-for-xxlarge-only,tr.hide-for-xxlarge-up,tr.show-for-large-down,tr.show-for-medium-down,tr.show-for-small,tr.show-for-small-down,tr.show-for-small-only,tr.show-for-small-up,tr.show-for-xlarge-down,tr.show-for-xxlarge-down{display:table-row}td.hide-for-large,td.hide-for-large-only,td.hide-for-large-up,td.hide-for-medium,td.hide-for-medium-only,td.hide-for-medium-up,td.hide-for-xlarge,td.hide-for-xlarge-only,td.hide-for-xlarge-up,td.hide-for-xxlarge,td.hide-for-xxlarge-only,td.hide-for-xxlarge-up,td.show-for-large-down,td.show-for-medium-down,td.show-for-small,td.show-for-small-down,td.show-for-small-only,td.show-for-small-up,td.show-for-xlarge-down,td.show-for-xxlarge-down,th.hide-for-large,th.hide-for-large-only,th.hide-for-large-up,th.hide-for-medium,th.hide-for-medium-only,th.hide-for-medium-up,th.hide-for-xlarge,th.hide-for-xlarge-only,th.hide-for-xlarge-up,th.hide-for-xxlarge,th.hide-for-xxlarge-only,th.hide-for-xxlarge-up,th.show-for-large-down,th.show-for-medium-down,th.show-for-small,th.show-for-small-down,th.show-for-small-only,th.show-for-small-up,th.show-for-xlarge-down,th.show-for-xxlarge-down{display:table-cell!important}}@media only screen and (min-width:40.0625em){.hide-for-large,.hide-for-large-only,.hide-for-large-up,.hide-for-small,.hide-for-small-down,.hide-for-small-only,.hide-for-xlarge,.hide-for-xlarge-only,.hide-for-xlarge-up,.hide-for-xxlarge,.hide-for-xxlarge-only,.hide-for-xxlarge-up,.show-for-large-down,.show-for-medium,.show-for-medium-down,.show-for-medium-only,.show-for-medium-up,.show-for-small-up,.show-for-xlarge-down,.show-for-xxlarge-down{display:inherit!important}.hide-for-large-down,.hide-for-medium,.hide-for-medium-down,.hide-for-medium-only,.hide-for-medium-up,.hide-for-small-up,.hide-for-xlarge-down,.hide-for-xxlarge-down,.show-for-large,.show-for-large-only,.show-for-large-up,.show-for-small,.show-for-small-down,.show-for-small-only,.show-for-xlarge,.show-for-xlarge-only,.show-for-xlarge-up,.show-for-xxlarge,.show-for-xxlarge-only,.show-for-xxlarge-up{display:none!important}.hidden-for-large,.hidden-for-large-only,.hidden-for-large-up,.hidden-for-small,.hidden-for-small-down,.hidden-for-small-only,.hidden-for-xlarge,.hidden-for-xlarge-only,.hidden-for-xlarge-up,.hidden-for-xxlarge,.hidden-for-xxlarge-only,.hidden-for-xxlarge-up,.visible-for-large-down,.visible-for-medium,.visible-for-medium-down,.visible-for-medium-only,.visible-for-medium-up,.visible-for-small-up,.visible-for-xlarge-down,.visible-for-xxlarge-down{position:static!important;height:auto;width:auto;overflow:visible;clip:auto}.hidden-for-large-down,.hidden-for-medium,.hidden-for-medium-down,.hidden-for-medium-only,.hidden-for-medium-up,.hidden-for-small-up,.hidden-for-xlarge-down,.hidden-for-xxlarge-down,.visible-for-large,.visible-for-large-only,.visible-for-large-up,.visible-for-small,.visible-for-small-down,.visible-for-small-only,.visible-for-xlarge,.visible-for-xlarge-only,.visible-for-xlarge-up,.visible-for-xxlarge,.visible-for-xxlarge-only,.visible-for-xxlarge-up{clip:rect(1px,1px,1px,1px);height:1px;overflow:hidden;position:absolute!important;width:1px}table.hide-for-large,table.hide-for-large-only,table.hide-for-large-up,table.hide-for-small,table.hide-for-small-down,table.hide-for-small-only,table.hide-for-xlarge,table.hide-for-xlarge-only,table.hide-for-xlarge-up,table.hide-for-xxlarge,table.hide-for-xxlarge-only,table.hide-for-xxlarge-up,table.show-for-large-down,table.show-for-medium,table.show-for-medium-down,table.show-for-medium-only,table.show-for-medium-up,table.show-for-small-up,table.show-for-xlarge-down,table.show-for-xxlarge-down{display:table!important}thead.hide-for-large,thead.hide-for-large-only,thead.hide-for-large-up,thead.hide-for-small,thead.hide-for-small-down,thead.hide-for-small-only,thead.hide-for-xlarge,thead.hide-for-xlarge-only,thead.hide-for-xlarge-up,thead.hide-for-xxlarge,thead.hide-for-xxlarge-only,thead.hide-for-xxlarge-up,thead.show-for-large-down,thead.show-for-medium,thead.show-for-medium-down,thead.show-for-medium-only,thead.show-for-medium-up,thead.show-for-small-up,thead.show-for-xlarge-down,thead.show-for-xxlarge-down{display:table-header-group!important}tbody.hide-for-large,tbody.hide-for-large-only,tbody.hide-for-large-up,tbody.hide-for-small,tbody.hide-for-small-down,tbody.hide-for-small-only,tbody.hide-for-xlarge,tbody.hide-for-xlarge-only,tbody.hide-for-xlarge-up,tbody.hide-for-xxlarge,tbody.hide-for-xxlarge-only,tbody.hide-for-xxlarge-up,tbody.show-for-large-down,tbody.show-for-medium,tbody.show-for-medium-down,tbody.show-for-medium-only,tbody.show-for-medium-up,tbody.show-for-small-up,tbody.show-for-xlarge-down,tbody.show-for-xxlarge-down{display:table-row-group!important}tr.hide-for-large,tr.hide-for-large-only,tr.hide-for-large-up,tr.hide-for-small,tr.hide-for-small-down,tr.hide-for-small-only,tr.hide-for-xlarge,tr.hide-for-xlarge-only,tr.hide-for-xlarge-up,tr.hide-for-xxlarge,tr.hide-for-xxlarge-only,tr.hide-for-xxlarge-up,tr.show-for-large-down,tr.show-for-medium,tr.show-for-medium-down,tr.show-for-medium-only,tr.show-for-medium-up,tr.show-for-small-up,tr.show-for-xlarge-down,tr.show-for-xxlarge-down{display:table-row}td.hide-for-large,td.hide-for-large-only,td.hide-for-large-up,td.hide-for-small,td.hide-for-small-down,td.hide-for-small-only,td.hide-for-xlarge,td.hide-for-xlarge-only,td.hide-for-xlarge-up,td.hide-for-xxlarge,td.hide-for-xxlarge-only,td.hide-for-xxlarge-up,td.show-for-large-down,td.show-for-medium,td.show-for-medium-down,td.show-for-medium-only,td.show-for-medium-up,td.show-for-small-up,td.show-for-xlarge-down,td.show-for-xxlarge-down,th.hide-for-large,th.hide-for-large-only,th.hide-for-large-up,th.hide-for-small,th.hide-for-small-down,th.hide-for-small-only,th.hide-for-xlarge,th.hide-for-xlarge-only,th.hide-for-xlarge-up,th.hide-for-xxlarge,th.hide-for-xxlarge-only,th.hide-for-xxlarge-up,th.show-for-large-down,th.show-for-medium,th.show-for-medium-down,th.show-for-medium-only,th.show-for-medium-up,th.show-for-small-up,th.show-for-xlarge-down,th.show-for-xxlarge-down{display:table-cell!important}}@media only screen and (min-width:64.0625em){.hide-for-medium,.hide-for-medium-down,.hide-for-medium-only,.hide-for-small,.hide-for-small-down,.hide-for-small-only,.hide-for-xlarge,.hide-for-xlarge-only,.hide-for-xlarge-up,.hide-for-xxlarge,.hide-for-xxlarge-only,.hide-for-xxlarge-up,.show-for-large,.show-for-large-down,.show-for-large-only,.show-for-large-up,.show-for-medium-up,.show-for-small-up,.show-for-xlarge-down,.show-for-xxlarge-down{display:inherit!important}.hide-for-large,.hide-for-large-down,.hide-for-large-only,.hide-for-large-up,.hide-for-medium-up,.hide-for-small-up,.hide-for-xlarge-down,.hide-for-xxlarge-down,.show-for-medium,.show-for-medium-down,.show-for-medium-only,.show-for-small,.show-for-small-down,.show-for-small-only,.show-for-xlarge,.show-for-xlarge-only,.show-for-xlarge-up,.show-for-xxlarge,.show-for-xxlarge-only,.show-for-xxlarge-up{display:none!important}.hidden-for-medium,.hidden-for-medium-down,.hidden-for-medium-only,.hidden-for-small,.hidden-for-small-down,.hidden-for-small-only,.hidden-for-xlarge,.hidden-for-xlarge-only,.hidden-for-xlarge-up,.hidden-for-xxlarge,.hidden-for-xxlarge-only,.hidden-for-xxlarge-up,.visible-for-large,.visible-for-large-down,.visible-for-large-only,.visible-for-large-up,.visible-for-medium-up,.visible-for-small-up,.visible-for-xlarge-down,.visible-for-xxlarge-down{position:static!important;height:auto;width:auto;overflow:visible;clip:auto}.hidden-for-large,.hidden-for-large-down,.hidden-for-large-only,.hidden-for-large-up,.hidden-for-medium-up,.hidden-for-small-up,.hidden-for-xlarge-down,.hidden-for-xxlarge-down,.visible-for-medium,.visible-for-medium-down,.visible-for-medium-only,.visible-for-small,.visible-for-small-down,.visible-for-small-only,.visible-for-xlarge,.visible-for-xlarge-only,.visible-for-xlarge-up,.visible-for-xxlarge,.visible-for-xxlarge-only,.visible-for-xxlarge-up{clip:rect(1px,1px,1px,1px);height:1px;overflow:hidden;position:absolute!important;width:1px}table.hide-for-medium,table.hide-for-medium-down,table.hide-for-medium-only,table.hide-for-small,table.hide-for-small-down,table.hide-for-small-only,table.hide-for-xlarge,table.hide-for-xlarge-only,table.hide-for-xlarge-up,table.hide-for-xxlarge,table.hide-for-xxlarge-only,table.hide-for-xxlarge-up,table.show-for-large,table.show-for-large-down,table.show-for-large-only,table.show-for-large-up,table.show-for-medium-up,table.show-for-small-up,table.show-for-xlarge-down,table.show-for-xxlarge-down{display:table!important}thead.hide-for-medium,thead.hide-for-medium-down,thead.hide-for-medium-only,thead.hide-for-small,thead.hide-for-small-down,thead.hide-for-small-only,thead.hide-for-xlarge,thead.hide-for-xlarge-only,thead.hide-for-xlarge-up,thead.hide-for-xxlarge,thead.hide-for-xxlarge-only,thead.hide-for-xxlarge-up,thead.show-for-large,thead.show-for-large-down,thead.show-for-large-only,thead.show-for-large-up,thead.show-for-medium-up,thead.show-for-small-up,thead.show-for-xlarge-down,thead.show-for-xxlarge-down{display:table-header-group!important}tbody.hide-for-medium,tbody.hide-for-medium-down,tbody.hide-for-medium-only,tbody.hide-for-small,tbody.hide-for-small-down,tbody.hide-for-small-only,tbody.hide-for-xlarge,tbody.hide-for-xlarge-only,tbody.hide-for-xlarge-up,tbody.hide-for-xxlarge,tbody.hide-for-xxlarge-only,tbody.hide-for-xxlarge-up,tbody.show-for-large,tbody.show-for-large-down,tbody.show-for-large-only,tbody.show-for-large-up,tbody.show-for-medium-up,tbody.show-for-small-up,tbody.show-for-xlarge-down,tbody.show-for-xxlarge-down{display:table-row-group!important}tr.hide-for-medium,tr.hide-for-medium-down,tr.hide-for-medium-only,tr.hide-for-small,tr.hide-for-small-down,tr.hide-for-small-only,tr.hide-for-xlarge,tr.hide-for-xlarge-only,tr.hide-for-xlarge-up,tr.hide-for-xxlarge,tr.hide-for-xxlarge-only,tr.hide-for-xxlarge-up,tr.show-for-large,tr.show-for-large-down,tr.show-for-large-only,tr.show-for-large-up,tr.show-for-medium-up,tr.show-for-small-up,tr.show-for-xlarge-down,tr.show-for-xxlarge-down{display:table-row}td.hide-for-medium,td.hide-for-medium-down,td.hide-for-medium-only,td.hide-for-small,td.hide-for-small-down,td.hide-for-small-only,td.hide-for-xlarge,td.hide-for-xlarge-only,td.hide-for-xlarge-up,td.hide-for-xxlarge,td.hide-for-xxlarge-only,td.hide-for-xxlarge-up,td.show-for-large,td.show-for-large-down,td.show-for-large-only,td.show-for-large-up,td.show-for-medium-up,td.show-for-small-up,td.show-for-xlarge-down,td.show-for-xxlarge-down,th.hide-for-medium,th.hide-for-medium-down,th.hide-for-medium-only,th.hide-for-small,th.hide-for-small-down,th.hide-for-small-only,th.hide-for-xlarge,th.hide-for-xlarge-only,th.hide-for-xlarge-up,th.hide-for-xxlarge,th.hide-for-xxlarge-only,th.hide-for-xxlarge-up,th.show-for-large,th.show-for-large-down,th.show-for-large-only,th.show-for-large-up,th.show-for-medium-up,th.show-for-small-up,th.show-for-xlarge-down,th.show-for-xxlarge-down{display:table-cell!important}}@media only screen and (min-width:90.0625em){.hide-for-large,.hide-for-large-down,.hide-for-large-only,.hide-for-medium,.hide-for-medium-down,.hide-for-medium-only,.hide-for-small,.hide-for-small-down,.hide-for-small-only,.hide-for-xxlarge,.hide-for-xxlarge-only,.hide-for-xxlarge-up,.show-for-large-up,.show-for-medium-up,.show-for-small-up,.show-for-xlarge,.show-for-xlarge-down,.show-for-xlarge-only,.show-for-xlarge-up,.show-for-xxlarge-down{display:inherit!important}.hide-for-large-up,.hide-for-medium-up,.hide-for-small-up,.hide-for-xlarge,.hide-for-xlarge-down,.hide-for-xlarge-only,.hide-for-xlarge-up,.hide-for-xxlarge-down,.show-for-large,.show-for-large-down,.show-for-large-only,.show-for-medium,.show-for-medium-down,.show-for-medium-only,.show-for-small,.show-for-small-down,.show-for-small-only,.show-for-xxlarge,.show-for-xxlarge-only,.show-for-xxlarge-up{display:none!important}.hidden-for-large,.hidden-for-large-down,.hidden-for-large-only,.hidden-for-medium,.hidden-for-medium-down,.hidden-for-medium-only,.hidden-for-small,.hidden-for-small-down,.hidden-for-small-only,.hidden-for-xxlarge,.hidden-for-xxlarge-only,.hidden-for-xxlarge-up,.visible-for-large-up,.visible-for-medium-up,.visible-for-small-up,.visible-for-xlarge,.visible-for-xlarge-down,.visible-for-xlarge-only,.visible-for-xlarge-up,.visible-for-xxlarge-down{position:static!important;height:auto;width:auto;overflow:visible;clip:auto}.hidden-for-large-up,.hidden-for-medium-up,.hidden-for-small-up,.hidden-for-xlarge,.hidden-for-xlarge-down,.hidden-for-xlarge-only,.hidden-for-xlarge-up,.hidden-for-xxlarge-down,.visible-for-large,.visible-for-large-down,.visible-for-large-only,.visible-for-medium,.visible-for-medium-down,.visible-for-medium-only,.visible-for-small,.visible-for-small-down,.visible-for-small-only,.visible-for-xxlarge,.visible-for-xxlarge-only,.visible-for-xxlarge-up{clip:rect(1px,1px,1px,1px);height:1px;overflow:hidden;position:absolute!important;width:1px}table.hide-for-large,table.hide-for-large-down,table.hide-for-large-only,table.hide-for-medium,table.hide-for-medium-down,table.hide-for-medium-only,table.hide-for-small,table.hide-for-small-down,table.hide-for-small-only,table.hide-for-xxlarge,table.hide-for-xxlarge-only,table.hide-for-xxlarge-up,table.show-for-large-up,table.show-for-medium-up,table.show-for-small-up,table.show-for-xlarge,table.show-for-xlarge-down,table.show-for-xlarge-only,table.show-for-xlarge-up,table.show-for-xxlarge-down{display:table!important}thead.hide-for-large,thead.hide-for-large-down,thead.hide-for-large-only,thead.hide-for-medium,thead.hide-for-medium-down,thead.hide-for-medium-only,thead.hide-for-small,thead.hide-for-small-down,thead.hide-for-small-only,thead.hide-for-xxlarge,thead.hide-for-xxlarge-only,thead.hide-for-xxlarge-up,thead.show-for-large-up,thead.show-for-medium-up,thead.show-for-small-up,thead.show-for-xlarge,thead.show-for-xlarge-down,thead.show-for-xlarge-only,thead.show-for-xlarge-up,thead.show-for-xxlarge-down{display:table-header-group!important}tbody.hide-for-large,tbody.hide-for-large-down,tbody.hide-for-large-only,tbody.hide-for-medium,tbody.hide-for-medium-down,tbody.hide-for-medium-only,tbody.hide-for-small,tbody.hide-for-small-down,tbody.hide-for-small-only,tbody.hide-for-xxlarge,tbody.hide-for-xxlarge-only,tbody.hide-for-xxlarge-up,tbody.show-for-large-up,tbody.show-for-medium-up,tbody.show-for-small-up,tbody.show-for-xlarge,tbody.show-for-xlarge-down,tbody.show-for-xlarge-only,tbody.show-for-xlarge-up,tbody.show-for-xxlarge-down{display:table-row-group!important}tr.hide-for-large,tr.hide-for-large-down,tr.hide-for-large-only,tr.hide-for-medium,tr.hide-for-medium-down,tr.hide-for-medium-only,tr.hide-for-small,tr.hide-for-small-down,tr.hide-for-small-only,tr.hide-for-xxlarge,tr.hide-for-xxlarge-only,tr.hide-for-xxlarge-up,tr.show-for-large-up,tr.show-for-medium-up,tr.show-for-small-up,tr.show-for-xlarge,tr.show-for-xlarge-down,tr.show-for-xlarge-only,tr.show-for-xlarge-up,tr.show-for-xxlarge-down{display:table-row}td.hide-for-large,td.hide-for-large-down,td.hide-for-large-only,td.hide-for-medium,td.hide-for-medium-down,td.hide-for-medium-only,td.hide-for-small,td.hide-for-small-down,td.hide-for-small-only,td.hide-for-xxlarge,td.hide-for-xxlarge-only,td.hide-for-xxlarge-up,td.show-for-large-up,td.show-for-medium-up,td.show-for-small-up,td.show-for-xlarge,td.show-for-xlarge-down,td.show-for-xlarge-only,td.show-for-xlarge-up,td.show-for-xxlarge-down,th.hide-for-large,th.hide-for-large-down,th.hide-for-large-only,th.hide-for-medium,th.hide-for-medium-down,th.hide-for-medium-only,th.hide-for-small,th.hide-for-small-down,th.hide-for-small-only,th.hide-for-xxlarge,th.hide-for-xxlarge-only,th.hide-for-xxlarge-up,th.show-for-large-up,th.show-for-medium-up,th.show-for-small-up,th.show-for-xlarge,th.show-for-xlarge-down,th.show-for-xlarge-only,th.show-for-xlarge-up,th.show-for-xxlarge-down{display:table-cell!important}}@media only screen and (min-width:120.0625em){.hide-for-large,.hide-for-large-down,.hide-for-large-only,.hide-for-medium,.hide-for-medium-down,.hide-for-medium-only,.hide-for-small,.hide-for-small-down,.hide-for-small-only,.hide-for-xlarge,.hide-for-xlarge-down,.hide-for-xlarge-only,.show-for-large-up,.show-for-medium-up,.show-for-small-up,.show-for-xlarge-up,.show-for-xxlarge,.show-for-xxlarge-down,.show-for-xxlarge-only,.show-for-xxlarge-up{display:inherit!important}.hide-for-large-up,.hide-for-medium-up,.hide-for-small-up,.hide-for-xlarge-up,.hide-for-xxlarge,.hide-for-xxlarge-down,.hide-for-xxlarge-only,.hide-for-xxlarge-up,.show-for-large,.show-for-large-down,.show-for-large-only,.show-for-medium,.show-for-medium-down,.show-for-medium-only,.show-for-small,.show-for-small-down,.show-for-small-only,.show-for-xlarge,.show-for-xlarge-down,.show-for-xlarge-only{display:none!important}.hidden-for-large,.hidden-for-large-down,.hidden-for-large-only,.hidden-for-medium,.hidden-for-medium-down,.hidden-for-medium-only,.hidden-for-small,.hidden-for-small-down,.hidden-for-small-only,.hidden-for-xlarge,.hidden-for-xlarge-down,.hidden-for-xlarge-only,.visible-for-large-up,.visible-for-medium-up,.visible-for-small-up,.visible-for-xlarge-up,.visible-for-xxlarge,.visible-for-xxlarge-down,.visible-for-xxlarge-only,.visible-for-xxlarge-up{position:static!important;height:auto;width:auto;overflow:visible;clip:auto}.hidden-for-large-up,.hidden-for-medium-up,.hidden-for-small-up,.hidden-for-xlarge-up,.hidden-for-xxlarge,.hidden-for-xxlarge-down,.hidden-for-xxlarge-only,.hidden-for-xxlarge-up,.visible-for-large,.visible-for-large-down,.visible-for-large-only,.visible-for-medium,.visible-for-medium-down,.visible-for-medium-only,.visible-for-small,.visible-for-small-down,.visible-for-small-only,.visible-for-xlarge,.visible-for-xlarge-down,.visible-for-xlarge-only{clip:rect(1px,1px,1px,1px);height:1px;overflow:hidden;position:absolute!important;width:1px}table.hide-for-large,table.hide-for-large-down,table.hide-for-large-only,table.hide-for-medium,table.hide-for-medium-down,table.hide-for-medium-only,table.hide-for-small,table.hide-for-small-down,table.hide-for-small-only,table.hide-for-xlarge,table.hide-for-xlarge-down,table.hide-for-xlarge-only,table.show-for-large-up,table.show-for-medium-up,table.show-for-small-up,table.show-for-xlarge-up,table.show-for-xxlarge,table.show-for-xxlarge-down,table.show-for-xxlarge-only,table.show-for-xxlarge-up{display:table!important}thead.hide-for-large,thead.hide-for-large-down,thead.hide-for-large-only,thead.hide-for-medium,thead.hide-for-medium-down,thead.hide-for-medium-only,thead.hide-for-small,thead.hide-for-small-down,thead.hide-for-small-only,thead.hide-for-xlarge,thead.hide-for-xlarge-down,thead.hide-for-xlarge-only,thead.show-for-large-up,thead.show-for-medium-up,thead.show-for-small-up,thead.show-for-xlarge-up,thead.show-for-xxlarge,thead.show-for-xxlarge-down,thead.show-for-xxlarge-only,thead.show-for-xxlarge-up{display:table-header-group!important}tbody.hide-for-large,tbody.hide-for-large-down,tbody.hide-for-large-only,tbody.hide-for-medium,tbody.hide-for-medium-down,tbody.hide-for-medium-only,tbody.hide-for-small,tbody.hide-for-small-down,tbody.hide-for-small-only,tbody.hide-for-xlarge,tbody.hide-for-xlarge-down,tbody.hide-for-xlarge-only,tbody.show-for-large-up,tbody.show-for-medium-up,tbody.show-for-small-up,tbody.show-for-xlarge-up,tbody.show-for-xxlarge,tbody.show-for-xxlarge-down,tbody.show-for-xxlarge-only,tbody.show-for-xxlarge-up{display:table-row-group!important}tr.hide-for-large,tr.hide-for-large-down,tr.hide-for-large-only,tr.hide-for-medium,tr.hide-for-medium-down,tr.hide-for-medium-only,tr.hide-for-small,tr.hide-for-small-down,tr.hide-for-small-only,tr.hide-for-xlarge,tr.hide-for-xlarge-down,tr.hide-for-xlarge-only,tr.show-for-large-up,tr.show-for-medium-up,tr.show-for-small-up,tr.show-for-xlarge-up,tr.show-for-xxlarge,tr.show-for-xxlarge-down,tr.show-for-xxlarge-only,tr.show-for-xxlarge-up{display:table-row}td.hide-for-large,td.hide-for-large-down,td.hide-for-large-only,td.hide-for-medium,td.hide-for-medium-down,td.hide-for-medium-only,td.hide-for-small,td.hide-for-small-down,td.hide-for-small-only,td.hide-for-xlarge,td.hide-for-xlarge-down,td.hide-for-xlarge-only,td.show-for-large-up,td.show-for-medium-up,td.show-for-small-up,td.show-for-xlarge-up,td.show-for-xxlarge,td.show-for-xxlarge-down,td.show-for-xxlarge-only,td.show-for-xxlarge-up,th.hide-for-large,th.hide-for-large-down,th.hide-for-large-only,th.hide-for-medium,th.hide-for-medium-down,th.hide-for-medium-only,th.hide-for-small,th.hide-for-small-down,th.hide-for-small-only,th.hide-for-xlarge,th.hide-for-xlarge-down,th.hide-for-xlarge-only,th.show-for-large-up,th.show-for-medium-up,th.show-for-small-up,th.show-for-xlarge-up,th.show-for-xxlarge,th.show-for-xxlarge-down,th.show-for-xxlarge-only,th.show-for-xxlarge-up{display:table-cell!important}}.hide-for-portrait,.show-for-landscape{display:inherit!important}.hide-for-landscape,.show-for-portrait{display:none!important}table.hide-for-landscape,table.show-for-portrait{display:table!important}thead.hide-for-landscape,thead.show-for-portrait{display:table-header-group!important}tbody.hide-for-landscape,tbody.show-for-portrait{display:table-row-group!important}tr.hide-for-landscape,tr.show-for-portrait{display:table-row!important}td.hide-for-landscape,td.show-for-portrait,th.hide-for-landscape,th.show-for-portrait{display:table-cell!important}@media only screen and (orientation:landscape){.hide-for-portrait,.show-for-landscape{display:inherit!important}.hide-for-landscape,.show-for-portrait{display:none!important}table.hide-for-portrait,table.show-for-landscape{display:table!important}thead.hide-for-portrait,thead.show-for-landscape{display:table-header-group!important}tbody.hide-for-portrait,tbody.show-for-landscape{display:table-row-group!important}tr.hide-for-portrait,tr.show-for-landscape{display:table-row!important}td.hide-for-portrait,td.show-for-landscape,th.hide-for-portrait,th.show-for-landscape{display:table-cell!important}}@media only screen and (orientation:portrait){.hide-for-landscape,.show-for-portrait{display:inherit!important}.hide-for-portrait,.show-for-landscape{display:none!important}table.hide-for-landscape,table.show-for-portrait{display:table!important}thead.hide-for-landscape,thead.show-for-portrait{display:table-header-group!important}tbody.hide-for-landscape,tbody.show-for-portrait{display:table-row-group!important}tr.hide-for-landscape,tr.show-for-portrait{display:table-row!important}td.hide-for-landscape,td.show-for-portrait,th.hide-for-landscape,th.show-for-portrait{display:table-cell!important}}.show-for-touch{display:none!important}.hide-for-touch,.touch .show-for-touch{display:inherit!important}.touch .hide-for-touch{display:none!important}.touch table.show-for-touch,table.hide-for-touch{display:table!important}.touch thead.show-for-touch,thead.hide-for-touch{display:table-header-group!important}.touch tbody.show-for-touch,tbody.hide-for-touch{display:table-row-group!important}.touch tr.show-for-touch,tr.hide-for-touch{display:table-row!important}.touch td.show-for-touch,.touch th.show-for-touch,td.hide-for-touch,th.hide-for-touch{display:table-cell!important}.show-for-sr,.show-on-focus{clip:rect(1px,1px,1px,1px);height:1px;overflow:hidden;position:absolute!important;width:1px}.show-on-focus:active,.show-on-focus:focus{position:static!important;height:auto;width:auto;overflow:visible;clip:auto}.print-only,.show-for-print{display:none!important}@media print{.print-only,.show-for-print{display:block!important}.hide-for-print,.hide-on-print{display:none!important}table.show-for-print{display:table!important}thead.show-for-print{display:table-header-group!important}tbody.show-for-print{display:table-row-group!important}tr.show-for-print{display:table-row!important}td.show-for-print,th.show-for-print{display:table-cell!important}}.fa,.fa-stack,.sidebar a .ripple{display:inline-block}/*!\n * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome\n * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)\n */@font-face{font-family:FontAwesome;src:url(../fonts/fontawesome-webfont.eot?v=4.7.0);src:url(../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0) format(\"embedded-opentype\"),url(../fonts/fontawesome-webfont.woff2?v=4.7.0) format(\"woff2\"),url(../fonts/fontawesome-webfont.woff?v=4.7.0) format(\"woff\"),url(../fonts/fontawesome-webfont.ttf?v=4.7.0) format(\"truetype\"),url(../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular) format(\"svg\");font-weight:400;font-style:normal}.fa{font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em}.fa-ul{padding-left:0;margin-left:2.14286em}.fa.fa-pull-right,.fa.pull-right{margin-left:.3em}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right,.pull-right{float:right}.pull-left{float:left}.fa-spin{animation:fa-spin 2s infinite linear}.fa-pulse{animation:fa-spin 1s infinite steps(8)}@keyframes fa-spin{0%{transform:rotate(0)}100%{transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:\"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)\";transform:rotate(90deg)}.fa-rotate-180{-ms-filter:\"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)\";transform:rotate(180deg)}.fa-rotate-270{-ms-filter:\"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)\";transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:\"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)\";transform:scale(-1,1)}.fa-flip-vertical{-ms-filter:\"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)\";transform:scale(1,-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-rotate-90{filter:none}.fa-stack{position:relative;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:\"\"}.fa-music:before{content:\"\"}.fa-search:before{content:\"\"}.fa-envelope-o:before{content:\"\"}.fa-heart:before{content:\"\"}.fa-star:before{content:\"\"}.fa-star-o:before{content:\"\"}.fa-user:before{content:\"\"}.fa-film:before{content:\"\"}.fa-th-large:before{content:\"\"}.fa-th:before{content:\"\"}.fa-th-list:before{content:\"\"}.fa-check:before{content:\"\"}.fa-close:before,.fa-remove:before,.fa-times:before{content:\"\"}.fa-search-plus:before{content:\"\"}.fa-search-minus:before{content:\"\"}.fa-power-off:before{content:\"\"}.fa-signal:before{content:\"\"}.fa-cog:before,.fa-gear:before{content:\"\"}.fa-trash-o:before{content:\"\"}.fa-home:before{content:\"\"}.fa-file-o:before{content:\"\"}.fa-clock-o:before{content:\"\"}.fa-road:before{content:\"\"}.fa-download:before{content:\"\"}.fa-arrow-circle-o-down:before{content:\"\"}.fa-arrow-circle-o-up:before{content:\"\"}.fa-inbox:before{content:\"\"}.fa-play-circle-o:before{content:\"\"}.fa-repeat:before,.fa-rotate-right:before{content:\"\"}.fa-refresh:before{content:\"\"}.fa-list-alt:before{content:\"\"}.fa-lock:before{content:\"\"}.fa-flag:before{content:\"\"}.fa-headphones:before{content:\"\"}.fa-volume-off:before{content:\"\"}.fa-volume-down:before{content:\"\"}.fa-volume-up:before{content:\"\"}.fa-qrcode:before{content:\"\"}.fa-barcode:before{content:\"\"}.fa-tag:before{content:\"\"}.fa-tags:before{content:\"\"}.fa-book:before{content:\"\"}.fa-bookmark:before{content:\"\"}.fa-print:before{content:\"\"}.fa-camera:before{content:\"\"}.fa-font:before{content:\"\"}.fa-bold:before{content:\"\"}.fa-italic:before{content:\"\"}.fa-text-height:before{content:\"\"}.fa-text-width:before{content:\"\"}.fa-align-left:before{content:\"\"}.fa-align-center:before{content:\"\"}.fa-align-right:before{content:\"\"}.fa-align-justify:before{content:\"\"}.fa-list:before{content:\"\"}.fa-dedent:before,.fa-outdent:before{content:\"\"}.fa-indent:before{content:\"\"}.fa-video-camera:before{content:\"\"}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:\"\"}.fa-pencil:before{content:\"\"}.fa-map-marker:before{content:\"\"}.fa-adjust:before{content:\"\"}.fa-tint:before{content:\"\"}.fa-edit:before,.fa-pencil-square-o:before{content:\"\"}.fa-share-square-o:before{content:\"\"}.fa-check-square-o:before{content:\"\"}.fa-arrows:before{content:\"\"}.fa-step-backward:before{content:\"\"}.fa-fast-backward:before{content:\"\"}.fa-backward:before{content:\"\"}.fa-play:before{content:\"\"}.fa-pause:before{content:\"\"}.fa-stop:before{content:\"\"}.fa-forward:before{content:\"\"}.fa-fast-forward:before{content:\"\"}.fa-step-forward:before{content:\"\"}.fa-eject:before{content:\"\"}.fa-chevron-left:before{content:\"\"}.fa-chevron-right:before{content:\"\"}.fa-plus-circle:before{content:\"\"}.fa-minus-circle:before{content:\"\"}.fa-times-circle:before{content:\"\"}.fa-check-circle:before{content:\"\"}.fa-question-circle:before{content:\"\"}.fa-info-circle:before{content:\"\"}.fa-crosshairs:before{content:\"\"}.fa-times-circle-o:before{content:\"\"}.fa-check-circle-o:before{content:\"\"}.fa-ban:before{content:\"\"}.fa-arrow-left:before{content:\"\"}.fa-arrow-right:before{content:\"\"}.fa-arrow-up:before{content:\"\"}.fa-arrow-down:before{content:\"\"}.fa-mail-forward:before,.fa-share:before{content:\"\"}.fa-expand:before{content:\"\"}.fa-compress:before{content:\"\"}.fa-plus:before{content:\"\"}.fa-minus:before{content:\"\"}.fa-asterisk:before{content:\"\"}.fa-exclamation-circle:before{content:\"\"}.fa-gift:before{content:\"\"}.fa-leaf:before{content:\"\"}.fa-fire:before{content:\"\"}.fa-eye:before{content:\"\"}.fa-eye-slash:before{content:\"\"}.fa-exclamation-triangle:before,.fa-warning:before{content:\"\"}.fa-plane:before{content:\"\"}.fa-calendar:before{content:\"\"}.fa-random:before{content:\"\"}.fa-comment:before{content:\"\"}.fa-magnet:before{content:\"\"}.fa-chevron-up:before{content:\"\"}.fa-chevron-down:before{content:\"\"}.fa-retweet:before{content:\"\"}.fa-shopping-cart:before{content:\"\"}.fa-folder:before{content:\"\"}.fa-folder-open:before{content:\"\"}.fa-arrows-v:before{content:\"\"}.fa-arrows-h:before{content:\"\"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:\"\"}.fa-twitter-square:before{content:\"\"}.fa-facebook-square:before{content:\"\"}.fa-camera-retro:before{content:\"\"}.fa-key:before{content:\"\"}.fa-cogs:before,.fa-gears:before{content:\"\"}.fa-comments:before{content:\"\"}.fa-thumbs-o-up:before{content:\"\"}.fa-thumbs-o-down:before{content:\"\"}.fa-star-half:before{content:\"\"}.fa-heart-o:before{content:\"\"}.fa-sign-out:before{content:\"\"}.fa-linkedin-square:before{content:\"\"}.fa-thumb-tack:before{content:\"\"}.fa-external-link:before{content:\"\"}.fa-sign-in:before{content:\"\"}.fa-trophy:before{content:\"\"}.fa-github-square:before{content:\"\"}.fa-upload:before{content:\"\"}.fa-lemon-o:before{content:\"\"}.fa-phone:before{content:\"\"}.fa-square-o:before{content:\"\"}.fa-bookmark-o:before{content:\"\"}.fa-phone-square:before{content:\"\"}.fa-twitter:before{content:\"\"}.fa-facebook-f:before,.fa-facebook:before{content:\"\"}.fa-github:before{content:\"\"}.fa-unlock:before{content:\"\"}.fa-credit-card:before{content:\"\"}.fa-feed:before,.fa-rss:before{content:\"\"}.fa-hdd-o:before{content:\"\"}.fa-bullhorn:before{content:\"\"}.fa-bell:before{content:\"\"}.fa-certificate:before{content:\"\"}.fa-hand-o-right:before{content:\"\"}.fa-hand-o-left:before{content:\"\"}.fa-hand-o-up:before{content:\"\"}.fa-hand-o-down:before{content:\"\"}.fa-arrow-circle-left:before{content:\"\"}.fa-arrow-circle-right:before{content:\"\"}.fa-arrow-circle-up:before{content:\"\"}.fa-arrow-circle-down:before{content:\"\"}.fa-globe:before{content:\"\"}.fa-wrench:before{content:\"\"}.fa-tasks:before{content:\"\"}.fa-filter:before{content:\"\"}.fa-briefcase:before{content:\"\"}.fa-arrows-alt:before{content:\"\"}.fa-group:before,.fa-users:before{content:\"\"}.fa-chain:before,.fa-link:before{content:\"\"}.fa-cloud:before{content:\"\"}.fa-flask:before{content:\"\"}.fa-cut:before,.fa-scissors:before{content:\"\"}.fa-copy:before,.fa-files-o:before{content:\"\"}.fa-paperclip:before{content:\"\"}.fa-floppy-o:before,.fa-save:before{content:\"\"}.fa-square:before{content:\"\"}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:\"\"}.fa-list-ul:before{content:\"\"}.fa-list-ol:before{content:\"\"}.fa-strikethrough:before{content:\"\"}.fa-underline:before{content:\"\"}.fa-table:before{content:\"\"}.fa-magic:before{content:\"\"}.fa-truck:before{content:\"\"}.fa-pinterest:before{content:\"\"}.fa-pinterest-square:before{content:\"\"}.fa-google-plus-square:before{content:\"\"}.fa-google-plus:before{content:\"\"}.fa-money:before{content:\"\"}.fa-caret-down:before{content:\"\"}.fa-caret-up:before{content:\"\"}.fa-caret-left:before{content:\"\"}.fa-caret-right:before{content:\"\"}.fa-columns:before{content:\"\"}.fa-sort:before,.fa-unsorted:before{content:\"\"}.fa-sort-desc:before,.fa-sort-down:before{content:\"\"}.fa-sort-asc:before,.fa-sort-up:before{content:\"\"}.fa-envelope:before{content:\"\"}.fa-linkedin:before{content:\"\"}.fa-rotate-left:before,.fa-undo:before{content:\"\"}.fa-gavel:before,.fa-legal:before{content:\"\"}.fa-dashboard:before,.fa-tachometer:before{content:\"\"}.fa-comment-o:before{content:\"\"}.fa-comments-o:before{content:\"\"}.fa-bolt:before,.fa-flash:before{content:\"\"}.fa-sitemap:before{content:\"\"}.fa-umbrella:before{content:\"\"}.fa-clipboard:before,.fa-paste:before{content:\"\"}.fa-lightbulb-o:before{content:\"\"}.fa-exchange:before{content:\"\"}.fa-cloud-download:before{content:\"\"}.fa-cloud-upload:before{content:\"\"}.fa-user-md:before{content:\"\"}.fa-stethoscope:before{content:\"\"}.fa-suitcase:before{content:\"\"}.fa-bell-o:before{content:\"\"}.fa-coffee:before{content:\"\"}.fa-cutlery:before{content:\"\"}.fa-file-text-o:before{content:\"\"}.fa-building-o:before{content:\"\"}.fa-hospital-o:before{content:\"\"}.fa-ambulance:before{content:\"\"}.fa-medkit:before{content:\"\"}.fa-fighter-jet:before{content:\"\"}.fa-beer:before{content:\"\"}.fa-h-square:before{content:\"\"}.fa-plus-square:before{content:\"\"}.fa-angle-double-left:before{content:\"\"}.fa-angle-double-right:before{content:\"\"}.fa-angle-double-up:before{content:\"\"}.fa-angle-double-down:before{content:\"\"}.fa-angle-left:before{content:\"\"}.fa-angle-right:before{content:\"\"}.fa-angle-up:before{content:\"\"}.fa-angle-down:before{content:\"\"}.fa-desktop:before{content:\"\"}.fa-laptop:before{content:\"\"}.fa-tablet:before{content:\"\"}.fa-mobile-phone:before,.fa-mobile:before{content:\"\"}.fa-circle-o:before{content:\"\"}.fa-quote-left:before{content:\"\"}.fa-quote-right:before{content:\"\"}.fa-spinner:before{content:\"\"}.fa-circle:before{content:\"\"}.fa-mail-reply:before,.fa-reply:before{content:\"\"}.fa-github-alt:before{content:\"\"}.fa-folder-o:before{content:\"\"}.fa-folder-open-o:before{content:\"\"}.fa-smile-o:before{content:\"\"}.fa-frown-o:before{content:\"\"}.fa-meh-o:before{content:\"\"}.fa-gamepad:before{content:\"\"}.fa-keyboard-o:before{content:\"\"}.fa-flag-o:before{content:\"\"}.fa-flag-checkered:before{content:\"\"}.fa-terminal:before{content:\"\"}.fa-code:before{content:\"\"}.fa-mail-reply-all:before,.fa-reply-all:before{content:\"\"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:\"\"}.fa-location-arrow:before{content:\"\"}.fa-crop:before{content:\"\"}.fa-code-fork:before{content:\"\"}.fa-chain-broken:before,.fa-unlink:before{content:\"\"}.fa-question:before{content:\"\"}.fa-info:before{content:\"\"}.fa-exclamation:before{content:\"\"}.fa-superscript:before{content:\"\"}.fa-subscript:before{content:\"\"}.fa-eraser:before{content:\"\"}.fa-puzzle-piece:before{content:\"\"}.fa-microphone:before{content:\"\"}.fa-microphone-slash:before{content:\"\"}.fa-shield:before{content:\"\"}.fa-calendar-o:before{content:\"\"}.fa-fire-extinguisher:before{content:\"\"}.fa-rocket:before{content:\"\"}.fa-maxcdn:before{content:\"\"}.fa-chevron-circle-left:before{content:\"\"}.fa-chevron-circle-right:before{content:\"\"}.fa-chevron-circle-up:before{content:\"\"}.fa-chevron-circle-down:before{content:\"\"}.fa-html5:before{content:\"\"}.fa-css3:before{content:\"\"}.fa-anchor:before{content:\"\"}.fa-unlock-alt:before{content:\"\"}.fa-bullseye:before{content:\"\"}.fa-ellipsis-h:before{content:\"\"}.fa-ellipsis-v:before{content:\"\"}.fa-rss-square:before{content:\"\"}.fa-play-circle:before{content:\"\"}.fa-ticket:before{content:\"\"}.fa-minus-square:before{content:\"\"}.fa-minus-square-o:before{content:\"\"}.fa-level-up:before{content:\"\"}.fa-level-down:before{content:\"\"}.fa-check-square:before{content:\"\"}.fa-pencil-square:before{content:\"\"}.fa-external-link-square:before{content:\"\"}.fa-share-square:before{content:\"\"}.fa-compass:before{content:\"\"}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:\"\"}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:\"\"}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:\"\"}.fa-eur:before,.fa-euro:before{content:\"\"}.fa-gbp:before{content:\"\"}.fa-dollar:before,.fa-usd:before{content:\"\"}.fa-inr:before,.fa-rupee:before{content:\"\"}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:\"\"}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:\"\"}.fa-krw:before,.fa-won:before{content:\"\"}.fa-bitcoin:before,.fa-btc:before{content:\"\"}.fa-file:before{content:\"\"}.fa-file-text:before{content:\"\"}.fa-sort-alpha-asc:before{content:\"\"}.fa-sort-alpha-desc:before{content:\"\"}.fa-sort-amount-asc:before{content:\"\"}.fa-sort-amount-desc:before{content:\"\"}.fa-sort-numeric-asc:before{content:\"\"}.fa-sort-numeric-desc:before{content:\"\"}.fa-thumbs-up:before{content:\"\"}.fa-thumbs-down:before{content:\"\"}.fa-youtube-square:before{content:\"\"}.fa-youtube:before{content:\"\"}.fa-xing:before{content:\"\"}.fa-xing-square:before{content:\"\"}.fa-youtube-play:before{content:\"\"}.fa-dropbox:before{content:\"\"}.fa-stack-overflow:before{content:\"\"}.fa-instagram:before{content:\"\"}.fa-flickr:before{content:\"\"}.fa-adn:before{content:\"\"}.fa-bitbucket:before{content:\"\"}.fa-bitbucket-square:before{content:\"\"}.fa-tumblr:before{content:\"\"}.fa-tumblr-square:before{content:\"\"}.fa-long-arrow-down:before{content:\"\"}.fa-long-arrow-up:before{content:\"\"}.fa-long-arrow-left:before{content:\"\"}.fa-long-arrow-right:before{content:\"\"}.fa-apple:before{content:\"\"}.fa-windows:before{content:\"\"}.fa-android:before{content:\"\"}.fa-linux:before{content:\"\"}.fa-dribbble:before{content:\"\"}.fa-skype:before{content:\"\"}.fa-foursquare:before{content:\"\"}.fa-trello:before{content:\"\"}.fa-female:before{content:\"\"}.fa-male:before{content:\"\"}.fa-gittip:before,.fa-gratipay:before{content:\"\"}.fa-sun-o:before{content:\"\"}.fa-moon-o:before{content:\"\"}.fa-archive:before{content:\"\"}.fa-bug:before{content:\"\"}.fa-vk:before{content:\"\"}.fa-weibo:before{content:\"\"}.fa-renren:before{content:\"\"}.fa-pagelines:before{content:\"\"}.fa-stack-exchange:before{content:\"\"}.fa-arrow-circle-o-right:before{content:\"\"}.fa-arrow-circle-o-left:before{content:\"\"}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:\"\"}.fa-dot-circle-o:before{content:\"\"}.fa-wheelchair:before{content:\"\"}.fa-vimeo-square:before{content:\"\"}.fa-try:before,.fa-turkish-lira:before{content:\"\"}.fa-plus-square-o:before{content:\"\"}.fa-space-shuttle:before{content:\"\"}.fa-slack:before{content:\"\"}.fa-envelope-square:before{content:\"\"}.fa-wordpress:before{content:\"\"}.fa-openid:before{content:\"\"}.fa-bank:before,.fa-institution:before,.fa-university:before{content:\"\"}.fa-graduation-cap:before,.fa-mortar-board:before{content:\"\"}.fa-yahoo:before{content:\"\"}.fa-google:before{content:\"\"}.fa-reddit:before{content:\"\"}.fa-reddit-square:before{content:\"\"}.fa-stumbleupon-circle:before{content:\"\"}.fa-stumbleupon:before{content:\"\"}.fa-delicious:before{content:\"\"}.fa-digg:before{content:\"\"}.fa-pied-piper-pp:before{content:\"\"}.fa-pied-piper-alt:before{content:\"\"}.fa-drupal:before{content:\"\"}.fa-joomla:before{content:\"\"}.fa-language:before{content:\"\"}.fa-fax:before{content:\"\"}.fa-building:before{content:\"\"}.fa-child:before{content:\"\"}.fa-paw:before{content:\"\"}.fa-spoon:before{content:\"\"}.fa-cube:before{content:\"\"}.fa-cubes:before{content:\"\"}.fa-behance:before{content:\"\"}.fa-behance-square:before{content:\"\"}.fa-steam:before{content:\"\"}.fa-steam-square:before{content:\"\"}.fa-recycle:before{content:\"\"}.fa-automobile:before,.fa-car:before{content:\"\"}.fa-cab:before,.fa-taxi:before{content:\"\"}.fa-tree:before{content:\"\"}.fa-spotify:before{content:\"\"}.fa-deviantart:before{content:\"\"}.fa-soundcloud:before{content:\"\"}.fa-database:before{content:\"\"}.fa-file-pdf-o:before{content:\"\"}.fa-file-word-o:before{content:\"\"}.fa-file-excel-o:before{content:\"\"}.fa-file-powerpoint-o:before{content:\"\"}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:\"\"}.fa-file-archive-o:before,.fa-file-zip-o:before{content:\"\"}.fa-file-audio-o:before,.fa-file-sound-o:before{content:\"\"}.fa-file-movie-o:before,.fa-file-video-o:before{content:\"\"}.fa-file-code-o:before{content:\"\"}.fa-vine:before{content:\"\"}.fa-codepen:before{content:\"\"}.fa-jsfiddle:before{content:\"\"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:\"\"}.fa-circle-o-notch:before{content:\"\"}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:\"\"}.fa-empire:before,.fa-ge:before{content:\"\"}.fa-git-square:before{content:\"\"}.fa-git:before{content:\"\"}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:\"\"}.fa-tencent-weibo:before{content:\"\"}.fa-qq:before{content:\"\"}.fa-wechat:before,.fa-weixin:before{content:\"\"}.fa-paper-plane:before,.fa-send:before{content:\"\"}.fa-paper-plane-o:before,.fa-send-o:before{content:\"\"}.fa-history:before{content:\"\"}.fa-circle-thin:before{content:\"\"}.fa-header:before{content:\"\"}.fa-paragraph:before{content:\"\"}.fa-sliders:before{content:\"\"}.fa-share-alt:before{content:\"\"}.fa-share-alt-square:before{content:\"\"}.fa-bomb:before{content:\"\"}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:\"\"}.fa-tty:before{content:\"\"}.fa-binoculars:before{content:\"\"}.fa-plug:before{content:\"\"}.fa-slideshare:before{content:\"\"}.fa-twitch:before{content:\"\"}.fa-yelp:before{content:\"\"}.fa-newspaper-o:before{content:\"\"}.fa-wifi:before{content:\"\"}.fa-calculator:before{content:\"\"}.fa-paypal:before{content:\"\"}.fa-google-wallet:before{content:\"\"}.fa-cc-visa:before{content:\"\"}.fa-cc-mastercard:before{content:\"\"}.fa-cc-discover:before{content:\"\"}.fa-cc-amex:before{content:\"\"}.fa-cc-paypal:before{content:\"\"}.fa-cc-stripe:before{content:\"\"}.fa-bell-slash:before{content:\"\"}.fa-bell-slash-o:before{content:\"\"}.fa-trash:before{content:\"\"}.fa-copyright:before{content:\"\"}.fa-at:before{content:\"\"}.fa-eyedropper:before{content:\"\"}.fa-paint-brush:before{content:\"\"}.fa-birthday-cake:before{content:\"\"}.fa-area-chart:before{content:\"\"}.fa-pie-chart:before{content:\"\"}.fa-line-chart:before{content:\"\"}.fa-lastfm:before{content:\"\"}.fa-lastfm-square:before{content:\"\"}.fa-toggle-off:before{content:\"\"}.fa-toggle-on:before{content:\"\"}.fa-bicycle:before{content:\"\"}.fa-bus:before{content:\"\"}.fa-ioxhost:before{content:\"\"}.fa-angellist:before{content:\"\"}.fa-cc:before{content:\"\"}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:\"\"}.fa-meanpath:before{content:\"\"}.fa-buysellads:before{content:\"\"}.fa-connectdevelop:before{content:\"\"}.fa-dashcube:before{content:\"\"}.fa-forumbee:before{content:\"\"}.fa-leanpub:before{content:\"\"}.fa-sellsy:before{content:\"\"}.fa-shirtsinbulk:before{content:\"\"}.fa-simplybuilt:before{content:\"\"}.fa-skyatlas:before{content:\"\"}.fa-cart-plus:before{content:\"\"}.fa-cart-arrow-down:before{content:\"\"}.fa-diamond:before{content:\"\"}.fa-ship:before{content:\"\"}.fa-user-secret:before{content:\"\"}.fa-motorcycle:before{content:\"\"}.fa-street-view:before{content:\"\"}.fa-heartbeat:before{content:\"\"}.fa-venus:before{content:\"\"}.fa-mars:before{content:\"\"}.fa-mercury:before{content:\"\"}.fa-intersex:before,.fa-transgender:before{content:\"\"}.fa-transgender-alt:before{content:\"\"}.fa-venus-double:before{content:\"\"}.fa-mars-double:before{content:\"\"}.fa-venus-mars:before{content:\"\"}.fa-mars-stroke:before{content:\"\"}.fa-mars-stroke-v:before{content:\"\"}.fa-mars-stroke-h:before{content:\"\"}.fa-neuter:before{content:\"\"}.fa-genderless:before{content:\"\"}.fa-facebook-official:before{content:\"\"}.fa-pinterest-p:before{content:\"\"}.fa-whatsapp:before{content:\"\"}.fa-server:before{content:\"\"}.fa-user-plus:before{content:\"\"}.fa-user-times:before{content:\"\"}.fa-bed:before,.fa-hotel:before{content:\"\"}.fa-viacoin:before{content:\"\"}.fa-train:before{content:\"\"}.fa-subway:before{content:\"\"}.fa-medium:before{content:\"\"}.fa-y-combinator:before,.fa-yc:before{content:\"\"}.fa-optin-monster:before{content:\"\"}.fa-opencart:before{content:\"\"}.fa-expeditedssl:before{content:\"\"}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:\"\"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:\"\"}.fa-battery-2:before,.fa-battery-half:before{content:\"\"}.fa-battery-1:before,.fa-battery-quarter:before{content:\"\"}.fa-battery-0:before,.fa-battery-empty:before{content:\"\"}.fa-mouse-pointer:before{content:\"\"}.fa-i-cursor:before{content:\"\"}.fa-object-group:before{content:\"\"}.fa-object-ungroup:before{content:\"\"}.fa-sticky-note:before{content:\"\"}.fa-sticky-note-o:before{content:\"\"}.fa-cc-jcb:before{content:\"\"}.fa-cc-diners-club:before{content:\"\"}.fa-clone:before{content:\"\"}.fa-balance-scale:before{content:\"\"}.fa-hourglass-o:before{content:\"\"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:\"\"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:\"\"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:\"\"}.fa-hourglass:before{content:\"\"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:\"\"}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:\"\"}.fa-hand-scissors-o:before{content:\"\"}.fa-hand-lizard-o:before{content:\"\"}.fa-hand-spock-o:before{content:\"\"}.fa-hand-pointer-o:before{content:\"\"}.fa-hand-peace-o:before{content:\"\"}.fa-trademark:before{content:\"\"}.fa-registered:before{content:\"\"}.fa-creative-commons:before{content:\"\"}.fa-gg:before{content:\"\"}.fa-gg-circle:before{content:\"\"}.fa-tripadvisor:before{content:\"\"}.fa-odnoklassniki:before{content:\"\"}.fa-odnoklassniki-square:before{content:\"\"}.fa-get-pocket:before{content:\"\"}.fa-wikipedia-w:before{content:\"\"}.fa-safari:before{content:\"\"}.fa-chrome:before{content:\"\"}.fa-firefox:before{content:\"\"}.fa-opera:before{content:\"\"}.fa-internet-explorer:before{content:\"\"}.fa-television:before,.fa-tv:before{content:\"\"}.fa-contao:before{content:\"\"}.fa-500px:before{content:\"\"}.fa-amazon:before{content:\"\"}.fa-calendar-plus-o:before{content:\"\"}.fa-calendar-minus-o:before{content:\"\"}.fa-calendar-times-o:before{content:\"\"}.fa-calendar-check-o:before{content:\"\"}.fa-industry:before{content:\"\"}.fa-map-pin:before{content:\"\"}.fa-map-signs:before{content:\"\"}.fa-map-o:before{content:\"\"}.fa-map:before{content:\"\"}.fa-commenting:before{content:\"\"}.fa-commenting-o:before{content:\"\"}.fa-houzz:before{content:\"\"}.fa-vimeo:before{content:\"\"}.fa-black-tie:before{content:\"\"}.fa-fonticons:before{content:\"\"}.fa-reddit-alien:before{content:\"\"}.fa-edge:before{content:\"\"}.fa-credit-card-alt:before{content:\"\"}.fa-codiepie:before{content:\"\"}.fa-modx:before{content:\"\"}.fa-fort-awesome:before{content:\"\"}.fa-usb:before{content:\"\"}.fa-product-hunt:before{content:\"\"}.fa-mixcloud:before{content:\"\"}.fa-scribd:before{content:\"\"}.fa-pause-circle:before{content:\"\"}.fa-pause-circle-o:before{content:\"\"}.fa-stop-circle:before{content:\"\"}.fa-stop-circle-o:before{content:\"\"}.fa-shopping-bag:before{content:\"\"}.fa-shopping-basket:before{content:\"\"}.fa-hashtag:before{content:\"\"}.fa-bluetooth:before{content:\"\"}.fa-bluetooth-b:before{content:\"\"}.fa-percent:before{content:\"\"}.fa-gitlab:before{content:\"\"}.fa-wpbeginner:before{content:\"\"}.fa-wpforms:before{content:\"\"}.fa-envira:before{content:\"\"}.fa-universal-access:before{content:\"\"}.fa-wheelchair-alt:before{content:\"\"}.fa-question-circle-o:before{content:\"\"}.fa-blind:before{content:\"\"}.fa-audio-description:before{content:\"\"}.fa-volume-control-phone:before{content:\"\"}.fa-braille:before{content:\"\"}.fa-assistive-listening-systems:before{content:\"\"}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:\"\"}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:\"\"}.fa-glide:before{content:\"\"}.fa-glide-g:before{content:\"\"}.fa-sign-language:before,.fa-signing:before{content:\"\"}.fa-low-vision:before{content:\"\"}.fa-viadeo:before{content:\"\"}.fa-viadeo-square:before{content:\"\"}.fa-snapchat:before{content:\"\"}.fa-snapchat-ghost:before{content:\"\"}.fa-snapchat-square:before{content:\"\"}.fa-pied-piper:before{content:\"\"}.fa-first-order:before{content:\"\"}.fa-yoast:before{content:\"\"}.fa-themeisle:before{content:\"\"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:\"\"}.fa-fa:before,.fa-font-awesome:before{content:\"\"}.fa-handshake-o:before{content:\"\"}.fa-envelope-open:before{content:\"\"}.fa-envelope-open-o:before{content:\"\"}.fa-linode:before{content:\"\"}.fa-address-book:before{content:\"\"}.fa-address-book-o:before{content:\"\"}.fa-address-card:before,.fa-vcard:before{content:\"\"}.fa-address-card-o:before,.fa-vcard-o:before{content:\"\"}.fa-user-circle:before{content:\"\"}.fa-user-circle-o:before{content:\"\"}.fa-user-o:before{content:\"\"}.fa-id-badge:before{content:\"\"}.fa-drivers-license:before,.fa-id-card:before{content:\"\"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:\"\"}.fa-quora:before{content:\"\"}.fa-free-code-camp:before{content:\"\"}.fa-telegram:before{content:\"\"}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:\"\"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:\"\"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:\"\"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:\"\"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:\"\"}.fa-shower:before{content:\"\"}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:\"\"}.fa-podcast:before{content:\"\"}.fa-window-maximize:before{content:\"\"}.fa-window-minimize:before{content:\"\"}.fa-window-restore:before{content:\"\"}.fa-times-rectangle:before,.fa-window-close:before{content:\"\"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:\"\"}.fa-bandcamp:before{content:\"\"}.fa-grav:before{content:\"\"}.fa-etsy:before{content:\"\"}.fa-imdb:before{content:\"\"}.fa-ravelry:before{content:\"\"}.fa-eercast:before{content:\"\"}.fa-microchip:before{content:\"\"}.fa-snowflake-o:before{content:\"\"}.fa-superpowers:before{content:\"\"}.fa-wpexplorer:before{content:\"\"}.fa-meetup:before{content:\"\"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}@font-face{font-family:klinic-reg;src:url(../fonts/klinicslabbook-webfont.eot);src:url(../fonts/klinicslabbook-webfont.eot?#iefix) format(\"embedded-opentype\"),url(../fonts/klinicslabbook-webfont.woff2) format(\"woff2\"),url(../fonts/klinicslabbook-webfont.woff) format(\"woff\"),url(../fonts/klinicslabbook-webfont.ttf) format(\"truetype\"),url(../fonts/klinicslabbook-webfont.svg#klinic_slabbook) format(\"svg\");font-weight:400;font-style:normal}@font-face{font-family:klinic-bold;src:url(../fonts/klinicslabmedium-webfont.eot);src:url(../fonts/klinicslabmedium-webfont.eot?#iefix) format(\"embedded-opentype\"),url(../fonts/klinicslabmedium-webfont.woff2) format(\"woff2\"),url(../fonts/klinicslabmedium-webfont.woff) format(\"woff\"),url(../fonts/klinicslabmedium-webfont.ttf) format(\"truetype\"),url(../fonts/klinicslabmedium-webfont.svg#klinic_slabmedium) format(\"svg\");font-weight:500;font-style:normal}.button{border-radius:.15em;font-family:klinic-bold,\"klinic bold\",\"Helvetica Neue\",Helvetica,Arial,sans-serif;font-weight:600;letter-spacing:.05em;-webkit-font-smoothing:antialiased;line-height:1.636;background-color:#2DAFE9}.x0{font-size:10px}.x1{font-size:12px}.x2{font-size:13px}.x3{font-size:14px}.x4{font-size:15px}.x5{font-size:17.92px}.x6{font-size:20px}.x7{font-size:24px}.x8{font-size:32px}.x9{font-size:36px}.x10,h1{font-size:47.2px}h1,h2,h3,h4,h5,h6{font-family:klinic-reg,klinic,\"Helvetica Neue\",Helvetica,Arial,sans-serif;font-weight:400;letter-spacing:.0075em;-webkit-font-smoothing:antialiased;margin-top:.83333rem;margin-bottom:.83333rem}h1,h2 .onboard-welcome,h2.onboard-welcome{color:#277A9F;font-family:klinic-bold,\"klinic bold\",\"Helvetica Neue\",Helvetica,Arial,sans-serif;font-weight:600;letter-spacing:.05em;-webkit-font-smoothing:antialiased}h1{text-transform:uppercase}h2{font-size:36px}h2 .onboard-welcome,h2.onboard-welcome{font-size:47.2px}h2 .onboard-tasks,h2.onboard-tasks{color:#2090CD}h2 .onboard,h2.onboard{color:#277A9F}h2 .welcome-text,h2.welcome-text{color:#277A9F;font-size:28px;font-family:klinic-reg,klinic,\"Helvetica Neue\",Helvetica,Arial,sans-serif;font-weight:400;letter-spacing:.0075em;-webkit-font-smoothing:antialiased}.content h3,h4{font-family:klinic-bold,\"klinic bold\",\"Helvetica Neue\",Helvetica,Arial,sans-serif;font-weight:600;letter-spacing:.05em}h3{font-size:24px}.content h3{text-transform:uppercase;-webkit-font-smoothing:antialiased;font-size:13px;color:#999}h4{font-size:12px;-webkit-font-smoothing:antialiased}.content h5,.line-chart-wrap h5,.regular-text{font-weight:400;-webkit-font-smoothing:antialiased}.content h5,.line-chart-wrap h5,.text-upper{letter-spacing:.25em;text-transform:uppercase}h4 .day,h4.day{color:#999}h5{color:#333}.content h5,.line-chart-wrap h5{font-family:klinic-reg,klinic,\"Helvetica Neue\",Helvetica,Arial,sans-serif;font-size:12px}blockquote,dl,ol,p,ul{font-size:14px;padding-right:5%;font-family:\"Helvetica Neue\",Helvetica,Arial,sans-serif}p{line-height:2.15;color:#666}ol,ul{margin-left:1.8rem;margin-bottom:2.5rem}ol li,ul li{margin-bottom:.5em}a{color:#2BA0D3}.regular-text{font-family:klinic-reg,klinic,\"Helvetica Neue\",Helvetica,Arial,sans-serif;letter-spacing:.0075em}.postfix,.prefix{font-family:klinic-bold,\"klinic bold\",\"Helvetica Neue\",Helvetica,Arial,sans-serif;font-weight:600;-webkit-font-smoothing:antialiased;border-radius:3px;text-transform:uppercase;letter-spacing:.25em;font-size:14px;height:3.3125rem;line-height:3.3125rem}body,html{-webkit-font-smoothing:antialiased;height:100%;padding:0;margin:0;background:url(../img/pattern-topo-sm.png),linear-gradient(170deg,#EBF7FC 5%,#fff 100%);background:url(../img/pattern-topo-sm.png),-webkit-gradient(170deg,right top,color-stop(5%,#EBF7FC),color-stop(100%,#fff));background:url(../img/pattern-topo-sm.png),-webkit-linear-gradient(170deg,#EBF7FC 5%,#fff 100%);background-position:static;background-attachment:fixed}.main{min-height:760px}.container-full{overflow-x:hidden;padding-left:300px;width:100%}.sidebar{width:25%;width:300px;left:0;top:0;background:#d4ebf5;z-index:700;position:fixed;overflow-y:scroll;border-right:1px solid #cfedfa}.sidebar a .ripple{margin:auto 0}.sidebar a .ripple span{display:block;margin:0 auto;background:#2090CD;width:10%;opacity:0;height:3px}.sidebar a:hover .ripple span{width:100%;opacity:1}.sidebar h1{margin:0;padding:0;text-transform:none}.sidebar h1 a{display:block;width:100%;padding:.333em 2.25rem;background-color:#fff;text-align:left}.sidebar h1 a img,.sidebar h1 a svg{display:block;fill:currentColor;transition:all .3s ease-in-out}.sidebar h1 a span{top:1em;position:absolute;font-size:1.5rem;color:#2090CD;left:6.5rem;font-family:klinic-reg,klinic,\"Helvetica Neue\",Helvetica,Arial,sans-serif;font-weight:400;letter-spacing:.0075em;-webkit-font-smoothing:antialiased}.sidebar h1 a:hover{background:#EBF7FC}.sidebar h1 a:hover svg{color:#fff!important}.sidebar ul{margin:3.667em auto 2em;padding:0}.sidebar ul li a{display:block;padding:0 15% .25em;color:#666;line-height:1.4;text-transform:capitalize;font-size:1.5em;font-family:klinic-bold,\"klinic bold\",\"Helvetica Neue\",Helvetica,Arial,sans-serif;font-weight:600;-webkit-font-smoothing:antialiased;letter-spacing:.02em;transition:all .3s cubic-bezier(.25,.1,.25,1)}.sidebar ul li a:hover{color:#277A9F;background:#b8dff4}.sidebar ul li a.active,.sidebar ul li a[state=open]{color:#277A9F;background:0 0}.sidebar ul li a.active .ripple span,.sidebar ul li a[state=open] .ripple span{width:100%;opacity:1;background:#4aade3}.sidebar ul li a.active:hover .ripple span,.sidebar ul li a[state=open]:hover .ripple span{background:#2090CD}.sidebar ul li a.active+ul,.sidebar ul li a[state=open]+ul{display:block}.sidebar ul li:last-child a.sidebar-nav-item:after{content:'\\f08e';font-family:FontAwesome;display:inline-block;padding-left:.5em;width:1em;height:1em;color:#2DAFE9;font-size:15px;opacity:.5}.sidebar ul li.toctree-l1.current ul{display:block!important}.sidebar ul li ul{margin:0;padding:.5em 0 1.25em;display:none}.sidebar ul li ul li{margin:0}.sidebar ul li ul li a{padding:.25em 0 .25em 17.5%;line-height:1;font-size:14px;border-right:4px solid transparent;color:#2DAFE9;transition:all .3s ease-in-out;font-family:\"Helvetica Neue\",Helvetica,Arial,sans-serif;font-weight:700}.sidebar ul li ul li a:hover{color:#277A9F;background:#b8dff4}.sidebar ul li ul li.active a{color:#277A9F;border-right:4px solid #277A9F;background:#e6f3f9}.sidebar .sidebar-buttons{border-top:2px solid #EBF7FC;background:#d4ebf5}.sidebar .sidebar-buttons .button-wrap{width:300px;padding:.5em 10%}.sidebar .sidebar-buttons .button.expand.small{margin:.333em 0;display:block;padding-top:.5rem;padding-bottom:.575rem;background-color:#EBF7FC;color:#2090CD}.sidebar .sidebar-buttons .button.expand.small i{margin:-.05em .5em 0 -.667em;color:#2090CD;font-size:14px}.left-off-canvas-toggle .fa:before{color:#2090CD}.top-bar{perspective:800px;z-index:800;min-height:5.125em;transform-style:preserve-3d;background:#fff;border-bottom:1px solid #cfedfa}.top-bar .right{min-width:33.333%;margin-right:0;margin-top:1.75em;padding-right:3.5%}.top-bar .right li{display:inline-block}.top-bar .right li a{padding:1em}.top-bar .right li a i{padding-right:.333em}.top-bar .breadcrumb{position:absolute;top:0;left:1em;z-index:1030;line-height:1.5;font-size:14px;letter-spacing:.05em}.styleguide-footer li,.styleguide-footer p,.top-bar .breadcrumb a{font-family:klinic-reg,klinic,\"Helvetica Neue\",Helvetica,Arial,sans-serif;letter-spacing:.0075em;-webkit-font-smoothing:antialiased;font-weight:400}.top-bar .breadcrumb a{padding:.333em 0;margin:.575em 0 .575em .5em;float:left;text-transform:capitalize;font-size:1.5rem;color:#2090CD;transition:all .3s ease-in-out}.top-bar .breadcrumb a:hover{color:#2DAFE9}.top-bar .breadcrumb a:before{content:'/';display:inline-block;width:.75em;height:2em;margin:0 0 0 -.2em;color:#ccc}.top-bar .breadcrumb a:first-child:before{display:none}.left-off-canvas-toggle{z-index:1100;position:fixed;top:0;left:0}.left-off-canvas-toggle .fa{background-color:#fff;padding:1.425em .925em;color:#333}.headroom{transition:transform .2s linear;position:fixed;left:300px;right:0;top:0;z-index:1000}.headroom.headroom--pinned{transform:translateY(0);box-shadow:0 1px 3px rgba(120,120,120,.1)}.headroom.headroom--unpinned{transform:translateY(-100%)}.main{margin-bottom:-5em}.main.footer-expanded{margin-bottom:-11em}.styleguide-footer{min-height:5rem;overflow:hidden;position:relative;z-index:500;padding-top:1.25em;background-color:#333;border-bottom:6px solid #333;min-width:100%;transition:all .3s ease-in-out}.styleguide-footer ul{list-style:none;float:left;margin-bottom:0}.styleguide-footer ul li{display:block;margin:0}.styleguide-footer ul li a{font-weight:400}.styleguide-footer li,.styleguide-footer p{color:#999;line-height:1.7;font-size:.667rem}.styleguide-footer li a{font-size:.75rem}.styleguide-footer strong{text-transform:uppercase;letter-spacing:.25em;margin:.75rem 0 .25rem;display:block;font-weight:400}.home #helm .billboard h1,.home h3{font-family:klinic-bold,\"klinic bold\",\"Helvetica Neue\",Helvetica,Arial,sans-serif;letter-spacing:.05em}.styleguide-footer strong a{color:#999;cursor:pointer}.styleguide-footer a{color:#2DAFE9}.styleguide-footer a:hover{border:none;text-decoration:none;color:#fff}.styleguide-footer .fa.footer-reveal{font-size:1rem;cursor:pointer;width:2em;height:2em;text-align:center;position:absolute;left:-.65em;top:.35rem;border-radius:50%;transition:all .3s ease-in-out}.styleguide-footer .fa.footer-reveal:hover{background:#262626;color:#999}.styleguide-footer p{margin-top:.75rem;color:#333}.styleguide-footer p:nth-child(2){margin-top:2.67rem;font-size:.75rem;line-height:1.5}.styleguide-footer p:nth-child(2) a{color:#2DAFE9}.styleguide-footer img{margin:0;float:right;opacity:.7;transition:all .3s ease-in-out}.styleguide-footer img:hover{opacity:1}.styleguide-footer .sub-nav-social{position:absolute;right:1em;bottom:2em;text-align:right}.styleguide-footer .sub-nav-social li{display:inline-block;margin:1rem .25em;text-align:right}.styleguide-footer .sub-nav-social li a{font-size:1.5em;color:#666;width:2em;height:2em;text-align:center;background:#262626;border-radius:50%;transition:all .3s ease-in-out}.styleguide-footer .sub-nav-social li a:hover{background:#277A9F;color:#fff}.styleguide-footer .footer-extra div{display:none;opacity:0;height:0;min-height:0;overflow:hidden;transition:all .3s ease-in-out}.styleguide-footer.footer-expanded{margin-top:-11rem;min-height:11rem}.styleguide-footer.footer-expanded .footer-extra div{display:block;opacity:1;min-height:8em}.styleguide-footer.footer-expanded a.fa.footer-reveal{transform:rotate(180deg)}#contrib{padding-top:2.5rem;padding-bottom:2.5rem}.contrib-text p{color:#999;font-size:1rem;margin:0 auto;padding-left:2rem}.contrib-text p.lead{font-size:1.2rem;margin:3rem auto;position:relative;line-height:4}.contrib-text p.lead:after{content:\" \";display:block;width:14%;position:absolute;bottom:0;left:43%;height:5px;background:#ccc;opacity:.25}.contrib-text p img{max-height:24px;margin:-2px 0 0 22px}.contrib-text p a{font-weight:700}.home #helm .billboard h1,.home .home-featured .panel h3,.home h3{font-weight:600;-webkit-font-smoothing:antialiased}.home,.home .home-intro-wrap{box-sizing:border-box;height:100%}.home h3{color:#f6fbfe;font-size:1.125rem}.home #helm{max-width:100%;position:relative;z-index:500}.home #helm:after{z-index:-100;display:block;height:850px;width:100%;bottom:0;position:fixed}.home #helm .billboard{background:url(../img/pattern-topo.png) left top;background-size:376px;padding-top:230px;position:relative;text-align:center}.home #helm .billboard h1{color:#2DAFE9;font-size:2.57rem;text-transform:none}.home #helm .billboard h2{font-family:\"Helvetica Neue\",Helvetica,Arial,sans-serif;color:#277A9F;font-size:1rem;margin-bottom:30px}.home #helm .billboard .helm-logo{position:absolute;left:5rem;top:2rem;max-width:102px}.home #helm .billboard .fa{position:absolute;font-size:2.5rem;top:4rem;right:5rem;color:#333}.home #helm .billboard .fa.fa-twitter{right:9rem;color:#2BA0D3;transition:all .3s ease-in-out}.home #helm .billboard .fa:hover{opacity:.7}.home #helm .billboard:after{background:url(../img/pattern-waves.png) left top repeat-x;background-size:20px;bottom:0;content:'';display:block;height:6px;position:absolute;width:100%}.home #boat{height:2em}@media only screen and (min-device-width:415px){@keyframes animatedBoat{0%{background-position:-150px 25%;bottom:-7px}10%,30%,50%,70%,90%{bottom:-12px}20%,40%,60%,80%{bottom:-7px}100%{background-position:145% 0;bottom:-7px}}.home #boat{background:url(../img/boat.png) no-repeat;background-size:150px;height:120px;position:relative;margin-top:40px;animation:animatedBoat 10s linear infinite;animation-duration:20s}}.home .home-featured{background-color:#2DAFE9;padding-top:20px;padding-bottom:65px;min-height:400px}.home .home-featured .panels{width:92%;max-width:1140px;min-width:800px}.home .home-featured .panel{background-color:#fff;box-shadow:0 1px 4px #277A9F;border-radius:.25em;text-align:center;min-height:125px;color:#333}.home .home-featured .panel h3{padding:.75rem 0 .5rem;border-bottom:1px solid #EBF7FC;margin-bottom:1rem;font-size:1rem;color:#2090CD;font-family:klinic-bold,\"klinic bold\",\"Helvetica Neue\",Helvetica,Arial,sans-serif;letter-spacing:.02em}.home .home-featured .panel p{line-height:1.4;display:block;font-size:.925rem;padding:0 3.5% 1rem}.main .content-wrap{padding-top:1em;padding-bottom:10em;font-size:17.92px;line-height:1.5;z-index:500;position:relative;font-family:klinic-reg,klinic,\"Helvetica Neue\",Helvetica,Arial,sans-serif;font-weight:400;letter-spacing:.0075em;-webkit-font-smoothing:antialiased}.main .content-wrap h2,.main .content-wrap h3{font-family:klinic-bold,\"klinic bold\",\"Helvetica Neue\",Helvetica,Arial,sans-serif;font-weight:600;-webkit-font-smoothing:antialiased}.main .content-wrap h1{text-transform:none;letter-spacing:.03em;margin-top:1em;padding-top:1.5em}.main .content-wrap article{padding:1em 0 0}.main .content-wrap article h1{font-size:32px;color:#2090CD;margin:1em 0;padding-top:3.5em}.main .content-wrap h2{color:#595959;font-size:24px;text-transform:uppercase;letter-spacing:.25em;letter-spacing:.125em;margin:0 0 .875em;padding-top:3.5em}.main .content-wrap h3{color:#333;letter-spacing:.05em;margin:1.25em 0 1.825em}.main .content-wrap h4{font-size:17.92px}.main .content-wrap p{color:#333;line-height:1.725;margin:.825rem 0 1.667rem;font-size:17.92px}.main .content-wrap p:first-child{font-size:20px;color:#333;line-height:1.636;margin-bottom:1.925rem;padding-right:7.5%}.main .content-wrap p a{padding-left:.25em;padding-right:.25em}.main .content-wrap pre,.main .content-wrap.markdown pre{background-color:#e4f3f9;color:#000;border:none;padding:.75em 1em;margin:.25em 0 2.5em;font-size:1rem}.main .content-wrap pre code,.main .content-wrap.markdown pre code{padding:0;background-color:#e4f3f9;font-size:1rem}.main .content-wrap .code-box{margin:0;width:100%;height:220px;border-bottom:3px solid #ccc;overflow:scroll}.main .content-wrap strong{letter-spacing:.0125em}.main .content-wrap code{color:#000;padding:.5em;background-color:#e4f3f9;border:none;font-size:1rem}.main .content-wrap ol,.main .content-wrap ul,.main .content-wrap.markdown ol,.main .content-wrap.markdown ul{padding:0 .25rem;margin-bottom:2em;color:#333;font-size:15px;line-height:1.7}.main .content-wrap ol li,.main .content-wrap ul li,.main .content-wrap.markdown ol li,.main .content-wrap.markdown ul li{font-size:1.125em}.main .content-wrap table{margin:1.5rem 0;border:none;width:100%}.main .content-wrap table td,.main .content-wrap table th{border:none;vertical-align:top;text-align:left;padding:.425em .75em .425em .2em;width:auto}.main .content-wrap table td{color:#333;font-size:15px}.main .content-wrap a{color:#1b79ac;background-color:#f6fbfe;transition:all .3s ease-in-out}.main .content-wrap a:hover{color:#2790be;border-bottom:2px solid #2DAFE9;background:#fff}.main .content-wrap .header-link{position:absolute;left:-.4em;opacity:0;font-size:1rem;padding-top:.333em;transition:all .3s ease-in-out}.main .content-wrap .header-link:hover{border-bottom:none;background-color:transparent}.main .content-wrap h2:hover,.main .content-wrap h3:hover,.main .content-wrap h4:hover,.main .content-wrap h5:hover,.main .content-wrap h6:hover{color:#277A9F}.main .content-wrap h2:hover .header-link,.main .content-wrap h3:hover .header-link,.main .content-wrap h4:hover .header-link,.main .content-wrap h5:hover .header-link,.main .content-wrap h6:hover .header-link{opacity:1;left:-.825em}.main .content-wrap img{box-shadow:0 0 3px #ccc;padding:.5em;background-color:#fff;max-width:100%;margin-bottom:.75em}.main .content-wrap img:hover{box-shadow:0 0 4px #999}.main .content-wrap .youtube-player,.main .content-wrap embed,.main .content-wrap iframe{min-height:320px}@media only screen and (max-width:64.063em){aside.left-off-canvas-menu ul,aside.left-off-canvas-menu ul li a:hover{background:#2BA0D3!important}.home .fa,.sidebar{display:none}.container-full{padding-left:0}.left-off-canvas-toggle .fa{padding:1em 1.25em;line-height:3}.headroom{left:0}.st-default-autocomplete{width:90%!important;min-width:320px!important;left:5%!important}.home{min-height:500px}.home #helm .billboard{padding-top:180px}.home #helm .billboard .container{margin-left:5%;margin-right:5%}.home #helm .billboard h1{font-size:2rem}.main .content-wrap article h1,.main .content-wrap h1{font-size:32px}.home #helm .billboard .helm-logo{max-width:60%!important;left:20%!important}.main .content-wrap article{padding:0 0 .5em}.main .content-wrap article h2{font-size:20px}.main .content-wrap article p:first-child{padding-right:0;font-size:17.92px}aside.left-off-canvas-menu ul li{font-family:klinic-bold,\"klinic bold\",\"Helvetica Neue\",Helvetica,Arial,sans-serif;font-weight:600;letter-spacing:.05em;-webkit-font-smoothing:antialiased;font-size:1.25rem}aside.left-off-canvas-menu ul li a{color:#fff!important;border-bottom:none!important}aside.left-off-canvas-menu ul li a.active{color:#fff!important;background:#277A9F!important}aside.left-off-canvas-menu ul li a+ul{display:none;background:#277A9F!important;margin-left:0;padding:.5em 0 1em 1.5em}aside.left-off-canvas-menu ul li a+ul li{font-family:\"Helvetica Neue\",Helvetica,Arial,sans-serif;letter-spacing:0;font-size:1rem;list-style:none}aside.left-off-canvas-menu ul li a+ul li a{padding:.1em .66667rem;border-bottom:none;color:#EBF7FC!important}aside.left-off-canvas-menu ul li a.active+ul{display:block}aside.left-off-canvas-menu .button-wrap{padding:.75em 5%}aside.left-off-canvas-menu .button-wrap .button{margin:.4em 0}.top-bar .breadcrumb{left:2.75rem}.top-bar .right li{display:none}.top-bar .right li:nth-child(2){display:inline-block}.top-bar .right li:nth-child(2) a{position:absolute;right:-4em;top:-.35em;font-size:1.75rem}}@media screen and (min-height:575px){.sidebar{padding-bottom:0}.sidebar .sidebar-nav{padding-bottom:180px}.sidebar .sidebar-buttons{position:fixed;bottom:0}}.section-404{position:relative;min-height:670px}.section-404 #particles-js{position:absolute;width:100%}.section-404 h1{text-transform:none;font-size:32px;letter-spacing:.05em;margin:5em 7.5% 2.5em;position:relative}"]} \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/src/fonts/fontawesome-webfont.eot b/docs.helm.sh/rootfs/public/src/fonts/fontawesome-webfont.eot deleted file mode 100644 index e9f60ca953..0000000000 Binary files a/docs.helm.sh/rootfs/public/src/fonts/fontawesome-webfont.eot and /dev/null differ diff --git a/docs.helm.sh/rootfs/public/src/fonts/fontawesome-webfont.otf b/docs.helm.sh/rootfs/public/src/fonts/fontawesome-webfont.otf deleted file mode 100644 index 401ec0f36e..0000000000 Binary files a/docs.helm.sh/rootfs/public/src/fonts/fontawesome-webfont.otf and /dev/null differ diff --git a/docs.helm.sh/rootfs/public/src/fonts/fontawesome-webfont.svg b/docs.helm.sh/rootfs/public/src/fonts/fontawesome-webfont.svg deleted file mode 100644 index 855c845e53..0000000000 --- a/docs.helm.sh/rootfs/public/src/fonts/fontawesome-webfont.svg +++ /dev/null @@ -1,2671 +0,0 @@ - - - - -Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 - By ,,, -Copyright Dave Gandy 2016. All rights reserved. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs.helm.sh/rootfs/public/src/fonts/fontawesome-webfont.ttf b/docs.helm.sh/rootfs/public/src/fonts/fontawesome-webfont.ttf deleted file mode 100644 index 35acda2fa1..0000000000 Binary files a/docs.helm.sh/rootfs/public/src/fonts/fontawesome-webfont.ttf and /dev/null differ diff --git a/docs.helm.sh/rootfs/public/src/fonts/fontawesome-webfont.woff b/docs.helm.sh/rootfs/public/src/fonts/fontawesome-webfont.woff deleted file mode 100644 index 400014a4b0..0000000000 Binary files a/docs.helm.sh/rootfs/public/src/fonts/fontawesome-webfont.woff and /dev/null differ diff --git a/docs.helm.sh/rootfs/public/src/fonts/fontawesome-webfont.woff2 b/docs.helm.sh/rootfs/public/src/fonts/fontawesome-webfont.woff2 deleted file mode 100644 index 4d13fc6040..0000000000 Binary files a/docs.helm.sh/rootfs/public/src/fonts/fontawesome-webfont.woff2 and /dev/null differ diff --git a/docs.helm.sh/rootfs/public/src/fonts/klinicslabbook-webfont.eot b/docs.helm.sh/rootfs/public/src/fonts/klinicslabbook-webfont.eot deleted file mode 100755 index 1907bfdc76..0000000000 Binary files a/docs.helm.sh/rootfs/public/src/fonts/klinicslabbook-webfont.eot and /dev/null differ diff --git a/docs.helm.sh/rootfs/public/src/fonts/klinicslabbook-webfont.svg b/docs.helm.sh/rootfs/public/src/fonts/klinicslabbook-webfont.svg deleted file mode 100755 index 7924220bd1..0000000000 --- a/docs.helm.sh/rootfs/public/src/fonts/klinicslabbook-webfont.svg +++ /dev/null @@ -1,1900 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/src/fonts/klinicslabbook-webfont.ttf b/docs.helm.sh/rootfs/public/src/fonts/klinicslabbook-webfont.ttf deleted file mode 100755 index acd4f27e4f..0000000000 Binary files a/docs.helm.sh/rootfs/public/src/fonts/klinicslabbook-webfont.ttf and /dev/null differ diff --git a/docs.helm.sh/rootfs/public/src/fonts/klinicslabbook-webfont.woff b/docs.helm.sh/rootfs/public/src/fonts/klinicslabbook-webfont.woff deleted file mode 100755 index 822179bd19..0000000000 Binary files a/docs.helm.sh/rootfs/public/src/fonts/klinicslabbook-webfont.woff and /dev/null differ diff --git a/docs.helm.sh/rootfs/public/src/fonts/klinicslabbook-webfont.woff2 b/docs.helm.sh/rootfs/public/src/fonts/klinicslabbook-webfont.woff2 deleted file mode 100755 index c18bf5e6ef..0000000000 Binary files a/docs.helm.sh/rootfs/public/src/fonts/klinicslabbook-webfont.woff2 and /dev/null differ diff --git a/docs.helm.sh/rootfs/public/src/fonts/klinicslabmedium-webfont.eot b/docs.helm.sh/rootfs/public/src/fonts/klinicslabmedium-webfont.eot deleted file mode 100755 index d2bc3bfd8a..0000000000 Binary files a/docs.helm.sh/rootfs/public/src/fonts/klinicslabmedium-webfont.eot and /dev/null differ diff --git a/docs.helm.sh/rootfs/public/src/fonts/klinicslabmedium-webfont.svg b/docs.helm.sh/rootfs/public/src/fonts/klinicslabmedium-webfont.svg deleted file mode 100755 index b1e553fb7e..0000000000 --- a/docs.helm.sh/rootfs/public/src/fonts/klinicslabmedium-webfont.svg +++ /dev/null @@ -1,1884 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/src/fonts/klinicslabmedium-webfont.ttf b/docs.helm.sh/rootfs/public/src/fonts/klinicslabmedium-webfont.ttf deleted file mode 100755 index 994071b3cb..0000000000 Binary files a/docs.helm.sh/rootfs/public/src/fonts/klinicslabmedium-webfont.ttf and /dev/null differ diff --git a/docs.helm.sh/rootfs/public/src/fonts/klinicslabmedium-webfont.woff b/docs.helm.sh/rootfs/public/src/fonts/klinicslabmedium-webfont.woff deleted file mode 100755 index 643977673a..0000000000 Binary files a/docs.helm.sh/rootfs/public/src/fonts/klinicslabmedium-webfont.woff and /dev/null differ diff --git a/docs.helm.sh/rootfs/public/src/fonts/klinicslabmedium-webfont.woff2 b/docs.helm.sh/rootfs/public/src/fonts/klinicslabmedium-webfont.woff2 deleted file mode 100755 index 55651e0b5a..0000000000 Binary files a/docs.helm.sh/rootfs/public/src/fonts/klinicslabmedium-webfont.woff2 and /dev/null differ diff --git a/docs.helm.sh/rootfs/public/src/img/btn-get-helm.png b/docs.helm.sh/rootfs/public/src/img/btn-get-helm.png deleted file mode 100644 index e20e1cd093..0000000000 Binary files a/docs.helm.sh/rootfs/public/src/img/btn-get-helm.png and /dev/null differ diff --git a/docs.helm.sh/rootfs/public/src/js/app_init.min.js b/docs.helm.sh/rootfs/public/src/js/app_init.min.js deleted file mode 100755 index 594a6c98a6..0000000000 --- a/docs.helm.sh/rootfs/public/src/js/app_init.min.js +++ /dev/null @@ -1 +0,0 @@ -$(document).ready(function(){$(document).foundation();var t=window.location.pathname,e=t.substring(0,t.lastIndexOf("/")),n=e.substring(e.lastIndexOf("/")+1);$(".toctree-l1 > a[href='"+n+"']").addClass("active").attr({state:"open"}),$(".toctree-l1 > a").click(function(){return"open"!=$(this).attr("state")&&("open"!=$(this).attr("state")&&$(this).siblings().size()>0?($(".toctree-l1 > ul").hide(),$(".toctree-l1 > a").attr("state",""),$(this).attr("state","open"),$(this).next().slideDown(function(){}),!1):void 0)})}),function(){var t=document.querySelector(".top-bar");new Headroom(t,{offset:50,classes:{initial:"headroom",pinned:"headroom--pinned",unpinned:"headroom--unpinned",top:"headroom--top",notTop:"headroom--not-top"}}).init()}(),$(function(){return $("h1, h2, h3, h4, h5, h6").each(function(t,e){var n,a,o;if(n=$(e),o=n.attr("id"),a='',o)return n.prepend($("").addClass("header-link").attr("href","#"+o).html(a))})}),$(function(){$("a[href*=#]:not([href=#])").click(function(){if(location.pathname.replace(/^\//,"")==this.pathname.replace(/^\//,"")&&location.hostname==this.hostname){var t=$(this.hash);t=t.length?t:$("[name="+this.hash.slice(1)+"]"),t.length&&$("html,body").animate({scrollTop:t.offset().top},400)}})}); \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/src/js/custom/app_init.js b/docs.helm.sh/rootfs/public/src/js/custom/app_init.js deleted file mode 100755 index 46160a1c01..0000000000 --- a/docs.helm.sh/rootfs/public/src/js/custom/app_init.js +++ /dev/null @@ -1,75 +0,0 @@ -$(document).ready(function() { - $(document).foundation(); - - // custom theme js for sidebar links - var allClosed; - - // close all accordions, besides that of the page that is currently active - var doclocation = window.location.pathname; - var docpath = doclocation.substring(0, doclocation.lastIndexOf("/")); - var directoryName = docpath.substring(docpath.lastIndexOf("/")+1); - $(".toctree-l1 > a[href='" + directoryName + "']").addClass('active').attr({state: "open"}); - - if (allClosed === true) { } - - // if menu is closed when clicked, expand it - $('.toctree-l1 > a').click(function() { - - //Make the titles of open accordions dead links - if ($(this).attr('state') == 'open') {return false;} - - //Clicking on a title of a closed accordion - if($(this).attr('state') != 'open' && $(this).siblings().size() > 0) { - $('.toctree-l1 > ul').hide(); - $('.toctree-l1 > a').attr('state', ''); - $(this).attr('state', 'open'); - $(this).next().slideDown(function(){}); - return false; - } - }); -}); // document ready - - -// headroom -(function() { - var searchBar = document.querySelector(".top-bar"); - new Headroom(searchBar, { - offset: 50, - classes: { - "initial": "headroom", - "pinned": "headroom--pinned", - "unpinned": "headroom--unpinned", - "top" : "headroom--top", - "notTop" : "headroom--not-top" - } - }).init(); -}()); - -// add permalinks to titles -$(function() { - return $("h1, h2, h3, h4, h5, h6").each(function(i, el) { - var $el, icon, id; - $el = $(el); - id = $el.attr('id'); - icon = ''; - if (id) { - return $el.prepend($("").addClass("header-link").attr("href", "#" + id).html(icon)); - } - }); -}); - -// smooth scroll -$(function() { - $('a[href*=#]:not([href=#])').click(function() { - if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) { - var target = $(this.hash); - target = target.length ? target : $('[name=' + this.hash.slice(1) +']'); - if (target.length) { - $('html,body').animate({ - scrollTop: target.offset().top - }, 400); - // return false; - } - } - }); -}); diff --git a/docs.helm.sh/rootfs/public/src/js/custom/foundation.js b/docs.helm.sh/rootfs/public/src/js/custom/foundation.js deleted file mode 100755 index c5a359d3b6..0000000000 --- a/docs.helm.sh/rootfs/public/src/js/custom/foundation.js +++ /dev/null @@ -1,732 +0,0 @@ -/* - * Foundation Responsive Library - * http://foundation.zurb.com - * Copyright 2015, ZURB - * Free to use under the MIT license. - * http://www.opensource.org/licenses/mit-license.php -*/ - -(function ($, window, document, undefined) { - 'use strict'; - - var header_helpers = function (class_array) { - var head = $('head'); - head.prepend($.map(class_array, function (class_name) { - if (head.has('.' + class_name).length === 0) { - return ''; - } - })); - }; - - header_helpers([ - 'foundation-mq-small', - 'foundation-mq-small-only', - 'foundation-mq-medium', - 'foundation-mq-medium-only', - 'foundation-mq-large', - 'foundation-mq-large-only', - 'foundation-mq-xlarge', - 'foundation-mq-xlarge-only', - 'foundation-mq-xxlarge', - 'foundation-data-attribute-namespace']); - - // Enable FastClick if present - - $(function () { - if (typeof FastClick !== 'undefined') { - // Don't attach to body if undefined - if (typeof document.body !== 'undefined') { - FastClick.attach(document.body); - } - } - }); - - // private Fast Selector wrapper, - // returns jQuery object. Only use where - // getElementById is not available. - var S = function (selector, context) { - if (typeof selector === 'string') { - if (context) { - var cont; - if (context.jquery) { - cont = context[0]; - if (!cont) { - return context; - } - } else { - cont = context; - } - return $(cont.querySelectorAll(selector)); - } - - return $(document.querySelectorAll(selector)); - } - - return $(selector, context); - }; - - // Namespace functions. - - var attr_name = function (init) { - var arr = []; - if (!init) { - arr.push('data'); - } - if (this.namespace.length > 0) { - arr.push(this.namespace); - } - arr.push(this.name); - - return arr.join('-'); - }; - - var add_namespace = function (str) { - var parts = str.split('-'), - i = parts.length, - arr = []; - - while (i--) { - if (i !== 0) { - arr.push(parts[i]); - } else { - if (this.namespace.length > 0) { - arr.push(this.namespace, parts[i]); - } else { - arr.push(parts[i]); - } - } - } - - return arr.reverse().join('-'); - }; - - // Event binding and data-options updating. - - var bindings = function (method, options) { - var self = this, - bind = function(){ - var $this = S(this), - should_bind_events = !$this.data(self.attr_name(true) + '-init'); - $this.data(self.attr_name(true) + '-init', $.extend({}, self.settings, (options || method), self.data_options($this))); - - if (should_bind_events) { - self.events(this); - } - }; - - if (S(this.scope).is('[' + this.attr_name() +']')) { - bind.call(this.scope); - } else { - S('[' + this.attr_name() +']', this.scope).each(bind); - } - // # Patch to fix #5043 to move this *after* the if/else clause in order for Backbone and similar frameworks to have improved control over event binding and data-options updating. - if (typeof method === 'string') { - return this[method].call(this, options); - } - - }; - - var single_image_loaded = function (image, callback) { - function loaded () { - callback(image[0]); - } - - function bindLoad () { - this.one('load', loaded); - - if (/MSIE (\d+\.\d+);/.test(navigator.userAgent)) { - var src = this.attr( 'src' ), - param = src.match( /\?/ ) ? '&' : '?'; - - param += 'random=' + (new Date()).getTime(); - this.attr('src', src + param); - } - } - - if (!image.attr('src')) { - loaded(); - return; - } - - if (image[0].complete || image[0].readyState === 4) { - loaded(); - } else { - bindLoad.call(image); - } - }; - - /*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas, David Knight. Dual MIT/BSD license */ - - window.matchMedia || (window.matchMedia = function() { - "use strict"; - - // For browsers that support matchMedium api such as IE 9 and webkit - var styleMedia = (window.styleMedia || window.media); - - // For those that don't support matchMedium - if (!styleMedia) { - var style = document.createElement('style'), - script = document.getElementsByTagName('script')[0], - info = null; - - style.type = 'text/css'; - style.id = 'matchmediajs-test'; - - script.parentNode.insertBefore(style, script); - - // 'style.currentStyle' is used by IE <= 8 and 'window.getComputedStyle' for all other browsers - info = ('getComputedStyle' in window) && window.getComputedStyle(style, null) || style.currentStyle; - - styleMedia = { - matchMedium: function(media) { - var text = '@media ' + media + '{ #matchmediajs-test { width: 1px; } }'; - - // 'style.styleSheet' is used by IE <= 8 and 'style.textContent' for all other browsers - if (style.styleSheet) { - style.styleSheet.cssText = text; - } else { - style.textContent = text; - } - - // Test if media query is true or false - return info.width === '1px'; - } - }; - } - - return function(media) { - return { - matches: styleMedia.matchMedium(media || 'all'), - media: media || 'all' - }; - }; - }()); - - /* - * jquery.requestAnimationFrame - * https://github.com/gnarf37/jquery-requestAnimationFrame - * Requires jQuery 1.8+ - * - * Copyright (c) 2012 Corey Frang - * Licensed under the MIT license. - */ - - (function(jQuery) { - - - // requestAnimationFrame polyfill adapted from Erik Möller - // fixes from Paul Irish and Tino Zijdel - // http://paulirish.com/2011/requestanimationframe-for-smart-animating/ - // http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating - - var animating, - lastTime = 0, - vendors = ['webkit', 'moz'], - requestAnimationFrame = window.requestAnimationFrame, - cancelAnimationFrame = window.cancelAnimationFrame, - jqueryFxAvailable = 'undefined' !== typeof jQuery.fx; - - for (; lastTime < vendors.length && !requestAnimationFrame; lastTime++) { - requestAnimationFrame = window[ vendors[lastTime] + 'RequestAnimationFrame' ]; - cancelAnimationFrame = cancelAnimationFrame || - window[ vendors[lastTime] + 'CancelAnimationFrame' ] || - window[ vendors[lastTime] + 'CancelRequestAnimationFrame' ]; - } - - function raf() { - if (animating) { - requestAnimationFrame(raf); - - if (jqueryFxAvailable) { - jQuery.fx.tick(); - } - } - } - - if (requestAnimationFrame) { - // use rAF - window.requestAnimationFrame = requestAnimationFrame; - window.cancelAnimationFrame = cancelAnimationFrame; - - if (jqueryFxAvailable) { - jQuery.fx.timer = function (timer) { - if (timer() && jQuery.timers.push(timer) && !animating) { - animating = true; - raf(); - } - }; - - jQuery.fx.stop = function () { - animating = false; - }; - } - } else { - // polyfill - window.requestAnimationFrame = function (callback) { - var currTime = new Date().getTime(), - timeToCall = Math.max(0, 16 - (currTime - lastTime)), - id = window.setTimeout(function () { - callback(currTime + timeToCall); - }, timeToCall); - lastTime = currTime + timeToCall; - return id; - }; - - window.cancelAnimationFrame = function (id) { - clearTimeout(id); - }; - - } - - }( $ )); - - function removeQuotes (string) { - if (typeof string === 'string' || string instanceof String) { - string = string.replace(/^['\\/"]+|(;\s?})+|['\\/"]+$/g, ''); - } - - return string; - } - - function MediaQuery(selector) { - this.selector = selector; - this.query = ''; - } - - MediaQuery.prototype.toString = function () { - return this.query || (this.query = S(this.selector).css('font-family').replace(/^[\/\\'"]+|(;\s?})+|[\/\\'"]+$/g, '')); - }; - - window.Foundation = { - name : 'Foundation', - - version : '5.5.3', - - media_queries : { - 'small' : new MediaQuery('.foundation-mq-small'), - 'small-only' : new MediaQuery('.foundation-mq-small-only'), - 'medium' : new MediaQuery('.foundation-mq-medium'), - 'medium-only' : new MediaQuery('.foundation-mq-medium-only'), - 'large' : new MediaQuery('.foundation-mq-large'), - 'large-only' : new MediaQuery('.foundation-mq-large-only'), - 'xlarge' : new MediaQuery('.foundation-mq-xlarge'), - 'xlarge-only' : new MediaQuery('.foundation-mq-xlarge-only'), - 'xxlarge' : new MediaQuery('.foundation-mq-xxlarge') - }, - - stylesheet : $('').appendTo('head')[0].sheet, - - global : { - namespace : undefined - }, - - init : function (scope, libraries, method, options, response) { - var args = [scope, method, options, response], - responses = []; - - // check RTL - this.rtl = /rtl/i.test(S('html').attr('dir')); - - // set foundation global scope - this.scope = scope || this.scope; - - this.set_namespace(); - - if (libraries && typeof libraries === 'string' && !/reflow/i.test(libraries)) { - if (this.libs.hasOwnProperty(libraries)) { - responses.push(this.init_lib(libraries, args)); - } - } else { - for (var lib in this.libs) { - responses.push(this.init_lib(lib, libraries)); - } - } - - S(window).load(function () { - S(window) - .trigger('resize.fndtn.clearing') - .trigger('resize.fndtn.dropdown') - .trigger('resize.fndtn.equalizer') - .trigger('resize.fndtn.interchange') - .trigger('resize.fndtn.joyride') - .trigger('resize.fndtn.magellan') - .trigger('resize.fndtn.topbar') - .trigger('resize.fndtn.slider'); - }); - - return scope; - }, - - init_lib : function (lib, args) { - if (this.libs.hasOwnProperty(lib)) { - this.patch(this.libs[lib]); - - if (args && args.hasOwnProperty(lib)) { - if (typeof this.libs[lib].settings !== 'undefined') { - $.extend(true, this.libs[lib].settings, args[lib]); - } else if (typeof this.libs[lib].defaults !== 'undefined') { - $.extend(true, this.libs[lib].defaults, args[lib]); - } - return this.libs[lib].init.apply(this.libs[lib], [this.scope, args[lib]]); - } - - args = args instanceof Array ? args : new Array(args); - return this.libs[lib].init.apply(this.libs[lib], args); - } - - return function () {}; - }, - - patch : function (lib) { - lib.scope = this.scope; - lib.namespace = this.global.namespace; - lib.rtl = this.rtl; - lib['data_options'] = this.utils.data_options; - lib['attr_name'] = attr_name; - lib['add_namespace'] = add_namespace; - lib['bindings'] = bindings; - lib['S'] = this.utils.S; - }, - - inherit : function (scope, methods) { - var methods_arr = methods.split(' '), - i = methods_arr.length; - - while (i--) { - if (this.utils.hasOwnProperty(methods_arr[i])) { - scope[methods_arr[i]] = this.utils[methods_arr[i]]; - } - } - }, - - set_namespace : function () { - - // Description: - // Don't bother reading the namespace out of the meta tag - // if the namespace has been set globally in javascript - // - // Example: - // Foundation.global.namespace = 'my-namespace'; - // or make it an empty string: - // Foundation.global.namespace = ''; - // - // - - // If the namespace has not been set (is undefined), try to read it out of the meta element. - // Otherwise use the globally defined namespace, even if it's empty ('') - var namespace = ( this.global.namespace === undefined ) ? $('.foundation-data-attribute-namespace').css('font-family') : this.global.namespace; - - // Finally, if the namsepace is either undefined or false, set it to an empty string. - // Otherwise use the namespace value. - this.global.namespace = ( namespace === undefined || /false/i.test(namespace) ) ? '' : namespace; - }, - - libs : {}, - - // methods that can be inherited in libraries - utils : { - - // Description: - // Fast Selector wrapper returns jQuery object. Only use where getElementById - // is not available. - // - // Arguments: - // Selector (String): CSS selector describing the element(s) to be - // returned as a jQuery object. - // - // Scope (String): CSS selector describing the area to be searched. Default - // is document. - // - // Returns: - // Element (jQuery Object): jQuery object containing elements matching the - // selector within the scope. - S : S, - - // Description: - // Executes a function a max of once every n milliseconds - // - // Arguments: - // Func (Function): Function to be throttled. - // - // Delay (Integer): Function execution threshold in milliseconds. - // - // Returns: - // Lazy_function (Function): Function with throttling applied. - throttle : function (func, delay) { - var timer = null; - - return function () { - var context = this, args = arguments; - - if (timer == null) { - timer = setTimeout(function () { - func.apply(context, args); - timer = null; - }, delay); - } - }; - }, - - // Description: - // Executes a function when it stops being invoked for n seconds - // Modified version of _.debounce() http://underscorejs.org - // - // Arguments: - // Func (Function): Function to be debounced. - // - // Delay (Integer): Function execution threshold in milliseconds. - // - // Immediate (Bool): Whether the function should be called at the beginning - // of the delay instead of the end. Default is false. - // - // Returns: - // Lazy_function (Function): Function with debouncing applied. - debounce : function (func, delay, immediate) { - var timeout, result; - return function () { - var context = this, args = arguments; - var later = function () { - timeout = null; - if (!immediate) { - result = func.apply(context, args); - } - }; - var callNow = immediate && !timeout; - clearTimeout(timeout); - timeout = setTimeout(later, delay); - if (callNow) { - result = func.apply(context, args); - } - return result; - }; - }, - - // Description: - // Parses data-options attribute - // - // Arguments: - // El (jQuery Object): Element to be parsed. - // - // Returns: - // Options (Javascript Object): Contents of the element's data-options - // attribute. - data_options : function (el, data_attr_name) { - data_attr_name = data_attr_name || 'options'; - var opts = {}, ii, p, opts_arr, - data_options = function (el) { - var namespace = Foundation.global.namespace; - - if (namespace.length > 0) { - return el.data(namespace + '-' + data_attr_name); - } - - return el.data(data_attr_name); - }; - - var cached_options = data_options(el); - - if (typeof cached_options === 'object') { - return cached_options; - } - - opts_arr = (cached_options || ':').split(';'); - ii = opts_arr.length; - - function isNumber (o) { - return !isNaN (o - 0) && o !== null && o !== '' && o !== false && o !== true; - } - - function trim (str) { - if (typeof str === 'string') { - return $.trim(str); - } - return str; - } - - while (ii--) { - p = opts_arr[ii].split(':'); - p = [p[0], p.slice(1).join(':')]; - - if (/true/i.test(p[1])) { - p[1] = true; - } - if (/false/i.test(p[1])) { - p[1] = false; - } - if (isNumber(p[1])) { - if (p[1].indexOf('.') === -1) { - p[1] = parseInt(p[1], 10); - } else { - p[1] = parseFloat(p[1]); - } - } - - if (p.length === 2 && p[0].length > 0) { - opts[trim(p[0])] = trim(p[1]); - } - } - - return opts; - }, - - // Description: - // Adds JS-recognizable media queries - // - // Arguments: - // Media (String): Key string for the media query to be stored as in - // Foundation.media_queries - // - // Class (String): Class name for the generated tag - register_media : function (media, media_class) { - if (Foundation.media_queries[media] === undefined) { - $('head').append(''); - Foundation.media_queries[media] = removeQuotes($('.' + media_class).css('font-family')); - } - }, - - // Description: - // Add custom CSS within a JS-defined media query - // - // Arguments: - // Rule (String): CSS rule to be appended to the document. - // - // Media (String): Optional media query string for the CSS rule to be - // nested under. - add_custom_rule : function (rule, media) { - if (media === undefined && Foundation.stylesheet) { - Foundation.stylesheet.insertRule(rule, Foundation.stylesheet.cssRules.length); - } else { - var query = Foundation.media_queries[media]; - - if (query !== undefined) { - Foundation.stylesheet.insertRule('@media ' + - Foundation.media_queries[media] + '{ ' + rule + ' }', Foundation.stylesheet.cssRules.length); - } - } - }, - - // Description: - // Performs a callback function when an image is fully loaded - // - // Arguments: - // Image (jQuery Object): Image(s) to check if loaded. - // - // Callback (Function): Function to execute when image is fully loaded. - image_loaded : function (images, callback) { - var self = this, - unloaded = images.length; - - function pictures_has_height(images) { - var pictures_number = images.length; - - for (var i = pictures_number - 1; i >= 0; i--) { - if(images.attr('height') === undefined) { - return false; - }; - }; - - return true; - } - - if (unloaded === 0 || pictures_has_height(images)) { - callback(images); - } - - images.each(function () { - single_image_loaded(self.S(this), function () { - unloaded -= 1; - if (unloaded === 0) { - callback(images); - } - }); - }); - }, - - // Description: - // Returns a random, alphanumeric string - // - // Arguments: - // Length (Integer): Length of string to be generated. Defaults to random - // integer. - // - // Returns: - // Rand (String): Pseudo-random, alphanumeric string. - random_str : function () { - if (!this.fidx) { - this.fidx = 0; - } - this.prefix = this.prefix || [(this.name || 'F'), (+new Date).toString(36)].join('-'); - - return this.prefix + (this.fidx++).toString(36); - }, - - // Description: - // Helper for window.matchMedia - // - // Arguments: - // mq (String): Media query - // - // Returns: - // (Boolean): Whether the media query passes or not - match : function (mq) { - return window.matchMedia(mq).matches; - }, - - // Description: - // Helpers for checking Foundation default media queries with JS - // - // Returns: - // (Boolean): Whether the media query passes or not - - is_small_up : function () { - return this.match(Foundation.media_queries.small); - }, - - is_medium_up : function () { - return this.match(Foundation.media_queries.medium); - }, - - is_large_up : function () { - return this.match(Foundation.media_queries.large); - }, - - is_xlarge_up : function () { - return this.match(Foundation.media_queries.xlarge); - }, - - is_xxlarge_up : function () { - return this.match(Foundation.media_queries.xxlarge); - }, - - is_small_only : function () { - return !this.is_medium_up() && !this.is_large_up() && !this.is_xlarge_up() && !this.is_xxlarge_up(); - }, - - is_medium_only : function () { - return this.is_medium_up() && !this.is_large_up() && !this.is_xlarge_up() && !this.is_xxlarge_up(); - }, - - is_large_only : function () { - return this.is_medium_up() && this.is_large_up() && !this.is_xlarge_up() && !this.is_xxlarge_up(); - }, - - is_xlarge_only : function () { - return this.is_medium_up() && this.is_large_up() && this.is_xlarge_up() && !this.is_xxlarge_up(); - }, - - is_xxlarge_only : function () { - return this.is_medium_up() && this.is_large_up() && this.is_xlarge_up() && this.is_xxlarge_up(); - } - } - }; - - $.fn.foundation = function () { - var args = Array.prototype.slice.call(arguments, 0); - - return this.each(function () { - Foundation.init.apply(Foundation, [this].concat(args)); - return this; - }); - }; - -}(jQuery, window, window.document)); diff --git a/docs.helm.sh/rootfs/public/src/js/custom/headroom.js b/docs.helm.sh/rootfs/public/src/js/custom/headroom.js deleted file mode 100755 index 58c4c336ec..0000000000 --- a/docs.helm.sh/rootfs/public/src/js/custom/headroom.js +++ /dev/null @@ -1,6 +0,0 @@ -/*! - * headroom.js v0.7.0 - Give your page some headroom. Hide your header until you need it - * Copyright (c) 2014 Nick Williams - http://wicky.nillia.ms/headroom.js - * License: MIT - */ -!function(a,b){"use strict";function c(a){this.callback=a,this.ticking=!1}function d(b){return b&&"undefined"!=typeof a&&(b===a||b.nodeType)}function e(a){if(arguments.length<=0)throw new Error("Missing arguments in extend function");var b,c,f=a||{};for(c=1;ca,c=a+this.getViewportHeight()>this.getScrollerHeight();return b||c},toleranceExceeded:function(a,b){return Math.abs(a-this.lastKnownScrollY)>=this.tolerance[b]},shouldUnpin:function(a,b){var c=a>this.lastKnownScrollY,d=a>=this.offset;return c&&d&&b},shouldPin:function(a,b){var c=athis.lastKnownScrollY?"down":"up",c=this.toleranceExceeded(a,b);this.isOutOfBounds(a)||(a<=this.offset?this.top():this.notTop(),this.shouldUnpin(a,c)?this.unpin():this.shouldPin(a,c)&&this.pin(),this.lastKnownScrollY=a)}},g.options={tolerance:{up:0,down:0},offset:0,scroller:a,classes:{pinned:"headroom--pinned",unpinned:"headroom--unpinned",top:"headroom--top",notTop:"headroom--not-top",initial:"headroom"}},g.cutsTheMustard="undefined"!=typeof h&&h.rAF&&h.bind&&h.classList,a.Headroom=g}(window,document); \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/src/js/custom/headroom.min.js b/docs.helm.sh/rootfs/public/src/js/custom/headroom.min.js deleted file mode 100755 index fcf9c18b2c..0000000000 --- a/docs.helm.sh/rootfs/public/src/js/custom/headroom.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * headroom.js v0.7.0 - Give your page some headroom. Hide your header until you need it - * Copyright (c) 2014 Nick Williams - http://wicky.nillia.ms/headroom.js - * License: MIT - */ - -!function(a,b){"use strict";function c(a){this.callback=a,this.ticking=!1}function d(b){return b&&"undefined"!=typeof a&&(b===a||b.nodeType)}function e(a){if(arguments.length<=0)throw new Error("Missing arguments in extend function");var b,c,f=a||{};for(c=1;ca,c=a+this.getViewportHeight()>this.getScrollerHeight();return b||c},toleranceExceeded:function(a,b){return Math.abs(a-this.lastKnownScrollY)>=this.tolerance[b]},shouldUnpin:function(a,b){var c=a>this.lastKnownScrollY,d=a>=this.offset;return c&&d&&b},shouldPin:function(a,b){var c=athis.lastKnownScrollY?"down":"up",c=this.toleranceExceeded(a,b);this.isOutOfBounds(a)||(a<=this.offset?this.top():this.notTop(),this.shouldUnpin(a,c)?this.unpin():this.shouldPin(a,c)&&this.pin(),this.lastKnownScrollY=a)}},g.options={tolerance:{up:0,down:0},offset:0,scroller:a,classes:{pinned:"headroom--pinned",unpinned:"headroom--unpinned",top:"headroom--top",notTop:"headroom--not-top",initial:"headroom"}},g.cutsTheMustard="undefined"!=typeof h&&h.rAF&&h.bind&&h.classList,a.Headroom=g}(window,document); \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/src/js/custom/jquery.headroom.min.js b/docs.helm.sh/rootfs/public/src/js/custom/jquery.headroom.min.js deleted file mode 100755 index fcf9c18b2c..0000000000 --- a/docs.helm.sh/rootfs/public/src/js/custom/jquery.headroom.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * headroom.js v0.7.0 - Give your page some headroom. Hide your header until you need it - * Copyright (c) 2014 Nick Williams - http://wicky.nillia.ms/headroom.js - * License: MIT - */ - -!function(a,b){"use strict";function c(a){this.callback=a,this.ticking=!1}function d(b){return b&&"undefined"!=typeof a&&(b===a||b.nodeType)}function e(a){if(arguments.length<=0)throw new Error("Missing arguments in extend function");var b,c,f=a||{};for(c=1;ca,c=a+this.getViewportHeight()>this.getScrollerHeight();return b||c},toleranceExceeded:function(a,b){return Math.abs(a-this.lastKnownScrollY)>=this.tolerance[b]},shouldUnpin:function(a,b){var c=a>this.lastKnownScrollY,d=a>=this.offset;return c&&d&&b},shouldPin:function(a,b){var c=athis.lastKnownScrollY?"down":"up",c=this.toleranceExceeded(a,b);this.isOutOfBounds(a)||(a<=this.offset?this.top():this.notTop(),this.shouldUnpin(a,c)?this.unpin():this.shouldPin(a,c)&&this.pin(),this.lastKnownScrollY=a)}},g.options={tolerance:{up:0,down:0},offset:0,scroller:a,classes:{pinned:"headroom--pinned",unpinned:"headroom--unpinned",top:"headroom--top",notTop:"headroom--not-top",initial:"headroom"}},g.cutsTheMustard="undefined"!=typeof h&&h.rAF&&h.bind&&h.classList,a.Headroom=g}(window,document); \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/src/js/main.js b/docs.helm.sh/rootfs/public/src/js/main.js deleted file mode 100755 index bd8aefb1b4..0000000000 --- a/docs.helm.sh/rootfs/public/src/js/main.js +++ /dev/null @@ -1,2693 +0,0 @@ -/*! - * jQuery JavaScript Library v2.1.1 - * http://jquery.com/ - * - * Includes Sizzle.js - * http://sizzlejs.com/ - * - * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors - * Released under the MIT license - * http://jquery.org/license - * - * Date: 2014-05-01T17:11Z - */ -!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){function c(a){var b=a.length,c=_.type(a);return"function"===c||_.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}function d(a,b,c){if(_.isFunction(b))return _.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return _.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(hb.test(b))return _.filter(b,a,c);b=_.filter(b,a)}return _.grep(a,function(a){return U.call(b,a)>=0!==c})}function e(a,b){for(;(a=a[b])&&1!==a.nodeType;);return a}function f(a){var b=ob[a]={};return _.each(a.match(nb)||[],function(a,c){b[c]=!0}),b}function g(){Z.removeEventListener("DOMContentLoaded",g,!1),a.removeEventListener("load",g,!1),_.ready()}function h(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=_.expando+Math.random()}function i(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(ub,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:tb.test(c)?_.parseJSON(c):c}catch(e){}sb.set(a,b,c)}else c=void 0;return c}function j(){return!0}function k(){return!1}function l(){try{return Z.activeElement}catch(a){}}function m(a,b){return _.nodeName(a,"table")&&_.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function n(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function o(a){var b=Kb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function p(a,b){for(var c=0,d=a.length;d>c;c++)rb.set(a[c],"globalEval",!b||rb.get(b[c],"globalEval"))}function q(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(rb.hasData(a)&&(f=rb.access(a),g=rb.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)_.event.add(b,e,j[e][c])}sb.hasData(a)&&(h=sb.access(a),i=_.extend({},h),sb.set(b,i))}}function r(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&_.nodeName(a,b)?_.merge([a],c):c}function s(a,b){var c=b.nodeName.toLowerCase();"input"===c&&yb.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}function t(b,c){var d,e=_(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:_.css(e[0],"display");return e.detach(),f}function u(a){var b=Z,c=Ob[a];return c||(c=t(a,b),"none"!==c&&c||(Nb=(Nb||_(" - diff --git a/docs.helm.sh/themes/helmdocs/static/images/make-bucket-public.png b/docs.helm.sh/themes/helmdocs/static/images/make-bucket-public.png deleted file mode 100755 index f8a5e17f02..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/images/make-bucket-public.png and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/fonts/fontawesome-webfont.eot b/docs.helm.sh/themes/helmdocs/static/src/fonts/fontawesome-webfont.eot deleted file mode 100644 index e9f60ca953..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/src/fonts/fontawesome-webfont.eot and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/fonts/fontawesome-webfont.otf b/docs.helm.sh/themes/helmdocs/static/src/fonts/fontawesome-webfont.otf deleted file mode 100644 index 401ec0f36e..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/src/fonts/fontawesome-webfont.otf and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/fonts/fontawesome-webfont.svg b/docs.helm.sh/themes/helmdocs/static/src/fonts/fontawesome-webfont.svg deleted file mode 100644 index 855c845e53..0000000000 --- a/docs.helm.sh/themes/helmdocs/static/src/fonts/fontawesome-webfont.svg +++ /dev/null @@ -1,2671 +0,0 @@ - - - - -Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 - By ,,, -Copyright Dave Gandy 2016. All rights reserved. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs.helm.sh/themes/helmdocs/static/src/fonts/fontawesome-webfont.ttf b/docs.helm.sh/themes/helmdocs/static/src/fonts/fontawesome-webfont.ttf deleted file mode 100644 index 35acda2fa1..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/src/fonts/fontawesome-webfont.ttf and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/fonts/fontawesome-webfont.woff b/docs.helm.sh/themes/helmdocs/static/src/fonts/fontawesome-webfont.woff deleted file mode 100644 index 400014a4b0..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/src/fonts/fontawesome-webfont.woff and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/fonts/fontawesome-webfont.woff2 b/docs.helm.sh/themes/helmdocs/static/src/fonts/fontawesome-webfont.woff2 deleted file mode 100644 index 4d13fc6040..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/src/fonts/fontawesome-webfont.woff2 and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/fonts/klinicslabbook-webfont.eot b/docs.helm.sh/themes/helmdocs/static/src/fonts/klinicslabbook-webfont.eot deleted file mode 100755 index 1907bfdc76..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/src/fonts/klinicslabbook-webfont.eot and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/fonts/klinicslabbook-webfont.svg b/docs.helm.sh/themes/helmdocs/static/src/fonts/klinicslabbook-webfont.svg deleted file mode 100755 index 7924220bd1..0000000000 --- a/docs.helm.sh/themes/helmdocs/static/src/fonts/klinicslabbook-webfont.svg +++ /dev/null @@ -1,1900 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/themes/helmdocs/static/src/fonts/klinicslabbook-webfont.ttf b/docs.helm.sh/themes/helmdocs/static/src/fonts/klinicslabbook-webfont.ttf deleted file mode 100755 index acd4f27e4f..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/src/fonts/klinicslabbook-webfont.ttf and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/fonts/klinicslabbook-webfont.woff b/docs.helm.sh/themes/helmdocs/static/src/fonts/klinicslabbook-webfont.woff deleted file mode 100755 index 822179bd19..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/src/fonts/klinicslabbook-webfont.woff and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/fonts/klinicslabbook-webfont.woff2 b/docs.helm.sh/themes/helmdocs/static/src/fonts/klinicslabbook-webfont.woff2 deleted file mode 100755 index c18bf5e6ef..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/src/fonts/klinicslabbook-webfont.woff2 and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/fonts/klinicslabmedium-webfont.eot b/docs.helm.sh/themes/helmdocs/static/src/fonts/klinicslabmedium-webfont.eot deleted file mode 100755 index d2bc3bfd8a..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/src/fonts/klinicslabmedium-webfont.eot and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/fonts/klinicslabmedium-webfont.svg b/docs.helm.sh/themes/helmdocs/static/src/fonts/klinicslabmedium-webfont.svg deleted file mode 100755 index b1e553fb7e..0000000000 --- a/docs.helm.sh/themes/helmdocs/static/src/fonts/klinicslabmedium-webfont.svg +++ /dev/null @@ -1,1884 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/themes/helmdocs/static/src/fonts/klinicslabmedium-webfont.ttf b/docs.helm.sh/themes/helmdocs/static/src/fonts/klinicslabmedium-webfont.ttf deleted file mode 100755 index 994071b3cb..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/src/fonts/klinicslabmedium-webfont.ttf and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/fonts/klinicslabmedium-webfont.woff b/docs.helm.sh/themes/helmdocs/static/src/fonts/klinicslabmedium-webfont.woff deleted file mode 100755 index 643977673a..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/src/fonts/klinicslabmedium-webfont.woff and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/fonts/klinicslabmedium-webfont.woff2 b/docs.helm.sh/themes/helmdocs/static/src/fonts/klinicslabmedium-webfont.woff2 deleted file mode 100755 index 55651e0b5a..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/src/fonts/klinicslabmedium-webfont.woff2 and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/img/apple-touch-icon-precomposed.png b/docs.helm.sh/themes/helmdocs/static/src/img/apple-touch-icon-precomposed.png deleted file mode 100644 index dbaab15c5b..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/src/img/apple-touch-icon-precomposed.png and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/img/apple-touch-icon.png b/docs.helm.sh/themes/helmdocs/static/src/img/apple-touch-icon.png deleted file mode 100644 index 858f1ab3b0..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/src/img/apple-touch-icon.png and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/img/bitnami.png b/docs.helm.sh/themes/helmdocs/static/src/img/bitnami.png deleted file mode 100644 index 6a2939e2b2..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/src/img/bitnami.png and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/img/boat.png b/docs.helm.sh/themes/helmdocs/static/src/img/boat.png deleted file mode 100644 index ae48314547..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/src/img/boat.png and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/img/btn-get-helm.png b/docs.helm.sh/themes/helmdocs/static/src/img/btn-get-helm.png deleted file mode 100644 index e20e1cd093..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/src/img/btn-get-helm.png and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/img/chart-illustration.png b/docs.helm.sh/themes/helmdocs/static/src/img/chart-illustration.png deleted file mode 100644 index f0406fefd9..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/src/img/chart-illustration.png and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/img/deis-logo-white.png b/docs.helm.sh/themes/helmdocs/static/src/img/deis-logo-white.png deleted file mode 100644 index c4abd7954b..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/src/img/deis-logo-white.png and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/img/favicon-152.png b/docs.helm.sh/themes/helmdocs/static/src/img/favicon-152.png deleted file mode 100755 index 0b2c9250d3..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/src/img/favicon-152.png and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/img/favicon.ico b/docs.helm.sh/themes/helmdocs/static/src/img/favicon.ico deleted file mode 100755 index 883ad37bd5..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/src/img/favicon.ico and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/img/favicon.png b/docs.helm.sh/themes/helmdocs/static/src/img/favicon.png deleted file mode 100755 index 0b2c9250d3..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/src/img/favicon.png and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/img/feature-icon-1.png b/docs.helm.sh/themes/helmdocs/static/src/img/feature-icon-1.png deleted file mode 100644 index 651523c904..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/src/img/feature-icon-1.png and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/img/feature-icon-2.png b/docs.helm.sh/themes/helmdocs/static/src/img/feature-icon-2.png deleted file mode 100644 index 1760a25d80..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/src/img/feature-icon-2.png and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/img/feature-icon-3.png b/docs.helm.sh/themes/helmdocs/static/src/img/feature-icon-3.png deleted file mode 100644 index 561b6b69f2..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/src/img/feature-icon-3.png and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/img/feature-icon-4.png b/docs.helm.sh/themes/helmdocs/static/src/img/feature-icon-4.png deleted file mode 100644 index fb81c99f19..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/src/img/feature-icon-4.png and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/img/features-bg.png b/docs.helm.sh/themes/helmdocs/static/src/img/features-bg.png deleted file mode 100644 index 4c4cdf1584..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/src/img/features-bg.png and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/img/fish.png b/docs.helm.sh/themes/helmdocs/static/src/img/fish.png deleted file mode 100644 index daf01fbcb1..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/src/img/fish.png and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/img/google.png b/docs.helm.sh/themes/helmdocs/static/src/img/google.png deleted file mode 100755 index 491f6d4a7d..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/src/img/google.png and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/img/helm-blue-vector.svg b/docs.helm.sh/themes/helmdocs/static/src/img/helm-blue-vector.svg deleted file mode 100644 index b8707ba909..0000000000 --- a/docs.helm.sh/themes/helmdocs/static/src/img/helm-blue-vector.svg +++ /dev/null @@ -1,27 +0,0 @@ - - - - logo - Created with Sketch. - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/themes/helmdocs/static/src/img/helm-charts.png b/docs.helm.sh/themes/helmdocs/static/src/img/helm-charts.png deleted file mode 100644 index 486734bc32..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/src/img/helm-charts.png and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/img/helm-footer-logo.png b/docs.helm.sh/themes/helmdocs/static/src/img/helm-footer-logo.png deleted file mode 100644 index 582aca8fbd..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/src/img/helm-footer-logo.png and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/img/helm-logo-deis.png b/docs.helm.sh/themes/helmdocs/static/src/img/helm-logo-deis.png deleted file mode 100644 index 04f7226712..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/src/img/helm-logo-deis.png and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/img/helm-logo-microsoft.png b/docs.helm.sh/themes/helmdocs/static/src/img/helm-logo-microsoft.png deleted file mode 100644 index 5ae834e55b..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/src/img/helm-logo-microsoft.png and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/img/helm-logo-microsoft.svg b/docs.helm.sh/themes/helmdocs/static/src/img/helm-logo-microsoft.svg deleted file mode 100644 index 2ea2487b60..0000000000 --- a/docs.helm.sh/themes/helmdocs/static/src/img/helm-logo-microsoft.svg +++ /dev/null @@ -1,38 +0,0 @@ - - - - Group 4 - Created with Sketch. - - - - - - - supported by - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/themes/helmdocs/static/src/img/helm-logo.svg b/docs.helm.sh/themes/helmdocs/static/src/img/helm-logo.svg deleted file mode 100644 index 6014e6d049..0000000000 --- a/docs.helm.sh/themes/helmdocs/static/src/img/helm-logo.svg +++ /dev/null @@ -1 +0,0 @@ -helm-logo \ No newline at end of file diff --git a/docs.helm.sh/themes/helmdocs/static/src/img/helm-white-vector.svg b/docs.helm.sh/themes/helmdocs/static/src/img/helm-white-vector.svg deleted file mode 100644 index 4b5163d8f3..0000000000 --- a/docs.helm.sh/themes/helmdocs/static/src/img/helm-white-vector.svg +++ /dev/null @@ -1,27 +0,0 @@ - - - - logo white - Created with Sketch. - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/themes/helmdocs/static/src/img/logo-with-deis.png b/docs.helm.sh/themes/helmdocs/static/src/img/logo-with-deis.png deleted file mode 100644 index ff86836526..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/src/img/logo-with-deis.png and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/img/logo.png b/docs.helm.sh/themes/helmdocs/static/src/img/logo.png deleted file mode 100644 index bcf6bb58de..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/src/img/logo.png and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/img/microsoft.png b/docs.helm.sh/themes/helmdocs/static/src/img/microsoft.png deleted file mode 100644 index 8e833c0273..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/src/img/microsoft.png and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/img/microsoft.svg b/docs.helm.sh/themes/helmdocs/static/src/img/microsoft.svg deleted file mode 100644 index 0247141da5..0000000000 --- a/docs.helm.sh/themes/helmdocs/static/src/img/microsoft.svg +++ /dev/null @@ -1,22 +0,0 @@ - - - - microsoft - Created with Sketch. - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs.helm.sh/themes/helmdocs/static/src/img/pattern-topo-sm.png b/docs.helm.sh/themes/helmdocs/static/src/img/pattern-topo-sm.png deleted file mode 100644 index 16cb86d9f9..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/src/img/pattern-topo-sm.png and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/img/pattern-topo-white.png b/docs.helm.sh/themes/helmdocs/static/src/img/pattern-topo-white.png deleted file mode 100644 index 532ca91438..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/src/img/pattern-topo-white.png and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/img/pattern-topo.png b/docs.helm.sh/themes/helmdocs/static/src/img/pattern-topo.png deleted file mode 100644 index 4d76654162..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/src/img/pattern-topo.png and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/img/pattern-waves.png b/docs.helm.sh/themes/helmdocs/static/src/img/pattern-waves.png deleted file mode 100644 index 1f31795240..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/src/img/pattern-waves.png and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/img/skippbox.png b/docs.helm.sh/themes/helmdocs/static/src/img/skippbox.png deleted file mode 100644 index a2ea7adae8..0000000000 Binary files a/docs.helm.sh/themes/helmdocs/static/src/img/skippbox.png and /dev/null differ diff --git a/docs.helm.sh/themes/helmdocs/static/src/js/custom/app_init.js b/docs.helm.sh/themes/helmdocs/static/src/js/custom/app_init.js deleted file mode 100755 index 46160a1c01..0000000000 --- a/docs.helm.sh/themes/helmdocs/static/src/js/custom/app_init.js +++ /dev/null @@ -1,75 +0,0 @@ -$(document).ready(function() { - $(document).foundation(); - - // custom theme js for sidebar links - var allClosed; - - // close all accordions, besides that of the page that is currently active - var doclocation = window.location.pathname; - var docpath = doclocation.substring(0, doclocation.lastIndexOf("/")); - var directoryName = docpath.substring(docpath.lastIndexOf("/")+1); - $(".toctree-l1 > a[href='" + directoryName + "']").addClass('active').attr({state: "open"}); - - if (allClosed === true) { } - - // if menu is closed when clicked, expand it - $('.toctree-l1 > a').click(function() { - - //Make the titles of open accordions dead links - if ($(this).attr('state') == 'open') {return false;} - - //Clicking on a title of a closed accordion - if($(this).attr('state') != 'open' && $(this).siblings().size() > 0) { - $('.toctree-l1 > ul').hide(); - $('.toctree-l1 > a').attr('state', ''); - $(this).attr('state', 'open'); - $(this).next().slideDown(function(){}); - return false; - } - }); -}); // document ready - - -// headroom -(function() { - var searchBar = document.querySelector(".top-bar"); - new Headroom(searchBar, { - offset: 50, - classes: { - "initial": "headroom", - "pinned": "headroom--pinned", - "unpinned": "headroom--unpinned", - "top" : "headroom--top", - "notTop" : "headroom--not-top" - } - }).init(); -}()); - -// add permalinks to titles -$(function() { - return $("h1, h2, h3, h4, h5, h6").each(function(i, el) { - var $el, icon, id; - $el = $(el); - id = $el.attr('id'); - icon = ''; - if (id) { - return $el.prepend($("").addClass("header-link").attr("href", "#" + id).html(icon)); - } - }); -}); - -// smooth scroll -$(function() { - $('a[href*=#]:not([href=#])').click(function() { - if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) { - var target = $(this.hash); - target = target.length ? target : $('[name=' + this.hash.slice(1) +']'); - if (target.length) { - $('html,body').animate({ - scrollTop: target.offset().top - }, 400); - // return false; - } - } - }); -}); diff --git a/docs.helm.sh/themes/helmdocs/static/src/js/custom/foundation.accordion.js b/docs.helm.sh/themes/helmdocs/static/src/js/custom/foundation.accordion.js deleted file mode 100755 index be329ae66f..0000000000 --- a/docs.helm.sh/themes/helmdocs/static/src/js/custom/foundation.accordion.js +++ /dev/null @@ -1,125 +0,0 @@ -;(function ($, window, document, undefined) { - 'use strict'; - - Foundation.libs.accordion = { - name : 'accordion', - - version : '5.5.3', - - settings : { - content_class : 'content', - active_class : 'active', - multi_expand : false, - toggleable : true, - callback : function () {} - }, - - init : function (scope, method, options) { - this.bindings(method, options); - }, - - events : function (instance) { - var self = this; - var S = this.S; - self.create(this.S(instance)); - - S(this.scope) - .off('.fndtn.accordion') - .on('click.fndtn.accordion', '[' + this.attr_name() + '] > dd > a, [' + this.attr_name() + '] > li > a', function (e) { - var accordion = S(this).closest('[' + self.attr_name() + ']'), - groupSelector = self.attr_name() + '=' + accordion.attr(self.attr_name()), - settings = accordion.data(self.attr_name(true) + '-init') || self.settings, - target = S('#' + this.href.split('#')[1]), - aunts = $('> dd, > li', accordion), - siblings = aunts.children('.' + settings.content_class), - active_content = siblings.filter('.' + settings.active_class); - - e.preventDefault(); - - if (accordion.attr(self.attr_name())) { - siblings = siblings.add('[' + groupSelector + '] dd > ' + '.' + settings.content_class + ', [' + groupSelector + '] li > ' + '.' + settings.content_class); - aunts = aunts.add('[' + groupSelector + '] dd, [' + groupSelector + '] li'); - } - - if (settings.toggleable && target.is(active_content)) { - target.parent('dd, li').toggleClass(settings.active_class, false); - target.toggleClass(settings.active_class, false); - S(this).attr('aria-expanded', function(i, attr){ - return attr === 'true' ? 'false' : 'true'; - }); - settings.callback(target); - target.triggerHandler('toggled', [accordion]); - accordion.triggerHandler('toggled', [target]); - return; - } - - if (!settings.multi_expand) { - siblings.removeClass(settings.active_class); - aunts.removeClass(settings.active_class); - aunts.children('a').attr('aria-expanded','false'); - } - - target.addClass(settings.active_class).parent().addClass(settings.active_class); - settings.callback(target); - target.triggerHandler('toggled', [accordion]); - accordion.triggerHandler('toggled', [target]); - S(this).attr('aria-expanded','true'); - }); - }, - - create: function($instance) { - var self = this, - accordion = $instance, - aunts = $('> .accordion-navigation', accordion), - settings = accordion.data(self.attr_name(true) + '-init') || self.settings; - - aunts.children('a').attr('aria-expanded','false'); - aunts.has('.' + settings.content_class + '.' + settings.active_class).addClass(settings.active_class).children('a').attr('aria-expanded','true'); - - if (settings.multi_expand) { - $instance.attr('aria-multiselectable','true'); - } - }, - - toggle : function(options) { - var options = typeof options !== 'undefined' ? options : {}; - var selector = typeof options.selector !== 'undefined' ? options.selector : ''; - var toggle_state = typeof options.toggle_state !== 'undefined' ? options.toggle_state : ''; - var $accordion = typeof options.$accordion !== 'undefined' ? options.$accordion : this.S(this.scope).closest('[' + this.attr_name() + ']'); - - var $items = $accordion.find('> dd' + selector + ', > li' + selector); - if ( $items.length < 1 ) { - if ( window.console ) { - console.error('Selection not found.', selector); - } - return false; - } - - var S = this.S; - var active_class = this.settings.active_class; - $items.each(function() { - var $item = S(this); - var is_active = $item.hasClass(active_class); - if ( ( is_active && toggle_state === 'close' ) || ( !is_active && toggle_state === 'open' ) || toggle_state === '' ) { - $item.find('> a').trigger('click.fndtn.accordion'); - } - }); - }, - - open : function(options) { - var options = typeof options !== 'undefined' ? options : {}; - options.toggle_state = 'open'; - this.toggle(options); - }, - - close : function(options) { - var options = typeof options !== 'undefined' ? options : {}; - options.toggle_state = 'close'; - this.toggle(options); - }, - - off : function () {}, - - reflow : function () {} - }; -}(jQuery, window, window.document)); diff --git a/docs.helm.sh/themes/helmdocs/static/src/js/custom/foundation.dropdown.js b/docs.helm.sh/themes/helmdocs/static/src/js/custom/foundation.dropdown.js deleted file mode 100755 index 5db3dea6db..0000000000 --- a/docs.helm.sh/themes/helmdocs/static/src/js/custom/foundation.dropdown.js +++ /dev/null @@ -1,468 +0,0 @@ -;(function ($, window, document, undefined) { - 'use strict'; - - Foundation.libs.dropdown = { - name : 'dropdown', - - version : '5.5.3', - - settings : { - active_class : 'open', - disabled_class : 'disabled', - mega_class : 'mega', - align : 'bottom', - is_hover : false, - hover_timeout : 150, - opened : function () {}, - closed : function () {} - }, - - init : function (scope, method, options) { - Foundation.inherit(this, 'throttle'); - - $.extend(true, this.settings, method, options); - this.bindings(method, options); - }, - - events : function (scope) { - var self = this, - S = self.S; - - S(this.scope) - .off('.dropdown') - .on('click.fndtn.dropdown', '[' + this.attr_name() + ']', function (e) { - var settings = S(this).data(self.attr_name(true) + '-init') || self.settings; - if (!settings.is_hover || Modernizr.touch) { - e.preventDefault(); - if (S(this).parent('[data-reveal-id]').length) { - e.stopPropagation(); - } - self.toggle($(this)); - } - }) - .on('mouseenter.fndtn.dropdown', '[' + this.attr_name() + '], [' + this.attr_name() + '-content]', function (e) { - var $this = S(this), - dropdown, - target; - - clearTimeout(self.timeout); - - if ($this.data(self.data_attr())) { - dropdown = S('#' + $this.data(self.data_attr())); - target = $this; - } else { - dropdown = $this; - target = S('[' + self.attr_name() + '="' + dropdown.attr('id') + '"]'); - } - - var settings = target.data(self.attr_name(true) + '-init') || self.settings; - - if (S(e.currentTarget).data(self.data_attr()) && settings.is_hover) { - self.closeall.call(self); - } - - if (settings.is_hover) { - self.open.apply(self, [dropdown, target]); - } - }) - .on('mouseleave.fndtn.dropdown', '[' + this.attr_name() + '], [' + this.attr_name() + '-content]', function (e) { - var $this = S(this); - var settings; - - if ($this.data(self.data_attr())) { - settings = $this.data(self.data_attr(true) + '-init') || self.settings; - } else { - var target = S('[' + self.attr_name() + '="' + S(this).attr('id') + '"]'), - settings = target.data(self.attr_name(true) + '-init') || self.settings; - } - - self.timeout = setTimeout(function () { - if ($this.data(self.data_attr())) { - if (settings.is_hover) { - self.close.call(self, S('#' + $this.data(self.data_attr()))); - } - } else { - if (settings.is_hover) { - self.close.call(self, $this); - } - } - }.bind(this), settings.hover_timeout); - }) - .on('click.fndtn.dropdown', function (e) { - var parent = S(e.target).closest('[' + self.attr_name() + '-content]'); - var links = parent.find('a'); - - if (links.length > 0 && parent.attr('aria-autoclose') !== 'false') { - self.close.call(self, S('[' + self.attr_name() + '-content]')); - } - - if (e.target !== document && !$.contains(document.documentElement, e.target)) { - return; - } - - if (S(e.target).closest('[' + self.attr_name() + ']').length > 0) { - return; - } - - if (!(S(e.target).data('revealId')) && - (parent.length > 0 && (S(e.target).is('[' + self.attr_name() + '-content]') || - $.contains(parent.first()[0], e.target)))) { - e.stopPropagation(); - return; - } - - self.close.call(self, S('[' + self.attr_name() + '-content]')); - }) - .on('opened.fndtn.dropdown', '[' + self.attr_name() + '-content]', function () { - self.settings.opened.call(this); - }) - .on('closed.fndtn.dropdown', '[' + self.attr_name() + '-content]', function () { - self.settings.closed.call(this); - }); - - S(window) - .off('.dropdown') - .on('resize.fndtn.dropdown', self.throttle(function () { - self.resize.call(self); - }, 50)); - - this.resize(); - }, - - close : function (dropdown) { - var self = this; - dropdown.each(function (idx) { - var original_target = $('[' + self.attr_name() + '=' + dropdown[idx].id + ']') || $('aria-controls=' + dropdown[idx].id + ']'); - original_target.attr('aria-expanded', 'false'); - if (self.S(this).hasClass(self.settings.active_class)) { - self.S(this) - .css(Foundation.rtl ? 'right' : 'left', '-99999px') - .attr('aria-hidden', 'true') - .removeClass(self.settings.active_class) - .prev('[' + self.attr_name() + ']') - .removeClass(self.settings.active_class) - .removeData('target'); - - self.S(this).trigger('closed.fndtn.dropdown', [dropdown]); - } - }); - dropdown.removeClass('f-open-' + this.attr_name(true)); - }, - - closeall : function () { - var self = this; - $.each(self.S('.f-open-' + this.attr_name(true)), function () { - self.close.call(self, self.S(this)); - }); - }, - - open : function (dropdown, target) { - this - .css(dropdown - .addClass(this.settings.active_class), target); - dropdown.prev('[' + this.attr_name() + ']').addClass(this.settings.active_class); - dropdown.data('target', target.get(0)).trigger('opened.fndtn.dropdown', [dropdown, target]); - dropdown.attr('aria-hidden', 'false'); - target.attr('aria-expanded', 'true'); - dropdown.focus(); - dropdown.addClass('f-open-' + this.attr_name(true)); - }, - - data_attr : function () { - if (this.namespace.length > 0) { - return this.namespace + '-' + this.name; - } - - return this.name; - }, - - toggle : function (target) { - if (target.hasClass(this.settings.disabled_class)) { - return; - } - var dropdown = this.S('#' + target.data(this.data_attr())); - if (dropdown.length === 0) { - // No dropdown found, not continuing - return; - } - - this.close.call(this, this.S('[' + this.attr_name() + '-content]').not(dropdown)); - - if (dropdown.hasClass(this.settings.active_class)) { - this.close.call(this, dropdown); - if (dropdown.data('target') !== target.get(0)) { - this.open.call(this, dropdown, target); - } - } else { - this.open.call(this, dropdown, target); - } - }, - - resize : function () { - var dropdown = this.S('[' + this.attr_name() + '-content].open'); - var target = $(dropdown.data("target")); - - if (dropdown.length && target.length) { - this.css(dropdown, target); - } - }, - - css : function (dropdown, target) { - var left_offset = Math.max((target.width() - dropdown.width()) / 2, 8), - settings = target.data(this.attr_name(true) + '-init') || this.settings, - parentOverflow = dropdown.parent().css('overflow-y') || dropdown.parent().css('overflow'); - - this.clear_idx(); - - - - if (this.small()) { - var p = this.dirs.bottom.call(dropdown, target, settings); - - dropdown.attr('style', '').removeClass('drop-left drop-right drop-top').css({ - position : 'absolute', - width : '95%', - 'max-width' : 'none', - top : p.top - }); - - dropdown.css(Foundation.rtl ? 'right' : 'left', left_offset); - } - // detect if dropdown is in an overflow container - else if (parentOverflow !== 'visible') { - var offset = target[0].offsetTop + target[0].offsetHeight; - - dropdown.attr('style', '').css({ - position : 'absolute', - top : offset - }); - - dropdown.css(Foundation.rtl ? 'right' : 'left', left_offset); - } - else { - - this.style(dropdown, target, settings); - } - - return dropdown; - }, - - style : function (dropdown, target, settings) { - var css = $.extend({position : 'absolute'}, - this.dirs[settings.align].call(dropdown, target, settings)); - - dropdown.attr('style', '').css(css); - }, - - // return CSS property object - // `this` is the dropdown - dirs : { - // Calculate target offset - _base : function (t, s) { - var o_p = this.offsetParent(), - o = o_p.offset(), - p = t.offset(); - - p.top -= o.top; - p.left -= o.left; - - //set some flags on the p object to pass along - p.missRight = false; - p.missTop = false; - p.missLeft = false; - p.leftRightFlag = false; - - //lets see if the panel will be off the screen - //get the actual width of the page and store it - var actualBodyWidth; - var windowWidth = window.innerWidth; - - if (document.getElementsByClassName('row')[0]) { - actualBodyWidth = document.getElementsByClassName('row')[0].clientWidth; - } else { - actualBodyWidth = windowWidth; - } - - var actualMarginWidth = (windowWidth - actualBodyWidth) / 2; - var actualBoundary = actualBodyWidth; - - if (!this.hasClass('mega') && !s.ignore_repositioning) { - var outerWidth = this.outerWidth(); - var o_left = t.offset().left; - - //miss top - if (t.offset().top <= this.outerHeight()) { - p.missTop = true; - actualBoundary = windowWidth - actualMarginWidth; - p.leftRightFlag = true; - } - - //miss right - if (o_left + outerWidth > o_left + actualMarginWidth && o_left - actualMarginWidth > outerWidth) { - p.missRight = true; - p.missLeft = false; - } - - //miss left - if (o_left - outerWidth <= 0) { - p.missLeft = true; - p.missRight = false; - } - } - - return p; - }, - - top : function (t, s) { - var self = Foundation.libs.dropdown, - p = self.dirs._base.call(this, t, s); - - this.addClass('drop-top'); - - if (p.missTop == true) { - p.top = p.top + t.outerHeight() + this.outerHeight(); - this.removeClass('drop-top'); - } - - if (p.missRight == true) { - p.left = p.left - this.outerWidth() + t.outerWidth(); - } - - if (t.outerWidth() < this.outerWidth() || self.small() || this.hasClass(s.mega_menu)) { - self.adjust_pip(this, t, s, p); - } - - if (Foundation.rtl) { - return {left : p.left - this.outerWidth() + t.outerWidth(), - top : p.top - this.outerHeight()}; - } - - return {left : p.left, top : p.top - this.outerHeight()}; - }, - - bottom : function (t, s) { - var self = Foundation.libs.dropdown, - p = self.dirs._base.call(this, t, s); - - if (p.missRight == true) { - p.left = p.left - this.outerWidth() + t.outerWidth(); - } - - if (t.outerWidth() < this.outerWidth() || self.small() || this.hasClass(s.mega_menu)) { - self.adjust_pip(this, t, s, p); - } - - if (self.rtl) { - return {left : p.left - this.outerWidth() + t.outerWidth(), top : p.top + t.outerHeight()}; - } - - return {left : p.left, top : p.top + t.outerHeight()}; - }, - - left : function (t, s) { - var p = Foundation.libs.dropdown.dirs._base.call(this, t, s); - - this.addClass('drop-left'); - - if (p.missLeft == true) { - p.left = p.left + this.outerWidth(); - p.top = p.top + t.outerHeight(); - this.removeClass('drop-left'); - } - - return {left : p.left - this.outerWidth(), top : p.top}; - }, - - right : function (t, s) { - var p = Foundation.libs.dropdown.dirs._base.call(this, t, s); - - this.addClass('drop-right'); - - if (p.missRight == true) { - p.left = p.left - this.outerWidth(); - p.top = p.top + t.outerHeight(); - this.removeClass('drop-right'); - } else { - p.triggeredRight = true; - } - - var self = Foundation.libs.dropdown; - - if (t.outerWidth() < this.outerWidth() || self.small() || this.hasClass(s.mega_menu)) { - self.adjust_pip(this, t, s, p); - } - - return {left : p.left + t.outerWidth(), top : p.top}; - } - }, - - // Insert rule to style psuedo elements - adjust_pip : function (dropdown, target, settings, position) { - var sheet = Foundation.stylesheet, - pip_offset_base = 8; - - if (dropdown.hasClass(settings.mega_class)) { - pip_offset_base = position.left + (target.outerWidth() / 2) - 8; - } else if (this.small()) { - pip_offset_base += position.left - 8; - } - - this.rule_idx = sheet.cssRules.length; - - //default - var sel_before = '.f-dropdown.open:before', - sel_after = '.f-dropdown.open:after', - css_before = 'left: ' + pip_offset_base + 'px;', - css_after = 'left: ' + (pip_offset_base - 1) + 'px;'; - - if (position.missRight == true) { - pip_offset_base = dropdown.outerWidth() - 23; - sel_before = '.f-dropdown.open:before', - sel_after = '.f-dropdown.open:after', - css_before = 'left: ' + pip_offset_base + 'px;', - css_after = 'left: ' + (pip_offset_base - 1) + 'px;'; - } - - //just a case where right is fired, but its not missing right - if (position.triggeredRight == true) { - sel_before = '.f-dropdown.open:before', - sel_after = '.f-dropdown.open:after', - css_before = 'left:-12px;', - css_after = 'left:-14px;'; - } - - if (sheet.insertRule) { - sheet.insertRule([sel_before, '{', css_before, '}'].join(' '), this.rule_idx); - sheet.insertRule([sel_after, '{', css_after, '}'].join(' '), this.rule_idx + 1); - } else { - sheet.addRule(sel_before, css_before, this.rule_idx); - sheet.addRule(sel_after, css_after, this.rule_idx + 1); - } - }, - - // Remove old dropdown rule index - clear_idx : function () { - var sheet = Foundation.stylesheet; - - if (typeof this.rule_idx !== 'undefined') { - sheet.deleteRule(this.rule_idx); - sheet.deleteRule(this.rule_idx); - delete this.rule_idx; - } - }, - - small : function () { - return matchMedia(Foundation.media_queries.small).matches && - !matchMedia(Foundation.media_queries.medium).matches; - }, - - off : function () { - this.S(this.scope).off('.fndtn.dropdown'); - this.S('html, body').off('.fndtn.dropdown'); - this.S(window).off('.fndtn.dropdown'); - this.S('[data-dropdown-content]').off('.fndtn.dropdown'); - }, - - reflow : function () {} - }; -}(jQuery, window, window.document)); diff --git a/docs.helm.sh/themes/helmdocs/static/src/js/custom/foundation.js b/docs.helm.sh/themes/helmdocs/static/src/js/custom/foundation.js deleted file mode 100755 index c5a359d3b6..0000000000 --- a/docs.helm.sh/themes/helmdocs/static/src/js/custom/foundation.js +++ /dev/null @@ -1,732 +0,0 @@ -/* - * Foundation Responsive Library - * http://foundation.zurb.com - * Copyright 2015, ZURB - * Free to use under the MIT license. - * http://www.opensource.org/licenses/mit-license.php -*/ - -(function ($, window, document, undefined) { - 'use strict'; - - var header_helpers = function (class_array) { - var head = $('head'); - head.prepend($.map(class_array, function (class_name) { - if (head.has('.' + class_name).length === 0) { - return ''; - } - })); - }; - - header_helpers([ - 'foundation-mq-small', - 'foundation-mq-small-only', - 'foundation-mq-medium', - 'foundation-mq-medium-only', - 'foundation-mq-large', - 'foundation-mq-large-only', - 'foundation-mq-xlarge', - 'foundation-mq-xlarge-only', - 'foundation-mq-xxlarge', - 'foundation-data-attribute-namespace']); - - // Enable FastClick if present - - $(function () { - if (typeof FastClick !== 'undefined') { - // Don't attach to body if undefined - if (typeof document.body !== 'undefined') { - FastClick.attach(document.body); - } - } - }); - - // private Fast Selector wrapper, - // returns jQuery object. Only use where - // getElementById is not available. - var S = function (selector, context) { - if (typeof selector === 'string') { - if (context) { - var cont; - if (context.jquery) { - cont = context[0]; - if (!cont) { - return context; - } - } else { - cont = context; - } - return $(cont.querySelectorAll(selector)); - } - - return $(document.querySelectorAll(selector)); - } - - return $(selector, context); - }; - - // Namespace functions. - - var attr_name = function (init) { - var arr = []; - if (!init) { - arr.push('data'); - } - if (this.namespace.length > 0) { - arr.push(this.namespace); - } - arr.push(this.name); - - return arr.join('-'); - }; - - var add_namespace = function (str) { - var parts = str.split('-'), - i = parts.length, - arr = []; - - while (i--) { - if (i !== 0) { - arr.push(parts[i]); - } else { - if (this.namespace.length > 0) { - arr.push(this.namespace, parts[i]); - } else { - arr.push(parts[i]); - } - } - } - - return arr.reverse().join('-'); - }; - - // Event binding and data-options updating. - - var bindings = function (method, options) { - var self = this, - bind = function(){ - var $this = S(this), - should_bind_events = !$this.data(self.attr_name(true) + '-init'); - $this.data(self.attr_name(true) + '-init', $.extend({}, self.settings, (options || method), self.data_options($this))); - - if (should_bind_events) { - self.events(this); - } - }; - - if (S(this.scope).is('[' + this.attr_name() +']')) { - bind.call(this.scope); - } else { - S('[' + this.attr_name() +']', this.scope).each(bind); - } - // # Patch to fix #5043 to move this *after* the if/else clause in order for Backbone and similar frameworks to have improved control over event binding and data-options updating. - if (typeof method === 'string') { - return this[method].call(this, options); - } - - }; - - var single_image_loaded = function (image, callback) { - function loaded () { - callback(image[0]); - } - - function bindLoad () { - this.one('load', loaded); - - if (/MSIE (\d+\.\d+);/.test(navigator.userAgent)) { - var src = this.attr( 'src' ), - param = src.match( /\?/ ) ? '&' : '?'; - - param += 'random=' + (new Date()).getTime(); - this.attr('src', src + param); - } - } - - if (!image.attr('src')) { - loaded(); - return; - } - - if (image[0].complete || image[0].readyState === 4) { - loaded(); - } else { - bindLoad.call(image); - } - }; - - /*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas, David Knight. Dual MIT/BSD license */ - - window.matchMedia || (window.matchMedia = function() { - "use strict"; - - // For browsers that support matchMedium api such as IE 9 and webkit - var styleMedia = (window.styleMedia || window.media); - - // For those that don't support matchMedium - if (!styleMedia) { - var style = document.createElement('style'), - script = document.getElementsByTagName('script')[0], - info = null; - - style.type = 'text/css'; - style.id = 'matchmediajs-test'; - - script.parentNode.insertBefore(style, script); - - // 'style.currentStyle' is used by IE <= 8 and 'window.getComputedStyle' for all other browsers - info = ('getComputedStyle' in window) && window.getComputedStyle(style, null) || style.currentStyle; - - styleMedia = { - matchMedium: function(media) { - var text = '@media ' + media + '{ #matchmediajs-test { width: 1px; } }'; - - // 'style.styleSheet' is used by IE <= 8 and 'style.textContent' for all other browsers - if (style.styleSheet) { - style.styleSheet.cssText = text; - } else { - style.textContent = text; - } - - // Test if media query is true or false - return info.width === '1px'; - } - }; - } - - return function(media) { - return { - matches: styleMedia.matchMedium(media || 'all'), - media: media || 'all' - }; - }; - }()); - - /* - * jquery.requestAnimationFrame - * https://github.com/gnarf37/jquery-requestAnimationFrame - * Requires jQuery 1.8+ - * - * Copyright (c) 2012 Corey Frang - * Licensed under the MIT license. - */ - - (function(jQuery) { - - - // requestAnimationFrame polyfill adapted from Erik Möller - // fixes from Paul Irish and Tino Zijdel - // http://paulirish.com/2011/requestanimationframe-for-smart-animating/ - // http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating - - var animating, - lastTime = 0, - vendors = ['webkit', 'moz'], - requestAnimationFrame = window.requestAnimationFrame, - cancelAnimationFrame = window.cancelAnimationFrame, - jqueryFxAvailable = 'undefined' !== typeof jQuery.fx; - - for (; lastTime < vendors.length && !requestAnimationFrame; lastTime++) { - requestAnimationFrame = window[ vendors[lastTime] + 'RequestAnimationFrame' ]; - cancelAnimationFrame = cancelAnimationFrame || - window[ vendors[lastTime] + 'CancelAnimationFrame' ] || - window[ vendors[lastTime] + 'CancelRequestAnimationFrame' ]; - } - - function raf() { - if (animating) { - requestAnimationFrame(raf); - - if (jqueryFxAvailable) { - jQuery.fx.tick(); - } - } - } - - if (requestAnimationFrame) { - // use rAF - window.requestAnimationFrame = requestAnimationFrame; - window.cancelAnimationFrame = cancelAnimationFrame; - - if (jqueryFxAvailable) { - jQuery.fx.timer = function (timer) { - if (timer() && jQuery.timers.push(timer) && !animating) { - animating = true; - raf(); - } - }; - - jQuery.fx.stop = function () { - animating = false; - }; - } - } else { - // polyfill - window.requestAnimationFrame = function (callback) { - var currTime = new Date().getTime(), - timeToCall = Math.max(0, 16 - (currTime - lastTime)), - id = window.setTimeout(function () { - callback(currTime + timeToCall); - }, timeToCall); - lastTime = currTime + timeToCall; - return id; - }; - - window.cancelAnimationFrame = function (id) { - clearTimeout(id); - }; - - } - - }( $ )); - - function removeQuotes (string) { - if (typeof string === 'string' || string instanceof String) { - string = string.replace(/^['\\/"]+|(;\s?})+|['\\/"]+$/g, ''); - } - - return string; - } - - function MediaQuery(selector) { - this.selector = selector; - this.query = ''; - } - - MediaQuery.prototype.toString = function () { - return this.query || (this.query = S(this.selector).css('font-family').replace(/^[\/\\'"]+|(;\s?})+|[\/\\'"]+$/g, '')); - }; - - window.Foundation = { - name : 'Foundation', - - version : '5.5.3', - - media_queries : { - 'small' : new MediaQuery('.foundation-mq-small'), - 'small-only' : new MediaQuery('.foundation-mq-small-only'), - 'medium' : new MediaQuery('.foundation-mq-medium'), - 'medium-only' : new MediaQuery('.foundation-mq-medium-only'), - 'large' : new MediaQuery('.foundation-mq-large'), - 'large-only' : new MediaQuery('.foundation-mq-large-only'), - 'xlarge' : new MediaQuery('.foundation-mq-xlarge'), - 'xlarge-only' : new MediaQuery('.foundation-mq-xlarge-only'), - 'xxlarge' : new MediaQuery('.foundation-mq-xxlarge') - }, - - stylesheet : $('').appendTo('head')[0].sheet, - - global : { - namespace : undefined - }, - - init : function (scope, libraries, method, options, response) { - var args = [scope, method, options, response], - responses = []; - - // check RTL - this.rtl = /rtl/i.test(S('html').attr('dir')); - - // set foundation global scope - this.scope = scope || this.scope; - - this.set_namespace(); - - if (libraries && typeof libraries === 'string' && !/reflow/i.test(libraries)) { - if (this.libs.hasOwnProperty(libraries)) { - responses.push(this.init_lib(libraries, args)); - } - } else { - for (var lib in this.libs) { - responses.push(this.init_lib(lib, libraries)); - } - } - - S(window).load(function () { - S(window) - .trigger('resize.fndtn.clearing') - .trigger('resize.fndtn.dropdown') - .trigger('resize.fndtn.equalizer') - .trigger('resize.fndtn.interchange') - .trigger('resize.fndtn.joyride') - .trigger('resize.fndtn.magellan') - .trigger('resize.fndtn.topbar') - .trigger('resize.fndtn.slider'); - }); - - return scope; - }, - - init_lib : function (lib, args) { - if (this.libs.hasOwnProperty(lib)) { - this.patch(this.libs[lib]); - - if (args && args.hasOwnProperty(lib)) { - if (typeof this.libs[lib].settings !== 'undefined') { - $.extend(true, this.libs[lib].settings, args[lib]); - } else if (typeof this.libs[lib].defaults !== 'undefined') { - $.extend(true, this.libs[lib].defaults, args[lib]); - } - return this.libs[lib].init.apply(this.libs[lib], [this.scope, args[lib]]); - } - - args = args instanceof Array ? args : new Array(args); - return this.libs[lib].init.apply(this.libs[lib], args); - } - - return function () {}; - }, - - patch : function (lib) { - lib.scope = this.scope; - lib.namespace = this.global.namespace; - lib.rtl = this.rtl; - lib['data_options'] = this.utils.data_options; - lib['attr_name'] = attr_name; - lib['add_namespace'] = add_namespace; - lib['bindings'] = bindings; - lib['S'] = this.utils.S; - }, - - inherit : function (scope, methods) { - var methods_arr = methods.split(' '), - i = methods_arr.length; - - while (i--) { - if (this.utils.hasOwnProperty(methods_arr[i])) { - scope[methods_arr[i]] = this.utils[methods_arr[i]]; - } - } - }, - - set_namespace : function () { - - // Description: - // Don't bother reading the namespace out of the meta tag - // if the namespace has been set globally in javascript - // - // Example: - // Foundation.global.namespace = 'my-namespace'; - // or make it an empty string: - // Foundation.global.namespace = ''; - // - // - - // If the namespace has not been set (is undefined), try to read it out of the meta element. - // Otherwise use the globally defined namespace, even if it's empty ('') - var namespace = ( this.global.namespace === undefined ) ? $('.foundation-data-attribute-namespace').css('font-family') : this.global.namespace; - - // Finally, if the namsepace is either undefined or false, set it to an empty string. - // Otherwise use the namespace value. - this.global.namespace = ( namespace === undefined || /false/i.test(namespace) ) ? '' : namespace; - }, - - libs : {}, - - // methods that can be inherited in libraries - utils : { - - // Description: - // Fast Selector wrapper returns jQuery object. Only use where getElementById - // is not available. - // - // Arguments: - // Selector (String): CSS selector describing the element(s) to be - // returned as a jQuery object. - // - // Scope (String): CSS selector describing the area to be searched. Default - // is document. - // - // Returns: - // Element (jQuery Object): jQuery object containing elements matching the - // selector within the scope. - S : S, - - // Description: - // Executes a function a max of once every n milliseconds - // - // Arguments: - // Func (Function): Function to be throttled. - // - // Delay (Integer): Function execution threshold in milliseconds. - // - // Returns: - // Lazy_function (Function): Function with throttling applied. - throttle : function (func, delay) { - var timer = null; - - return function () { - var context = this, args = arguments; - - if (timer == null) { - timer = setTimeout(function () { - func.apply(context, args); - timer = null; - }, delay); - } - }; - }, - - // Description: - // Executes a function when it stops being invoked for n seconds - // Modified version of _.debounce() http://underscorejs.org - // - // Arguments: - // Func (Function): Function to be debounced. - // - // Delay (Integer): Function execution threshold in milliseconds. - // - // Immediate (Bool): Whether the function should be called at the beginning - // of the delay instead of the end. Default is false. - // - // Returns: - // Lazy_function (Function): Function with debouncing applied. - debounce : function (func, delay, immediate) { - var timeout, result; - return function () { - var context = this, args = arguments; - var later = function () { - timeout = null; - if (!immediate) { - result = func.apply(context, args); - } - }; - var callNow = immediate && !timeout; - clearTimeout(timeout); - timeout = setTimeout(later, delay); - if (callNow) { - result = func.apply(context, args); - } - return result; - }; - }, - - // Description: - // Parses data-options attribute - // - // Arguments: - // El (jQuery Object): Element to be parsed. - // - // Returns: - // Options (Javascript Object): Contents of the element's data-options - // attribute. - data_options : function (el, data_attr_name) { - data_attr_name = data_attr_name || 'options'; - var opts = {}, ii, p, opts_arr, - data_options = function (el) { - var namespace = Foundation.global.namespace; - - if (namespace.length > 0) { - return el.data(namespace + '-' + data_attr_name); - } - - return el.data(data_attr_name); - }; - - var cached_options = data_options(el); - - if (typeof cached_options === 'object') { - return cached_options; - } - - opts_arr = (cached_options || ':').split(';'); - ii = opts_arr.length; - - function isNumber (o) { - return !isNaN (o - 0) && o !== null && o !== '' && o !== false && o !== true; - } - - function trim (str) { - if (typeof str === 'string') { - return $.trim(str); - } - return str; - } - - while (ii--) { - p = opts_arr[ii].split(':'); - p = [p[0], p.slice(1).join(':')]; - - if (/true/i.test(p[1])) { - p[1] = true; - } - if (/false/i.test(p[1])) { - p[1] = false; - } - if (isNumber(p[1])) { - if (p[1].indexOf('.') === -1) { - p[1] = parseInt(p[1], 10); - } else { - p[1] = parseFloat(p[1]); - } - } - - if (p.length === 2 && p[0].length > 0) { - opts[trim(p[0])] = trim(p[1]); - } - } - - return opts; - }, - - // Description: - // Adds JS-recognizable media queries - // - // Arguments: - // Media (String): Key string for the media query to be stored as in - // Foundation.media_queries - // - // Class (String): Class name for the generated tag - register_media : function (media, media_class) { - if (Foundation.media_queries[media] === undefined) { - $('head').append(''); - Foundation.media_queries[media] = removeQuotes($('.' + media_class).css('font-family')); - } - }, - - // Description: - // Add custom CSS within a JS-defined media query - // - // Arguments: - // Rule (String): CSS rule to be appended to the document. - // - // Media (String): Optional media query string for the CSS rule to be - // nested under. - add_custom_rule : function (rule, media) { - if (media === undefined && Foundation.stylesheet) { - Foundation.stylesheet.insertRule(rule, Foundation.stylesheet.cssRules.length); - } else { - var query = Foundation.media_queries[media]; - - if (query !== undefined) { - Foundation.stylesheet.insertRule('@media ' + - Foundation.media_queries[media] + '{ ' + rule + ' }', Foundation.stylesheet.cssRules.length); - } - } - }, - - // Description: - // Performs a callback function when an image is fully loaded - // - // Arguments: - // Image (jQuery Object): Image(s) to check if loaded. - // - // Callback (Function): Function to execute when image is fully loaded. - image_loaded : function (images, callback) { - var self = this, - unloaded = images.length; - - function pictures_has_height(images) { - var pictures_number = images.length; - - for (var i = pictures_number - 1; i >= 0; i--) { - if(images.attr('height') === undefined) { - return false; - }; - }; - - return true; - } - - if (unloaded === 0 || pictures_has_height(images)) { - callback(images); - } - - images.each(function () { - single_image_loaded(self.S(this), function () { - unloaded -= 1; - if (unloaded === 0) { - callback(images); - } - }); - }); - }, - - // Description: - // Returns a random, alphanumeric string - // - // Arguments: - // Length (Integer): Length of string to be generated. Defaults to random - // integer. - // - // Returns: - // Rand (String): Pseudo-random, alphanumeric string. - random_str : function () { - if (!this.fidx) { - this.fidx = 0; - } - this.prefix = this.prefix || [(this.name || 'F'), (+new Date).toString(36)].join('-'); - - return this.prefix + (this.fidx++).toString(36); - }, - - // Description: - // Helper for window.matchMedia - // - // Arguments: - // mq (String): Media query - // - // Returns: - // (Boolean): Whether the media query passes or not - match : function (mq) { - return window.matchMedia(mq).matches; - }, - - // Description: - // Helpers for checking Foundation default media queries with JS - // - // Returns: - // (Boolean): Whether the media query passes or not - - is_small_up : function () { - return this.match(Foundation.media_queries.small); - }, - - is_medium_up : function () { - return this.match(Foundation.media_queries.medium); - }, - - is_large_up : function () { - return this.match(Foundation.media_queries.large); - }, - - is_xlarge_up : function () { - return this.match(Foundation.media_queries.xlarge); - }, - - is_xxlarge_up : function () { - return this.match(Foundation.media_queries.xxlarge); - }, - - is_small_only : function () { - return !this.is_medium_up() && !this.is_large_up() && !this.is_xlarge_up() && !this.is_xxlarge_up(); - }, - - is_medium_only : function () { - return this.is_medium_up() && !this.is_large_up() && !this.is_xlarge_up() && !this.is_xxlarge_up(); - }, - - is_large_only : function () { - return this.is_medium_up() && this.is_large_up() && !this.is_xlarge_up() && !this.is_xxlarge_up(); - }, - - is_xlarge_only : function () { - return this.is_medium_up() && this.is_large_up() && this.is_xlarge_up() && !this.is_xxlarge_up(); - }, - - is_xxlarge_only : function () { - return this.is_medium_up() && this.is_large_up() && this.is_xlarge_up() && this.is_xxlarge_up(); - } - } - }; - - $.fn.foundation = function () { - var args = Array.prototype.slice.call(arguments, 0); - - return this.each(function () { - Foundation.init.apply(Foundation, [this].concat(args)); - return this; - }); - }; - -}(jQuery, window, window.document)); diff --git a/docs.helm.sh/themes/helmdocs/static/src/js/custom/foundation.offcanvas.js b/docs.helm.sh/themes/helmdocs/static/src/js/custom/foundation.offcanvas.js deleted file mode 100755 index 685e9a03af..0000000000 --- a/docs.helm.sh/themes/helmdocs/static/src/js/custom/foundation.offcanvas.js +++ /dev/null @@ -1,225 +0,0 @@ -;(function ($, window, document, undefined) { - 'use strict'; - - Foundation.libs.offcanvas = { - name : 'offcanvas', - - version : '5.5.3', - - settings : { - open_method : 'move', - close_on_click : false - }, - - init : function (scope, method, options) { - this.bindings(method, options); - }, - - events : function () { - var self = this, - S = self.S, - move_class = '', - right_postfix = '', - left_postfix = '', - top_postfix = '', - bottom_postfix = ''; - - if (this.settings.open_method === 'move') { - move_class = 'move-'; - right_postfix = 'right'; - left_postfix = 'left'; - top_postfix = 'top'; - bottom_postfix = 'bottom'; - } else if (this.settings.open_method === 'overlap_single') { - move_class = 'offcanvas-overlap-'; - right_postfix = 'right'; - left_postfix = 'left'; - top_postfix = 'top'; - bottom_postfix = 'bottom'; - } else if (this.settings.open_method === 'overlap') { - move_class = 'offcanvas-overlap'; - } - - S(this.scope).off('.offcanvas') - .on('click.fndtn.offcanvas', '.left-off-canvas-toggle', function (e) { - self.click_toggle_class(e, move_class + right_postfix); - if (self.settings.open_method !== 'overlap') { - S('.left-submenu').removeClass(move_class + right_postfix); - } - $('.left-off-canvas-toggle').attr('aria-expanded', 'true'); - }) - .on('click.fndtn.offcanvas', '.left-off-canvas-menu a', function (e) { - var settings = self.get_settings(e); - var parent = S(this).parent(); - - if (settings.close_on_click && !parent.hasClass('has-submenu') && !parent.hasClass('back')) { - self.hide.call(self, move_class + right_postfix, self.get_wrapper(e)); - parent.parent().removeClass(move_class + right_postfix); - } else if (S(this).parent().hasClass('has-submenu')) { - e.preventDefault(); - S(this).siblings('.left-submenu').toggleClass(move_class + right_postfix); - } else if (parent.hasClass('back')) { - e.preventDefault(); - parent.parent().removeClass(move_class + right_postfix); - } - $('.left-off-canvas-toggle').attr('aria-expanded', 'true'); - }) - //end of left canvas - .on('click.fndtn.offcanvas', '.right-off-canvas-toggle', function (e) { - self.click_toggle_class(e, move_class + left_postfix); - if (self.settings.open_method !== 'overlap') { - S('.right-submenu').removeClass(move_class + left_postfix); - } - $('.right-off-canvas-toggle').attr('aria-expanded', 'true'); - }) - .on('click.fndtn.offcanvas', '.right-off-canvas-menu a', function (e) { - var settings = self.get_settings(e); - var parent = S(this).parent(); - - if (settings.close_on_click && !parent.hasClass('has-submenu') && !parent.hasClass('back')) { - self.hide.call(self, move_class + left_postfix, self.get_wrapper(e)); - parent.parent().removeClass(move_class + left_postfix); - } else if (S(this).parent().hasClass('has-submenu')) { - e.preventDefault(); - S(this).siblings('.right-submenu').toggleClass(move_class + left_postfix); - } else if (parent.hasClass('back')) { - e.preventDefault(); - parent.parent().removeClass(move_class + left_postfix); - } - $('.right-off-canvas-toggle').attr('aria-expanded', 'true'); - }) - //end of right canvas - .on('click.fndtn.offcanvas', '.top-off-canvas-toggle', function (e) { - self.click_toggle_class(e, move_class + bottom_postfix); - if (self.settings.open_method !== 'overlap') { - S('.top-submenu').removeClass(move_class + bottom_postfix); - } - $('.top-off-canvas-toggle').attr('aria-expanded', 'true'); - }) - .on('click.fndtn.offcanvas', '.top-off-canvas-menu a', function (e) { - var settings = self.get_settings(e); - var parent = S(this).parent(); - - if (settings.close_on_click && !parent.hasClass('has-submenu') && !parent.hasClass('back')) { - self.hide.call(self, move_class + bottom_postfix, self.get_wrapper(e)); - parent.parent().removeClass(move_class + bottom_postfix); - } else if (S(this).parent().hasClass('has-submenu')) { - e.preventDefault(); - S(this).siblings('.top-submenu').toggleClass(move_class + bottom_postfix); - } else if (parent.hasClass('back')) { - e.preventDefault(); - parent.parent().removeClass(move_class + bottom_postfix); - } - $('.top-off-canvas-toggle').attr('aria-expanded', 'true'); - }) - //end of top canvas - .on('click.fndtn.offcanvas', '.bottom-off-canvas-toggle', function (e) { - self.click_toggle_class(e, move_class + top_postfix); - if (self.settings.open_method !== 'overlap') { - S('.bottom-submenu').removeClass(move_class + top_postfix); - } - $('.bottom-off-canvas-toggle').attr('aria-expanded', 'true'); - }) - .on('click.fndtn.offcanvas', '.bottom-off-canvas-menu a', function (e) { - var settings = self.get_settings(e); - var parent = S(this).parent(); - - if (settings.close_on_click && !parent.hasClass('has-submenu') && !parent.hasClass('back')) { - self.hide.call(self, move_class + top_postfix, self.get_wrapper(e)); - parent.parent().removeClass(move_class + top_postfix); - } else if (S(this).parent().hasClass('has-submenu')) { - e.preventDefault(); - S(this).siblings('.bottom-submenu').toggleClass(move_class + top_postfix); - } else if (parent.hasClass('back')) { - e.preventDefault(); - parent.parent().removeClass(move_class + top_postfix); - } - $('.bottom-off-canvas-toggle').attr('aria-expanded', 'true'); - }) - //end of bottom - .on('click.fndtn.offcanvas', '.exit-off-canvas', function (e) { - self.click_remove_class(e, move_class + left_postfix); - S('.right-submenu').removeClass(move_class + left_postfix); - if (right_postfix) { - self.click_remove_class(e, move_class + right_postfix); - S('.left-submenu').removeClass(move_class + left_postfix); - } - $('.right-off-canvas-toggle').attr('aria-expanded', 'true'); - }) - .on('click.fndtn.offcanvas', '.exit-off-canvas', function (e) { - self.click_remove_class(e, move_class + left_postfix); - $('.left-off-canvas-toggle').attr('aria-expanded', 'false'); - if (right_postfix) { - self.click_remove_class(e, move_class + right_postfix); - $('.right-off-canvas-toggle').attr('aria-expanded', 'false'); - } - }) - .on('click.fndtn.offcanvas', '.exit-off-canvas', function (e) { - self.click_remove_class(e, move_class + top_postfix); - S('.bottom-submenu').removeClass(move_class + top_postfix); - if (bottom_postfix) { - self.click_remove_class(e, move_class + bottom_postfix); - S('.top-submenu').removeClass(move_class + top_postfix); - } - $('.bottom-off-canvas-toggle').attr('aria-expanded', 'true'); - }) - .on('click.fndtn.offcanvas', '.exit-off-canvas', function (e) { - self.click_remove_class(e, move_class + top_postfix); - $('.top-off-canvas-toggle').attr('aria-expanded', 'false'); - if (bottom_postfix) { - self.click_remove_class(e, move_class + bottom_postfix); - $('.bottom-off-canvas-toggle').attr('aria-expanded', 'false'); - } - }); - }, - - toggle : function (class_name, $off_canvas) { - $off_canvas = $off_canvas || this.get_wrapper(); - if ($off_canvas.is('.' + class_name)) { - this.hide(class_name, $off_canvas); - } else { - this.show(class_name, $off_canvas); - } - }, - - show : function (class_name, $off_canvas) { - $off_canvas = $off_canvas || this.get_wrapper(); - $off_canvas.trigger('open.fndtn.offcanvas'); - $off_canvas.addClass(class_name); - }, - - hide : function (class_name, $off_canvas) { - $off_canvas = $off_canvas || this.get_wrapper(); - $off_canvas.trigger('close.fndtn.offcanvas'); - $off_canvas.removeClass(class_name); - }, - - click_toggle_class : function (e, class_name) { - e.preventDefault(); - var $off_canvas = this.get_wrapper(e); - this.toggle(class_name, $off_canvas); - }, - - click_remove_class : function (e, class_name) { - e.preventDefault(); - var $off_canvas = this.get_wrapper(e); - this.hide(class_name, $off_canvas); - }, - - get_settings : function (e) { - var offcanvas = this.S(e.target).closest('[' + this.attr_name() + ']'); - return offcanvas.data(this.attr_name(true) + '-init') || this.settings; - }, - - get_wrapper : function (e) { - var $off_canvas = this.S(e ? e.target : this.scope).closest('.off-canvas-wrap'); - - if ($off_canvas.length === 0) { - $off_canvas = this.S('.off-canvas-wrap'); - } - return $off_canvas; - }, - - reflow : function () {} - }; -}(jQuery, window, window.document)); diff --git a/docs.helm.sh/themes/helmdocs/static/src/js/custom/foundation.slider.js b/docs.helm.sh/themes/helmdocs/static/src/js/custom/foundation.slider.js deleted file mode 100755 index 0d71d567f4..0000000000 --- a/docs.helm.sh/themes/helmdocs/static/src/js/custom/foundation.slider.js +++ /dev/null @@ -1,296 +0,0 @@ -;(function ($, window, document, undefined) { - 'use strict'; - - Foundation.libs.slider = { - name : 'slider', - - version : '5.5.3', - - settings : { - start : 0, - end : 100, - step : 1, - precision : 2, - initial : null, - display_selector : '', - vertical : false, - trigger_input_change : false, - on_change : function () {} - }, - - cache : {}, - - init : function (scope, method, options) { - Foundation.inherit(this, 'throttle'); - this.bindings(method, options); - this.reflow(); - }, - - events : function () { - var self = this; - $(this.scope) - .off('.slider') - .on('mousedown.fndtn.slider touchstart.fndtn.slider pointerdown.fndtn.slider', - '[' + self.attr_name() + ']:not(.disabled, [disabled]) .range-slider-handle', function (e) { - if (!self.cache.active) { - e.preventDefault(); - self.set_active_slider($(e.target)); - } - }) - .on('mousemove.fndtn.slider touchmove.fndtn.slider pointermove.fndtn.slider', function (e) { - if (!!self.cache.active) { - e.preventDefault(); - if ($.data(self.cache.active[0], 'settings').vertical) { - var scroll_offset = 0; - if (!e.pageY) { - scroll_offset = window.scrollY; - } - self.calculate_position(self.cache.active, self.get_cursor_position(e, 'y') + scroll_offset); - } else { - self.calculate_position(self.cache.active, self.get_cursor_position(e, 'x')); - } - } - }) - .on('mouseup.fndtn.slider touchend.fndtn.slider pointerup.fndtn.slider', function (e) { - if(!self.cache.active) { - // if the user has just clicked into the slider without starting to drag the handle - var slider = $(e.target).attr('role') === 'slider' ? $(e.target) : $(e.target).closest('.range-slider').find("[role='slider']"); - - if (slider.length && (!slider.parent().hasClass('disabled') && !slider.parent().attr('disabled'))) { - self.set_active_slider(slider); - if ($.data(self.cache.active[0], 'settings').vertical) { - var scroll_offset = 0; - if (!e.pageY) { - scroll_offset = window.scrollY; - } - self.calculate_position(self.cache.active, self.get_cursor_position(e, 'y') + scroll_offset); - } else { - self.calculate_position(self.cache.active, self.get_cursor_position(e, 'x')); - } - } - } - self.remove_active_slider(); - }) - .on('change.fndtn.slider', function (e) { - self.settings.on_change(); - }); - - self.S(window) - .on('resize.fndtn.slider', self.throttle(function (e) { - self.reflow(); - }, 300)); - - // update slider value as users change input value - this.S('[' + this.attr_name() + ']').each(function () { - var slider = $(this), - handle = slider.children('.range-slider-handle')[0], - settings = self.initialize_settings(handle); - - if (settings.display_selector != '') { - $(settings.display_selector).each(function(){ - if ($(this).attr('value')) { - $(this).off('change').on('change', function () { - slider.foundation("slider", "set_value", $(this).val()); - }); - } - }); - } - }); - }, - - get_cursor_position : function (e, xy) { - var pageXY = 'page' + xy.toUpperCase(), - clientXY = 'client' + xy.toUpperCase(), - position; - - if (typeof e[pageXY] !== 'undefined') { - position = e[pageXY]; - } else if (typeof e.originalEvent[clientXY] !== 'undefined') { - position = e.originalEvent[clientXY]; - } else if (e.originalEvent.touches && e.originalEvent.touches[0] && typeof e.originalEvent.touches[0][clientXY] !== 'undefined') { - position = e.originalEvent.touches[0][clientXY]; - } else if (e.currentPoint && typeof e.currentPoint[xy] !== 'undefined') { - position = e.currentPoint[xy]; - } - - return position; - }, - - set_active_slider : function ($handle) { - this.cache.active = $handle; - }, - - remove_active_slider : function () { - this.cache.active = null; - }, - - calculate_position : function ($handle, cursor_x) { - var self = this, - settings = $.data($handle[0], 'settings'), - handle_l = $.data($handle[0], 'handle_l'), - handle_o = $.data($handle[0], 'handle_o'), - bar_l = $.data($handle[0], 'bar_l'), - bar_o = $.data($handle[0], 'bar_o'); - - requestAnimationFrame(function () { - var pct; - - if (Foundation.rtl && !settings.vertical) { - pct = self.limit_to(((bar_o + bar_l - cursor_x) / bar_l), 0, 1); - } else { - pct = self.limit_to(((cursor_x - bar_o) / bar_l), 0, 1); - } - - pct = settings.vertical ? 1 - pct : pct; - - var norm = self.normalized_value(pct, settings.start, settings.end, settings.step, settings.precision); - - self.set_ui($handle, norm); - }); - }, - - set_ui : function ($handle, value) { - var settings = $.data($handle[0], 'settings'), - handle_l = $.data($handle[0], 'handle_l'), - bar_l = $.data($handle[0], 'bar_l'), - norm_pct = this.normalized_percentage(value, settings.start, settings.end), - handle_offset = norm_pct * (bar_l - handle_l) - 1, - progress_bar_length = norm_pct * 100, - $handle_parent = $handle.parent(), - $hidden_inputs = $handle.parent().children('input[type=hidden]'); - - if (Foundation.rtl && !settings.vertical) { - handle_offset = -handle_offset; - } - - handle_offset = settings.vertical ? -handle_offset + bar_l - handle_l + 1 : handle_offset; - this.set_translate($handle, handle_offset, settings.vertical); - - if (settings.vertical) { - $handle.siblings('.range-slider-active-segment').css('height', progress_bar_length + '%'); - } else { - $handle.siblings('.range-slider-active-segment').css('width', progress_bar_length + '%'); - } - - $handle_parent.attr(this.attr_name(), value).trigger('change.fndtn.slider'); - - $hidden_inputs.val(value); - if (settings.trigger_input_change) { - $hidden_inputs.trigger('change.fndtn.slider'); - } - - if (!$handle[0].hasAttribute('aria-valuemin')) { - $handle.attr({ - 'aria-valuemin' : settings.start, - 'aria-valuemax' : settings.end - }); - } - $handle.attr('aria-valuenow', value); - - if (settings.display_selector != '') { - $(settings.display_selector).each(function () { - if (this.hasAttribute('value')) { - $(this).val(value); - } else { - $(this).text(value); - } - }); - } - - }, - - normalized_percentage : function (val, start, end) { - return Math.min(1, (val - start) / (end - start)); - }, - - normalized_value : function (val, start, end, step, precision) { - var range = end - start, - point = val * range, - mod = (point - (point % step)) / step, - rem = point % step, - round = ( rem >= step * 0.5 ? step : 0); - return ((mod * step + round) + start).toFixed(precision); - }, - - set_translate : function (ele, offset, vertical) { - if (vertical) { - $(ele) - .css('-webkit-transform', 'translateY(' + offset + 'px)') - .css('-moz-transform', 'translateY(' + offset + 'px)') - .css('-ms-transform', 'translateY(' + offset + 'px)') - .css('-o-transform', 'translateY(' + offset + 'px)') - .css('transform', 'translateY(' + offset + 'px)'); - } else { - $(ele) - .css('-webkit-transform', 'translateX(' + offset + 'px)') - .css('-moz-transform', 'translateX(' + offset + 'px)') - .css('-ms-transform', 'translateX(' + offset + 'px)') - .css('-o-transform', 'translateX(' + offset + 'px)') - .css('transform', 'translateX(' + offset + 'px)'); - } - }, - - limit_to : function (val, min, max) { - return Math.min(Math.max(val, min), max); - }, - - initialize_settings : function (handle) { - var settings = $.extend({}, this.settings, this.data_options($(handle).parent())), - decimal_places_match_result; - - if (settings.precision === null) { - decimal_places_match_result = ('' + settings.step).match(/\.([\d]*)/); - settings.precision = decimal_places_match_result && decimal_places_match_result[1] ? decimal_places_match_result[1].length : 0; - } - - if (settings.vertical) { - $.data(handle, 'bar_o', $(handle).parent().offset().top); - $.data(handle, 'bar_l', $(handle).parent().outerHeight()); - $.data(handle, 'handle_o', $(handle).offset().top); - $.data(handle, 'handle_l', $(handle).outerHeight()); - } else { - $.data(handle, 'bar_o', $(handle).parent().offset().left); - $.data(handle, 'bar_l', $(handle).parent().outerWidth()); - $.data(handle, 'handle_o', $(handle).offset().left); - $.data(handle, 'handle_l', $(handle).outerWidth()); - } - - $.data(handle, 'bar', $(handle).parent()); - return $.data(handle, 'settings', settings); - }, - - set_initial_position : function ($ele) { - var settings = $.data($ele.children('.range-slider-handle')[0], 'settings'), - initial = ((typeof settings.initial == 'number' && !isNaN(settings.initial)) ? settings.initial : Math.floor((settings.end - settings.start) * 0.5 / settings.step) * settings.step + settings.start), - $handle = $ele.children('.range-slider-handle'); - this.set_ui($handle, initial); - }, - - set_value : function (value) { - var self = this; - $('[' + self.attr_name() + ']', this.scope).each(function () { - $(this).attr(self.attr_name(), value); - }); - if (!!$(this.scope).attr(self.attr_name())) { - $(this.scope).attr(self.attr_name(), value); - } - self.reflow(); - }, - - reflow : function () { - var self = this; - self.S('[' + this.attr_name() + ']').each(function () { - var handle = $(this).children('.range-slider-handle')[0], - val = $(this).attr(self.attr_name()); - self.initialize_settings(handle); - - if (val) { - self.set_ui($(handle), parseFloat(val)); - } else { - self.set_initial_position($(this)); - } - }); - } - }; - -}(jQuery, window, window.document)); diff --git a/docs.helm.sh/themes/helmdocs/static/src/js/custom/foundation.tooltip.js b/docs.helm.sh/themes/helmdocs/static/src/js/custom/foundation.tooltip.js deleted file mode 100755 index 0690e2514c..0000000000 --- a/docs.helm.sh/themes/helmdocs/static/src/js/custom/foundation.tooltip.js +++ /dev/null @@ -1,348 +0,0 @@ -;(function ($, window, document, undefined) { - 'use strict'; - - Foundation.libs.tooltip = { - name : 'tooltip', - - version : '5.5.3', - - settings : { - additional_inheritable_classes : [], - tooltip_class : '.tooltip', - append_to : 'body', - touch_close_text : 'Tap To Close', - disable_for_touch : false, - hover_delay : 200, - fade_in_duration : 150, - fade_out_duration : 150, - show_on : 'all', - tip_template : function (selector, content) { - return '' + content + ''; - } - }, - - cache : {}, - - init : function (scope, method, options) { - Foundation.inherit(this, 'random_str'); - this.bindings(method, options); - }, - - should_show : function (target, tip) { - var settings = $.extend({}, this.settings, this.data_options(target)); - - if (settings.show_on === 'all') { - return true; - } else if (this.small() && settings.show_on === 'small') { - return true; - } else if (this.medium() && settings.show_on === 'medium') { - return true; - } else if (this.large() && settings.show_on === 'large') { - return true; - } - return false; - }, - - medium : function () { - return matchMedia(Foundation.media_queries['medium']).matches; - }, - - large : function () { - return matchMedia(Foundation.media_queries['large']).matches; - }, - - events : function (instance) { - var self = this, - S = self.S; - - self.create(this.S(instance)); - - function _startShow(elt, $this, immediate) { - if (elt.timer) { - return; - } - - if (immediate) { - elt.timer = null; - self.showTip($this); - } else { - elt.timer = setTimeout(function () { - elt.timer = null; - self.showTip($this); - }.bind(elt), self.settings.hover_delay); - } - } - - function _startHide(elt, $this) { - if (elt.timer) { - clearTimeout(elt.timer); - elt.timer = null; - } - - self.hide($this); - } - - $(this.scope) - .off('.tooltip') - .on('mouseenter.fndtn.tooltip mouseleave.fndtn.tooltip touchstart.fndtn.tooltip MSPointerDown.fndtn.tooltip', - '[' + this.attr_name() + ']', function (e) { - var $this = S(this), - settings = $.extend({}, self.settings, self.data_options($this)), - is_touch = false; - - if (Modernizr.touch && /touchstart|MSPointerDown/i.test(e.type) && S(e.target).is('a')) { - return false; - } - - if (/mouse/i.test(e.type) && self.ie_touch(e)) { - return false; - } - - if ($this.hasClass('open')) { - if (Modernizr.touch && /touchstart|MSPointerDown/i.test(e.type)) { - e.preventDefault(); - } - self.hide($this); - } else { - if (settings.disable_for_touch && Modernizr.touch && /touchstart|MSPointerDown/i.test(e.type)) { - return; - } else if (!settings.disable_for_touch && Modernizr.touch && /touchstart|MSPointerDown/i.test(e.type)) { - e.preventDefault(); - S(settings.tooltip_class + '.open').hide(); - is_touch = true; - // close other open tooltips on touch - if ($('.open[' + self.attr_name() + ']').length > 0) { - var prevOpen = S($('.open[' + self.attr_name() + ']')[0]); - self.hide(prevOpen); - } - } - - if (/enter|over/i.test(e.type)) { - _startShow(this, $this); - - } else if (e.type === 'mouseout' || e.type === 'mouseleave') { - _startHide(this, $this); - } else { - _startShow(this, $this, true); - } - } - }) - .on('mouseleave.fndtn.tooltip touchstart.fndtn.tooltip MSPointerDown.fndtn.tooltip', '[' + this.attr_name() + '].open', function (e) { - if (/mouse/i.test(e.type) && self.ie_touch(e)) { - return false; - } - - if ($(this).data('tooltip-open-event-type') == 'touch' && e.type == 'mouseleave') { - return; - } else if ($(this).data('tooltip-open-event-type') == 'mouse' && /MSPointerDown|touchstart/i.test(e.type)) { - self.convert_to_touch($(this)); - } else { - _startHide(this, $(this)); - } - }) - .on('DOMNodeRemoved DOMAttrModified', '[' + this.attr_name() + ']:not(a)', function (e) { - _startHide(this, S(this)); - }); - }, - - ie_touch : function (e) { - // How do I distinguish between IE11 and Windows Phone 8????? - return false; - }, - - showTip : function ($target) { - var $tip = this.getTip($target); - if (this.should_show($target, $tip)) { - return this.show($target); - } - return; - }, - - getTip : function ($target) { - var selector = this.selector($target), - settings = $.extend({}, this.settings, this.data_options($target)), - tip = null; - - if (selector) { - tip = this.S('span[data-selector="' + selector + '"]' + settings.tooltip_class); - } - - return (typeof tip === 'object') ? tip : false; - }, - - selector : function ($target) { - var dataSelector = $target.attr(this.attr_name()) || $target.attr('data-selector'); - - if (typeof dataSelector != 'string') { - dataSelector = this.random_str(6); - $target - .attr('data-selector', dataSelector) - .attr('aria-describedby', dataSelector); - } - - return dataSelector; - }, - - create : function ($target) { - var self = this, - settings = $.extend({}, this.settings, this.data_options($target)), - tip_template = this.settings.tip_template; - - if (typeof settings.tip_template === 'string' && window.hasOwnProperty(settings.tip_template)) { - tip_template = window[settings.tip_template]; - } - - var $tip = $(tip_template(this.selector($target), $('
').html($target.attr('title')).html())), - classes = this.inheritable_classes($target); - - $tip.addClass(classes).appendTo(settings.append_to); - - if (Modernizr.touch) { - $tip.append('' + settings.touch_close_text + ''); - $tip.on('touchstart.fndtn.tooltip MSPointerDown.fndtn.tooltip', function (e) { - self.hide($target); - }); - } - - $target.removeAttr('title').attr('title', ''); - }, - - reposition : function (target, tip, classes) { - var width, nub, nubHeight, nubWidth, objPos; - - tip.css('visibility', 'hidden').show(); - - width = target.data('width'); - nub = tip.children('.nub'); - nubHeight = nub.outerHeight(); - nubWidth = nub.outerWidth(); - - if (this.small()) { - tip.css({'width' : '100%'}); - } else { - tip.css({'width' : (width) ? width : 'auto'}); - } - - objPos = function (obj, top, right, bottom, left, width) { - return obj.css({ - 'top' : (top) ? top : 'auto', - 'bottom' : (bottom) ? bottom : 'auto', - 'left' : (left) ? left : 'auto', - 'right' : (right) ? right : 'auto' - }).end(); - }; - - var o_top = target.offset().top; - var o_left = target.offset().left; - var outerHeight = target.outerHeight(); - - objPos(tip, (o_top + outerHeight + 10), 'auto', 'auto', o_left); - - if (this.small()) { - objPos(tip, (o_top + outerHeight + 10), 'auto', 'auto', 12.5, $(this.scope).width()); - tip.addClass('tip-override'); - objPos(nub, -nubHeight, 'auto', 'auto', o_left); - } else { - - if (Foundation.rtl) { - nub.addClass('rtl'); - o_left = o_left + target.outerWidth() - tip.outerWidth(); - } - - objPos(tip, (o_top + outerHeight + 10), 'auto', 'auto', o_left); - // reset nub from small styles, if they've been applied - if (nub.attr('style')) { - nub.removeAttr('style'); - } - - tip.removeClass('tip-override'); - - var tip_outerHeight = tip.outerHeight(); - - if (classes && classes.indexOf('tip-top') > -1) { - if (Foundation.rtl) { - nub.addClass('rtl'); - } - objPos(tip, (o_top - tip_outerHeight), 'auto', 'auto', o_left) - .removeClass('tip-override'); - } else if (classes && classes.indexOf('tip-left') > -1) { - objPos(tip, (o_top + (outerHeight / 2) - (tip_outerHeight / 2)), 'auto', 'auto', (o_left - tip.outerWidth() - nubHeight)) - .removeClass('tip-override'); - nub.removeClass('rtl'); - } else if (classes && classes.indexOf('tip-right') > -1) { - objPos(tip, (o_top + (outerHeight / 2) - (tip_outerHeight / 2)), 'auto', 'auto', (o_left + target.outerWidth() + nubHeight)) - .removeClass('tip-override'); - nub.removeClass('rtl'); - } - } - - tip.css('visibility', 'visible').hide(); - }, - - small : function () { - return matchMedia(Foundation.media_queries.small).matches && - !matchMedia(Foundation.media_queries.medium).matches; - }, - - inheritable_classes : function ($target) { - var settings = $.extend({}, this.settings, this.data_options($target)), - inheritables = ['tip-top', 'tip-left', 'tip-bottom', 'tip-right', 'radius', 'round'].concat(settings.additional_inheritable_classes), - classes = $target.attr('class'), - filtered = classes ? $.map(classes.split(' '), function (el, i) { - if ($.inArray(el, inheritables) !== -1) { - return el; - } - }).join(' ') : ''; - - return $.trim(filtered); - }, - - convert_to_touch : function ($target) { - var self = this, - $tip = self.getTip($target), - settings = $.extend({}, self.settings, self.data_options($target)); - - if ($tip.find('.tap-to-close').length === 0) { - $tip.append('' + settings.touch_close_text + ''); - $tip.on('click.fndtn.tooltip.tapclose touchstart.fndtn.tooltip.tapclose MSPointerDown.fndtn.tooltip.tapclose', function (e) { - self.hide($target); - }); - } - - $target.data('tooltip-open-event-type', 'touch'); - }, - - show : function ($target) { - var $tip = this.getTip($target); - if ($target.data('tooltip-open-event-type') == 'touch') { - this.convert_to_touch($target); - } - - this.reposition($target, $tip, $target.attr('class')); - $target.addClass('open'); - $tip.fadeIn(this.settings.fade_in_duration); - }, - - hide : function ($target) { - var $tip = this.getTip($target); - - $tip.fadeOut(this.settings.fade_out_duration, function () { - $tip.find('.tap-to-close').remove(); - $tip.off('click.fndtn.tooltip.tapclose MSPointerDown.fndtn.tapclose'); - $target.removeClass('open'); - }); - }, - - off : function () { - var self = this; - this.S(this.scope).off('.fndtn.tooltip'); - this.S(this.settings.tooltip_class).each(function (i) { - $('[' + self.attr_name() + ']').eq(i).attr('title', $(this).text()); - }).remove(); - }, - - reflow : function () {} - }; -}(jQuery, window, window.document)); diff --git a/docs.helm.sh/themes/helmdocs/static/src/js/custom/foundation.topbar.js b/docs.helm.sh/themes/helmdocs/static/src/js/custom/foundation.topbar.js deleted file mode 100755 index 23b7c7f1fc..0000000000 --- a/docs.helm.sh/themes/helmdocs/static/src/js/custom/foundation.topbar.js +++ /dev/null @@ -1,458 +0,0 @@ -;(function ($, window, document, undefined) { - 'use strict'; - - Foundation.libs.topbar = { - name : 'topbar', - - version : '5.5.3', - - settings : { - index : 0, - start_offset : 0, - sticky_class : 'sticky', - custom_back_text : true, - back_text : 'Back', - mobile_show_parent_link : true, - is_hover : true, - scrolltop : true, // jump to top when sticky nav menu toggle is clicked - sticky_on : 'all', - dropdown_autoclose: true - }, - - init : function (section, method, options) { - Foundation.inherit(this, 'add_custom_rule register_media throttle'); - var self = this; - - self.register_media('topbar', 'foundation-mq-topbar'); - - this.bindings(method, options); - - self.S('[' + this.attr_name() + ']', this.scope).each(function () { - var topbar = $(this), - settings = topbar.data(self.attr_name(true) + '-init'), - section = self.S('section, .top-bar-section', this); - topbar.data('index', 0); - var topbarContainer = topbar.parent(); - if (topbarContainer.hasClass('fixed') || self.is_sticky(topbar, topbarContainer, settings) ) { - self.settings.sticky_class = settings.sticky_class; - self.settings.sticky_topbar = topbar; - topbar.data('height', topbarContainer.outerHeight()); - topbar.data('stickyoffset', topbarContainer.offset().top); - } else { - topbar.data('height', topbar.outerHeight()); - } - - if (!settings.assembled) { - self.assemble(topbar); - } - - if (settings.is_hover) { - self.S('.has-dropdown', topbar).addClass('not-click'); - } else { - self.S('.has-dropdown', topbar).removeClass('not-click'); - } - - // Pad body when sticky (scrolled) or fixed. - self.add_custom_rule('.f-topbar-fixed { padding-top: ' + topbar.data('height') + 'px }'); - - if (topbarContainer.hasClass('fixed')) { - self.S('body').addClass('f-topbar-fixed'); - } - }); - - }, - - is_sticky : function (topbar, topbarContainer, settings) { - var sticky = topbarContainer.hasClass(settings.sticky_class); - var smallMatch = matchMedia(Foundation.media_queries.small).matches; - var medMatch = matchMedia(Foundation.media_queries.medium).matches; - var lrgMatch = matchMedia(Foundation.media_queries.large).matches; - - if (sticky && settings.sticky_on === 'all') { - return true; - } - if (sticky && this.small() && settings.sticky_on.indexOf('small') !== -1) { - if (smallMatch && !medMatch && !lrgMatch) { return true; } - } - if (sticky && this.medium() && settings.sticky_on.indexOf('medium') !== -1) { - if (smallMatch && medMatch && !lrgMatch) { return true; } - } - if (sticky && this.large() && settings.sticky_on.indexOf('large') !== -1) { - if (smallMatch && medMatch && lrgMatch) { return true; } - } - - return false; - }, - - toggle : function (toggleEl) { - var self = this, - topbar; - - if (toggleEl) { - topbar = self.S(toggleEl).closest('[' + this.attr_name() + ']'); - } else { - topbar = self.S('[' + this.attr_name() + ']'); - } - - var settings = topbar.data(this.attr_name(true) + '-init'); - - var section = self.S('section, .top-bar-section', topbar); - - if (self.breakpoint()) { - if (!self.rtl) { - section.css({left : '0%'}); - $('>.name', section).css({left : '100%'}); - } else { - section.css({right : '0%'}); - $('>.name', section).css({right : '100%'}); - } - - self.S('li.moved', section).removeClass('moved'); - topbar.data('index', 0); - - topbar - .toggleClass('expanded') - .css('height', ''); - } - - if (settings.scrolltop) { - if (!topbar.hasClass('expanded')) { - if (topbar.hasClass('fixed')) { - topbar.parent().addClass('fixed'); - topbar.removeClass('fixed'); - self.S('body').addClass('f-topbar-fixed'); - } - } else if (topbar.parent().hasClass('fixed')) { - if (settings.scrolltop) { - topbar.parent().removeClass('fixed'); - topbar.addClass('fixed'); - self.S('body').removeClass('f-topbar-fixed'); - - window.scrollTo(0, 0); - } else { - topbar.parent().removeClass('expanded'); - } - } - } else { - if (self.is_sticky(topbar, topbar.parent(), settings)) { - topbar.parent().addClass('fixed'); - } - - if (topbar.parent().hasClass('fixed')) { - if (!topbar.hasClass('expanded')) { - topbar.removeClass('fixed'); - topbar.parent().removeClass('expanded'); - self.update_sticky_positioning(); - } else { - topbar.addClass('fixed'); - topbar.parent().addClass('expanded'); - self.S('body').addClass('f-topbar-fixed'); - } - } - } - }, - - timer : null, - - events : function (bar) { - var self = this, - S = this.S; - - S(this.scope) - .off('.topbar') - .on('click.fndtn.topbar', '[' + this.attr_name() + '] .toggle-topbar', function (e) { - e.preventDefault(); - self.toggle(this); - }) - .on('click.fndtn.topbar contextmenu.fndtn.topbar', '.top-bar .top-bar-section li a[href^="#"],[' + this.attr_name() + '] .top-bar-section li a[href^="#"]', function (e) { - var li = $(this).closest('li'), - topbar = li.closest('[' + self.attr_name() + ']'), - settings = topbar.data(self.attr_name(true) + '-init'); - - if (settings.dropdown_autoclose && settings.is_hover) { - var hoverLi = $(this).closest('.hover'); - hoverLi.removeClass('hover'); - } - if (self.breakpoint() && !li.hasClass('back') && !li.hasClass('has-dropdown')) { - self.toggle(); - } - - }) - .on('click.fndtn.topbar', '[' + this.attr_name() + '] li.has-dropdown', function (e) { - var li = S(this), - target = S(e.target), - topbar = li.closest('[' + self.attr_name() + ']'), - settings = topbar.data(self.attr_name(true) + '-init'); - - if (target.data('revealId')) { - self.toggle(); - return; - } - - if (self.breakpoint()) { - return; - } - - if (settings.is_hover && !Modernizr.touch) { - return; - } - - e.stopImmediatePropagation(); - - if (li.hasClass('hover')) { - li - .removeClass('hover') - .find('li') - .removeClass('hover'); - - li.parents('li.hover') - .removeClass('hover'); - } else { - li.addClass('hover'); - - $(li).siblings().removeClass('hover'); - - if (target[0].nodeName === 'A' && target.parent().hasClass('has-dropdown')) { - e.preventDefault(); - } - } - }) - .on('click.fndtn.topbar', '[' + this.attr_name() + '] .has-dropdown>a', function (e) { - if (self.breakpoint()) { - - e.preventDefault(); - - var $this = S(this), - topbar = $this.closest('[' + self.attr_name() + ']'), - section = topbar.find('section, .top-bar-section'), - dropdownHeight = $this.next('.dropdown').outerHeight(), - $selectedLi = $this.closest('li'); - - topbar.data('index', topbar.data('index') + 1); - $selectedLi.addClass('moved'); - - if (!self.rtl) { - section.css({left : -(100 * topbar.data('index')) + '%'}); - section.find('>.name').css({left : 100 * topbar.data('index') + '%'}); - } else { - section.css({right : -(100 * topbar.data('index')) + '%'}); - section.find('>.name').css({right : 100 * topbar.data('index') + '%'}); - } - - topbar.css('height', $this.siblings('ul').outerHeight(true) + topbar.data('height')); - } - }); - - S(window).off('.topbar').on('resize.fndtn.topbar', self.throttle(function () { - self.resize.call(self); - }, 50)).trigger('resize.fndtn.topbar').load(function () { - // Ensure that the offset is calculated after all of the pages resources have loaded - S(this).trigger('resize.fndtn.topbar'); - }); - - S('body').off('.topbar').on('click.fndtn.topbar', function (e) { - var parent = S(e.target).closest('li').closest('li.hover'); - - if (parent.length > 0) { - return; - } - - S('[' + self.attr_name() + '] li.hover').removeClass('hover'); - }); - - // Go up a level on Click - S(this.scope).on('click.fndtn.topbar', '[' + this.attr_name() + '] .has-dropdown .back', function (e) { - e.preventDefault(); - - var $this = S(this), - topbar = $this.closest('[' + self.attr_name() + ']'), - section = topbar.find('section, .top-bar-section'), - settings = topbar.data(self.attr_name(true) + '-init'), - $movedLi = $this.closest('li.moved'), - $previousLevelUl = $movedLi.parent(); - - topbar.data('index', topbar.data('index') - 1); - - if (!self.rtl) { - section.css({left : -(100 * topbar.data('index')) + '%'}); - section.find('>.name').css({left : 100 * topbar.data('index') + '%'}); - } else { - section.css({right : -(100 * topbar.data('index')) + '%'}); - section.find('>.name').css({right : 100 * topbar.data('index') + '%'}); - } - - if (topbar.data('index') === 0) { - topbar.css('height', ''); - } else { - topbar.css('height', $previousLevelUl.outerHeight(true) + topbar.data('height')); - } - - setTimeout(function () { - $movedLi.removeClass('moved'); - }, 300); - }); - - // Show dropdown menus when their items are focused - S(this.scope).find('.dropdown a') - .focus(function () { - $(this).parents('.has-dropdown').addClass('hover'); - }) - .blur(function () { - $(this).parents('.has-dropdown').removeClass('hover'); - }); - }, - - resize : function () { - var self = this; - self.S('[' + this.attr_name() + ']').each(function () { - var topbar = self.S(this), - settings = topbar.data(self.attr_name(true) + '-init'); - - var stickyContainer = topbar.parent('.' + self.settings.sticky_class); - var stickyOffset; - - if (!self.breakpoint()) { - var doToggle = topbar.hasClass('expanded'); - topbar - .css('height', '') - .removeClass('expanded') - .find('li') - .removeClass('hover'); - - if (doToggle) { - self.toggle(topbar); - } - } - - if (self.is_sticky(topbar, stickyContainer, settings)) { - if (stickyContainer.hasClass('fixed')) { - // Remove the fixed to allow for correct calculation of the offset. - stickyContainer.removeClass('fixed'); - - stickyOffset = stickyContainer.offset().top; - if (self.S(document.body).hasClass('f-topbar-fixed')) { - stickyOffset -= topbar.data('height'); - } - - topbar.data('stickyoffset', stickyOffset); - stickyContainer.addClass('fixed'); - } else { - stickyOffset = stickyContainer.offset().top; - topbar.data('stickyoffset', stickyOffset); - } - } - - }); - }, - - breakpoint : function () { - return !matchMedia(Foundation.media_queries['topbar']).matches; - }, - - small : function () { - return matchMedia(Foundation.media_queries['small']).matches; - }, - - medium : function () { - return matchMedia(Foundation.media_queries['medium']).matches; - }, - - large : function () { - return matchMedia(Foundation.media_queries['large']).matches; - }, - - assemble : function (topbar) { - var self = this, - settings = topbar.data(this.attr_name(true) + '-init'), - section = self.S('section, .top-bar-section', topbar); - - // Pull element out of the DOM for manipulation - section.detach(); - - self.S('.has-dropdown>a', section).each(function () { - var $link = self.S(this), - $dropdown = $link.siblings('.dropdown'), - url = $link.attr('href'), - $titleLi; - - if (!$dropdown.find('.title.back').length) { - - if (settings.mobile_show_parent_link == true && url) { - $titleLi = $('
  • '); - } else { - $titleLi = $('
  • '); - } - - // Copy link to subnav - if (settings.custom_back_text == true) { - $('h5>a', $titleLi).html(settings.back_text); - } else { - $('h5>a', $titleLi).html('« ' + $link.html()); - } - $dropdown.prepend($titleLi); - } - }); - - // Put element back in the DOM - section.appendTo(topbar); - - // check for sticky - this.sticky(); - - this.assembled(topbar); - }, - - assembled : function (topbar) { - topbar.data(this.attr_name(true), $.extend({}, topbar.data(this.attr_name(true)), {assembled : true})); - }, - - height : function (ul) { - var total = 0, - self = this; - - $('> li', ul).each(function () { - total += self.S(this).outerHeight(true); - }); - - return total; - }, - - sticky : function () { - var self = this; - - this.S(window).on('scroll', function () { - self.update_sticky_positioning(); - }); - }, - - update_sticky_positioning : function () { - var klass = '.' + this.settings.sticky_class, - $window = this.S(window), - self = this; - - if (self.settings.sticky_topbar && self.is_sticky(this.settings.sticky_topbar,this.settings.sticky_topbar.parent(), this.settings)) { - var distance = this.settings.sticky_topbar.data('stickyoffset') + this.settings.start_offset; - if (!self.S(klass).hasClass('expanded')) { - if ($window.scrollTop() > (distance)) { - if (!self.S(klass).hasClass('fixed')) { - self.S(klass).addClass('fixed'); - self.S('body').addClass('f-topbar-fixed'); - } - } else if ($window.scrollTop() <= distance) { - if (self.S(klass).hasClass('fixed')) { - self.S(klass).removeClass('fixed'); - self.S('body').removeClass('f-topbar-fixed'); - } - } - } - } - }, - - off : function () { - this.S(this.scope).off('.fndtn.topbar'); - this.S(window).off('.fndtn.topbar'); - }, - - reflow : function () {} - }; -}(jQuery, window, window.document)); diff --git a/docs.helm.sh/themes/helmdocs/static/src/js/custom/headroom.js b/docs.helm.sh/themes/helmdocs/static/src/js/custom/headroom.js deleted file mode 100755 index 58c4c336ec..0000000000 --- a/docs.helm.sh/themes/helmdocs/static/src/js/custom/headroom.js +++ /dev/null @@ -1,6 +0,0 @@ -/*! - * headroom.js v0.7.0 - Give your page some headroom. Hide your header until you need it - * Copyright (c) 2014 Nick Williams - http://wicky.nillia.ms/headroom.js - * License: MIT - */ -!function(a,b){"use strict";function c(a){this.callback=a,this.ticking=!1}function d(b){return b&&"undefined"!=typeof a&&(b===a||b.nodeType)}function e(a){if(arguments.length<=0)throw new Error("Missing arguments in extend function");var b,c,f=a||{};for(c=1;ca,c=a+this.getViewportHeight()>this.getScrollerHeight();return b||c},toleranceExceeded:function(a,b){return Math.abs(a-this.lastKnownScrollY)>=this.tolerance[b]},shouldUnpin:function(a,b){var c=a>this.lastKnownScrollY,d=a>=this.offset;return c&&d&&b},shouldPin:function(a,b){var c=athis.lastKnownScrollY?"down":"up",c=this.toleranceExceeded(a,b);this.isOutOfBounds(a)||(a<=this.offset?this.top():this.notTop(),this.shouldUnpin(a,c)?this.unpin():this.shouldPin(a,c)&&this.pin(),this.lastKnownScrollY=a)}},g.options={tolerance:{up:0,down:0},offset:0,scroller:a,classes:{pinned:"headroom--pinned",unpinned:"headroom--unpinned",top:"headroom--top",notTop:"headroom--not-top",initial:"headroom"}},g.cutsTheMustard="undefined"!=typeof h&&h.rAF&&h.bind&&h.classList,a.Headroom=g}(window,document); \ No newline at end of file diff --git a/docs.helm.sh/themes/helmdocs/static/src/js/custom/headroom.min.js b/docs.helm.sh/themes/helmdocs/static/src/js/custom/headroom.min.js deleted file mode 100755 index fcf9c18b2c..0000000000 --- a/docs.helm.sh/themes/helmdocs/static/src/js/custom/headroom.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * headroom.js v0.7.0 - Give your page some headroom. Hide your header until you need it - * Copyright (c) 2014 Nick Williams - http://wicky.nillia.ms/headroom.js - * License: MIT - */ - -!function(a,b){"use strict";function c(a){this.callback=a,this.ticking=!1}function d(b){return b&&"undefined"!=typeof a&&(b===a||b.nodeType)}function e(a){if(arguments.length<=0)throw new Error("Missing arguments in extend function");var b,c,f=a||{};for(c=1;ca,c=a+this.getViewportHeight()>this.getScrollerHeight();return b||c},toleranceExceeded:function(a,b){return Math.abs(a-this.lastKnownScrollY)>=this.tolerance[b]},shouldUnpin:function(a,b){var c=a>this.lastKnownScrollY,d=a>=this.offset;return c&&d&&b},shouldPin:function(a,b){var c=athis.lastKnownScrollY?"down":"up",c=this.toleranceExceeded(a,b);this.isOutOfBounds(a)||(a<=this.offset?this.top():this.notTop(),this.shouldUnpin(a,c)?this.unpin():this.shouldPin(a,c)&&this.pin(),this.lastKnownScrollY=a)}},g.options={tolerance:{up:0,down:0},offset:0,scroller:a,classes:{pinned:"headroom--pinned",unpinned:"headroom--unpinned",top:"headroom--top",notTop:"headroom--not-top",initial:"headroom"}},g.cutsTheMustard="undefined"!=typeof h&&h.rAF&&h.bind&&h.classList,a.Headroom=g}(window,document); \ No newline at end of file diff --git a/docs.helm.sh/themes/helmdocs/static/src/js/custom/jquery.headroom.min.js b/docs.helm.sh/themes/helmdocs/static/src/js/custom/jquery.headroom.min.js deleted file mode 100755 index fcf9c18b2c..0000000000 --- a/docs.helm.sh/themes/helmdocs/static/src/js/custom/jquery.headroom.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * headroom.js v0.7.0 - Give your page some headroom. Hide your header until you need it - * Copyright (c) 2014 Nick Williams - http://wicky.nillia.ms/headroom.js - * License: MIT - */ - -!function(a,b){"use strict";function c(a){this.callback=a,this.ticking=!1}function d(b){return b&&"undefined"!=typeof a&&(b===a||b.nodeType)}function e(a){if(arguments.length<=0)throw new Error("Missing arguments in extend function");var b,c,f=a||{};for(c=1;ca,c=a+this.getViewportHeight()>this.getScrollerHeight();return b||c},toleranceExceeded:function(a,b){return Math.abs(a-this.lastKnownScrollY)>=this.tolerance[b]},shouldUnpin:function(a,b){var c=a>this.lastKnownScrollY,d=a>=this.offset;return c&&d&&b},shouldPin:function(a,b){var c=athis.lastKnownScrollY?"down":"up",c=this.toleranceExceeded(a,b);this.isOutOfBounds(a)||(a<=this.offset?this.top():this.notTop(),this.shouldUnpin(a,c)?this.unpin():this.shouldPin(a,c)&&this.pin(),this.lastKnownScrollY=a)}},g.options={tolerance:{up:0,down:0},offset:0,scroller:a,classes:{pinned:"headroom--pinned",unpinned:"headroom--unpinned",top:"headroom--top",notTop:"headroom--not-top",initial:"headroom"}},g.cutsTheMustard="undefined"!=typeof h&&h.rAF&&h.bind&&h.classList,a.Headroom=g}(window,document); \ No newline at end of file diff --git a/docs.helm.sh/themes/helmdocs/static/src/js/custom/jquery.js b/docs.helm.sh/themes/helmdocs/static/src/js/custom/jquery.js deleted file mode 100755 index 05fb1ec2be..0000000000 --- a/docs.helm.sh/themes/helmdocs/static/src/js/custom/jquery.js +++ /dev/null @@ -1,26 +0,0 @@ -/*! - * jQuery JavaScript Library v2.1.1 - * http://jquery.com/ - * - * Includes Sizzle.js - * http://sizzlejs.com/ - * - * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors - * Released under the MIT license - * http://jquery.org/license - * - * Date: 2014-05-01T17:11Z - */ -!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){function c(a){var b=a.length,c=_.type(a);return"function"===c||_.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}function d(a,b,c){if(_.isFunction(b))return _.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return _.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(hb.test(b))return _.filter(b,a,c);b=_.filter(b,a)}return _.grep(a,function(a){return U.call(b,a)>=0!==c})}function e(a,b){for(;(a=a[b])&&1!==a.nodeType;);return a}function f(a){var b=ob[a]={};return _.each(a.match(nb)||[],function(a,c){b[c]=!0}),b}function g(){Z.removeEventListener("DOMContentLoaded",g,!1),a.removeEventListener("load",g,!1),_.ready()}function h(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=_.expando+Math.random()}function i(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(ub,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:tb.test(c)?_.parseJSON(c):c}catch(e){}sb.set(a,b,c)}else c=void 0;return c}function j(){return!0}function k(){return!1}function l(){try{return Z.activeElement}catch(a){}}function m(a,b){return _.nodeName(a,"table")&&_.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function n(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function o(a){var b=Kb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function p(a,b){for(var c=0,d=a.length;d>c;c++)rb.set(a[c],"globalEval",!b||rb.get(b[c],"globalEval"))}function q(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(rb.hasData(a)&&(f=rb.access(a),g=rb.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)_.event.add(b,e,j[e][c])}sb.hasData(a)&&(h=sb.access(a),i=_.extend({},h),sb.set(b,i))}}function r(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&_.nodeName(a,b)?_.merge([a],c):c}function s(a,b){var c=b.nodeName.toLowerCase();"input"===c&&yb.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}function t(b,c){var d,e=_(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:_.css(e[0],"display");return e.detach(),f}function u(a){var b=Z,c=Ob[a];return c||(c=t(a,b),"none"!==c&&c||(Nb=(Nb||_(" - - - - -
    -

    Developer Standups

    -

    Each week, the Helm teams meet on Zoom.

    - -
    - - -
    -
    - - -
    -

    Helm is supported by and built with a community of over 250 developers.

    -
    - -
    - Microsoft - Google - Codefresh - Bitnami - Ticketmaster - codecentric AG -
    - -

    ...and many other wonderful helm and charts core maintainers.

    -
    -
    - - - - - diff --git a/helm.sh/package-lock.json b/helm.sh/package-lock.json deleted file mode 100644 index fed1db9047..0000000000 --- a/helm.sh/package-lock.json +++ /dev/null @@ -1,10328 +0,0 @@ -{ - "name": "helm.sh", - "version": "0.0.1", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@gulp-sourcemaps/map-sources": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/map-sources/-/map-sources-1.0.0.tgz", - "integrity": "sha1-iQrnxdjId/bThIYCFazp1+yUW9o=", - "dev": true, - "requires": { - "normalize-path": "2.1.1", - "through2": "2.0.3" - } - }, - "abab": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz", - "integrity": "sha1-X6rZwsB/YN12dw9xzwJbYqY8/U4=", - "dev": true, - "optional": true - }, - "accepts": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.2.13.tgz", - "integrity": "sha1-5fHzkoxtlf2WVYw27D2dDeSm7Oo=", - "dev": true, - "requires": { - "mime-types": "2.1.17", - "negotiator": "0.5.3" - } - }, - "acorn": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-2.7.0.tgz", - "integrity": "sha1-q259nYhqrKiwhbwzEreaGYQz8Oc=", - "dev": true - }, - "acorn-globals": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-1.0.9.tgz", - "integrity": "sha1-VbtemGkVB7dFedBRNBMhfDgMVM8=", - "dev": true, - "optional": true, - "requires": { - "acorn": "2.7.0" - } - }, - "ajv": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.2.3.tgz", - "integrity": "sha1-wG9Zh3jETGsWGrr+NGa4GtGBTtI=", - "dev": true, - "requires": { - "co": "4.6.0", - "fast-deep-equal": "1.0.0", - "json-schema-traverse": "0.3.1", - "json-stable-stringify": "1.0.1" - } - }, - "align-text": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", - "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", - "dev": true, - "requires": { - "kind-of": "3.2.2", - "longest": "1.0.1", - "repeat-string": "1.6.1" - } - }, - "alphanum-sort": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", - "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=", - "dev": true - }, - "amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", - "dev": true - }, - "ansi-align": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-1.1.0.tgz", - "integrity": "sha1-LwwWWIKXOa3V67FeawxuNCPwFro=", - "dev": true, - "requires": { - "string-width": "1.0.2" - } - }, - "ansi-colors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", - "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", - "dev": true, - "requires": { - "ansi-wrap": "0.1.0" - } - }, - "ansi-cyan": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-cyan/-/ansi-cyan-0.1.1.tgz", - "integrity": "sha1-U4rlKK+JgvKK4w2G8vF0VtJgmHM=", - "dev": true, - "requires": { - "ansi-wrap": "0.1.0" - } - }, - "ansi-gray": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", - "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=", - "dev": true, - "requires": { - "ansi-wrap": "0.1.0" - } - }, - "ansi-red": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-red/-/ansi-red-0.1.1.tgz", - "integrity": "sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw=", - "dev": true, - "requires": { - "ansi-wrap": "0.1.0" - } - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "ansi-wrap": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", - "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=", - "dev": true - }, - "apartment": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/apartment/-/apartment-1.1.1.tgz", - "integrity": "sha1-/ZQGzcyodTWULxWzYKGrWkqpfiY=", - "dev": true, - "requires": { - "css": "2.2.1", - "get-stdin": "5.0.1", - "lodash": "3.10.1", - "minimist": "1.2.0" - }, - "dependencies": { - "lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", - "dev": true - } - } - }, - "archive-type": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/archive-type/-/archive-type-3.2.0.tgz", - "integrity": "sha1-nNnABpV+vpX62tW9YJiUKoE3N/Y=", - "dev": true, - "requires": { - "file-type": "3.9.0" - } - }, - "archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", - "dev": true - }, - "argparse": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", - "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", - "dev": true, - "requires": { - "sprintf-js": "1.0.3" - } - }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "1.1.0" - } - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-2.1.0.tgz", - "integrity": "sha1-IPnqtexw9cfSFbEHexw5Fh0pLH0=", - "dev": true - }, - "array-differ": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", - "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=", - "dev": true - }, - "array-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", - "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", - "dev": true - }, - "array-find-index": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", - "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", - "dev": true - }, - "array-slice": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.0.0.tgz", - "integrity": "sha1-5zA08A3MH0CHYAj9IP6ud71LfC8=", - "dev": true - }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "1.0.3" - } - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", - "dev": true - }, - "asn1": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", - "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", - "dev": true - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - }, - "asset-resolver": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/asset-resolver/-/asset-resolver-0.2.1.tgz", - "integrity": "sha1-hqDb1Aug7ZgGLlNhIDytGTt77gg=", - "dev": true, - "requires": { - "bluebird": "3.3.5", - "debug": "2.2.0", - "filesize": "3.3.0", - "globby": "4.1.0", - "hash": "0.2.0", - "lodash": "4.12.0", - "meow": "3.7.0", - "mime": "1.3.4", - "object": "0.1.1", - "request": "2.71.0" - }, - "dependencies": { - "assert-plus": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", - "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", - "dev": true - }, - "async": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz", - "integrity": "sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw==", - "dev": true, - "requires": { - "lodash": "4.17.4" - }, - "dependencies": { - "lodash": { - "version": "4.17.4", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", - "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", - "dev": true - } - } - }, - "aws-sign2": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", - "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", - "dev": true - }, - "bluebird": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.3.5.tgz", - "integrity": "sha1-XudH8ce9lnZYtoOTZDCu51OVWjQ=", - "dev": true - }, - "boom": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", - "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", - "dev": true, - "requires": { - "hoek": "2.16.3" - } - }, - "caseless": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", - "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=", - "dev": true - }, - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", - "dev": true - }, - "cryptiles": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", - "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", - "dev": true, - "requires": { - "boom": "2.10.1" - } - }, - "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", - "dev": true, - "requires": { - "ms": "0.7.1" - } - }, - "form-data": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-1.0.1.tgz", - "integrity": "sha1-rjFduaSQf6BlUCMEpm13M0de43w=", - "dev": true, - "requires": { - "async": "2.5.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.17" - } - }, - "har-validator": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", - "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=", - "dev": true, - "requires": { - "chalk": "1.1.3", - "commander": "2.11.0", - "is-my-json-valid": "2.16.1", - "pinkie-promise": "2.0.1" - } - }, - "hawk": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", - "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", - "dev": true, - "requires": { - "boom": "2.10.1", - "cryptiles": "2.0.5", - "hoek": "2.16.3", - "sntp": "1.0.9" - } - }, - "hoek": { - "version": "2.16.3", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", - "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", - "dev": true - }, - "http-signature": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", - "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", - "dev": true, - "requires": { - "assert-plus": "0.2.0", - "jsprim": "1.4.1", - "sshpk": "1.13.1" - } - }, - "lodash": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.12.0.tgz", - "integrity": "sha1-K9bcRqBA9Z5obJcu0h2T3FkFMlg=", - "dev": true - }, - "mime": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz", - "integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM=", - "dev": true - }, - "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", - "dev": true - }, - "node-uuid": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", - "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=", - "dev": true - }, - "qs": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.1.2.tgz", - "integrity": "sha1-tZ2JJdDJme9tY6z0rFq7CtqiS1Q=", - "dev": true - }, - "request": { - "version": "2.71.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.71.0.tgz", - "integrity": "sha1-bxRkPJxaZ8ruapXPjvBHfVYDvZE=", - "dev": true, - "requires": { - "aws-sign2": "0.6.0", - "aws4": "1.6.0", - "bl": "1.1.2", - "caseless": "0.11.0", - "combined-stream": "1.0.5", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "1.0.1", - "har-validator": "2.0.6", - "hawk": "3.1.3", - "http-signature": "1.1.1", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.17", - "node-uuid": "1.4.8", - "oauth-sign": "0.8.2", - "qs": "6.1.2", - "stringstream": "0.0.5", - "tough-cookie": "2.2.2", - "tunnel-agent": "0.4.3" - } - }, - "sntp": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", - "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", - "dev": true, - "requires": { - "hoek": "2.16.3" - } - }, - "tough-cookie": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.2.2.tgz", - "integrity": "sha1-yDoYMPTl7wuT7yo0iOck+N4Basc=", - "dev": true - }, - "tunnel-agent": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", - "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=", - "dev": true - } - } - }, - "async": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", - "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=", - "dev": true - }, - "async-each-series": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/async-each-series/-/async-each-series-1.1.0.tgz", - "integrity": "sha1-9C/YFV048hpbjqB8KOBj7RcAsTg=", - "dev": true, - "optional": true - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true - }, - "atob": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/atob/-/atob-1.1.3.tgz", - "integrity": "sha1-lfE2KbEsOlGl0hWr3OKqnzL4B3M=", - "dev": true - }, - "autoprefixer": { - "version": "6.7.7", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-6.7.7.tgz", - "integrity": "sha1-Hb0cg1ZY41zj+ZhAmdsAWFx4IBQ=", - "dev": true, - "requires": { - "browserslist": "1.7.7", - "caniuse-db": "1.0.30000738", - "normalize-range": "0.1.2", - "num2fraction": "1.2.2", - "postcss": "5.2.17", - "postcss-value-parser": "3.3.0" - } - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true - }, - "aws4": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", - "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=", - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base64-url": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/base64-url/-/base64-url-1.2.1.tgz", - "integrity": "sha1-GZ/WYXAqDnt9yubgaYuwicUvbXg=", - "dev": true - }, - "basic-auth": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-1.0.4.tgz", - "integrity": "sha1-Awk1sB3nyblKgksp8/zLdQ06UpA=", - "dev": true - }, - "basic-auth-connect": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/basic-auth-connect/-/basic-auth-connect-1.0.0.tgz", - "integrity": "sha1-/bC0OWLKe0BFanwrtI/hc9otISI=", - "dev": true - }, - "batch": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.5.3.tgz", - "integrity": "sha1-PzQU84AyF0O/wQQvmoP/HVgk1GQ=", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", - "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", - "dev": true, - "optional": true, - "requires": { - "tweetnacl": "0.14.5" - } - }, - "beeper": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", - "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=", - "dev": true - }, - "bin-build": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/bin-build/-/bin-build-2.2.0.tgz", - "integrity": "sha1-EfjdYfcP/Por3KpbRvXo/t1CIcw=", - "dev": true, - "optional": true, - "requires": { - "archive-type": "3.2.0", - "decompress": "3.0.0", - "download": "4.4.3", - "exec-series": "1.0.3", - "rimraf": "2.6.2", - "tempfile": "1.1.1", - "url-regex": "3.2.0" - } - }, - "bin-check": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/bin-check/-/bin-check-2.0.0.tgz", - "integrity": "sha1-hvjm9CU4k99g3DFpV/WvAqywWTA=", - "dev": true, - "optional": true, - "requires": { - "executable": "1.1.0" - } - }, - "bin-version": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/bin-version/-/bin-version-1.0.4.tgz", - "integrity": "sha1-nrSY7m/Xb3q5p8FgQ2+JV5Q1144=", - "dev": true, - "optional": true, - "requires": { - "find-versions": "1.2.1" - } - }, - "bin-version-check": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/bin-version-check/-/bin-version-check-2.1.0.tgz", - "integrity": "sha1-5OXfKQuQaffRETJAMe/BP90RpbA=", - "dev": true, - "optional": true, - "requires": { - "bin-version": "1.0.4", - "minimist": "1.2.0", - "semver": "4.3.6", - "semver-truncate": "1.1.2" - }, - "dependencies": { - "semver": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz", - "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=", - "dev": true, - "optional": true - } - } - }, - "bin-wrapper": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/bin-wrapper/-/bin-wrapper-3.0.2.tgz", - "integrity": "sha1-Z9MwYmLksaXy+I7iNGT2plVneus=", - "dev": true, - "optional": true, - "requires": { - "bin-check": "2.0.0", - "bin-version-check": "2.1.0", - "download": "4.4.3", - "each-async": "1.1.1", - "lazy-req": "1.1.0", - "os-filter-obj": "1.0.3" - } - }, - "bl": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/bl/-/bl-1.1.2.tgz", - "integrity": "sha1-/cqHGplxOqANGeO7ukHER4emU5g=", - "dev": true, - "requires": { - "readable-stream": "2.0.6" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", - "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "string_decoder": "0.10.31", - "util-deprecate": "1.0.2" - } - } - } - }, - "bluebird": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz", - "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=", - "dev": true - }, - "body-parser": { - "version": "1.13.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.13.3.tgz", - "integrity": "sha1-wIzzMMM1jhUQFqBXRvE/ApyX+pc=", - "dev": true, - "requires": { - "bytes": "2.1.0", - "content-type": "1.0.4", - "debug": "2.2.0", - "depd": "1.0.1", - "http-errors": "1.3.1", - "iconv-lite": "0.4.11", - "on-finished": "2.3.0", - "qs": "4.0.0", - "raw-body": "2.1.7", - "type-is": "1.6.15" - }, - "dependencies": { - "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", - "dev": true, - "requires": { - "ms": "0.7.1" - } - }, - "depd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.0.1.tgz", - "integrity": "sha1-gK7GTJ1tl+ZcwqnKqTwKpqv3Oqo=", - "dev": true - }, - "http-errors": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.3.1.tgz", - "integrity": "sha1-GX4izevUGYWF6GlO9nhhl7ke2UI=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "statuses": "1.3.1" - } - }, - "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", - "dev": true - }, - "qs": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-4.0.0.tgz", - "integrity": "sha1-wx2bdOwn33XlQ6hseHKO2NRiNgc=", - "dev": true - } - } - }, - "boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", - "dev": true - }, - "boom": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", - "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", - "dev": true, - "requires": { - "hoek": "4.2.0" - } - }, - "boxen": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-0.5.1.tgz", - "integrity": "sha1-W3PYhA6388ihVcv2ntPtaNRyABQ=", - "dev": true, - "requires": { - "camelcase": "2.1.1", - "chalk": "1.1.3", - "cli-boxes": "1.0.0", - "filled-array": "1.1.0", - "object-assign": "4.1.1", - "repeating": "2.0.1", - "string-width": "1.0.2", - "widest-line": "1.0.0" - } - }, - "brace-expansion": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", - "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", - "dev": true, - "requires": { - "balanced-match": "1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "1.8.2", - "preserve": "0.2.0", - "repeat-element": "1.1.2" - } - }, - "browserslist": { - "version": "1.7.7", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz", - "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", - "dev": true, - "requires": { - "caniuse-db": "1.0.30000738", - "electron-to-chromium": "1.3.22" - } - }, - "buffer-to-vinyl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-to-vinyl/-/buffer-to-vinyl-1.1.0.tgz", - "integrity": "sha1-APFfruOreh3aLN5tkSG//dB7ImI=", - "dev": true, - "requires": { - "file-type": "3.9.0", - "readable-stream": "2.3.3", - "uuid": "2.0.3", - "vinyl": "1.2.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - }, - "uuid": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", - "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=", - "dev": true - }, - "vinyl": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", - "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", - "dev": true, - "requires": { - "clone": "1.0.2", - "clone-stats": "0.0.1", - "replace-ext": "0.0.1" - } - } - } - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "bytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.1.0.tgz", - "integrity": "sha1-rJPEEOL/ycx89LRks4KJBn9eR7Q=", - "dev": true - }, - "cache-swap": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/cache-swap/-/cache-swap-0.3.0.tgz", - "integrity": "sha1-HFQaoQilAQb2ML3Zj+HeyLoTP1E=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "mkdirp": "0.5.1", - "object-assign": "4.1.1", - "rimraf": "2.6.2" - } - }, - "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", - "dev": true - }, - "camelcase-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", - "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", - "dev": true, - "requires": { - "camelcase": "2.1.1", - "map-obj": "1.0.1" - } - }, - "caniuse-api": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-1.6.1.tgz", - "integrity": "sha1-tTTnxzTE+B7F++isoq0kNUuWLGw=", - "dev": true, - "requires": { - "browserslist": "1.7.7", - "caniuse-db": "1.0.30000738", - "lodash.memoize": "4.1.2", - "lodash.uniq": "4.5.0" - } - }, - "caniuse-db": { - "version": "1.0.30000738", - "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000738.tgz", - "integrity": "sha1-hICavEmjkOWowiSrk2nT+NAaogI=", - "dev": true - }, - "capture-stack-trace": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz", - "integrity": "sha1-Sm+gc5nCa7pH8LJJa00PtAjFVQ0=", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true - }, - "cave": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/cave/-/cave-2.0.0.tgz", - "integrity": "sha1-DFd66oWSgBXQKgK2GIgG2VvrJiY=", - "dev": true, - "requires": { - "css": "2.2.1", - "get-stdin": "3.0.2", - "lodash": "2.4.2", - "minimist": "1.2.0" - }, - "dependencies": { - "get-stdin": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-3.0.2.tgz", - "integrity": "sha1-wc7SS5A5s43thb3xYeV3E7bdSr4=", - "dev": true - }, - "lodash": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", - "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=", - "dev": true - } - } - }, - "caw": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/caw/-/caw-1.2.0.tgz", - "integrity": "sha1-/7Im/n78VHKI3GLuPpcHPCEtEDQ=", - "dev": true, - "requires": { - "get-proxy": "1.1.0", - "is-obj": "1.0.1", - "object-assign": "3.0.0", - "tunnel-agent": "0.4.3" - }, - "dependencies": { - "object-assign": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", - "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=", - "dev": true - }, - "tunnel-agent": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", - "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=", - "dev": true - } - } - }, - "center-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", - "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", - "dev": true, - "requires": { - "align-text": "0.1.4", - "lazy-cache": "1.0.4" - } - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - }, - "cheerio": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.20.0.tgz", - "integrity": "sha1-XHEPK6uVZTJyhCugHG6mGzVF7DU=", - "dev": true, - "requires": { - "css-select": "1.2.0", - "dom-serializer": "0.1.0", - "entities": "1.1.1", - "htmlparser2": "3.8.3", - "jsdom": "7.2.2", - "lodash": "4.17.4" - } - }, - "clap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/clap/-/clap-1.2.3.tgz", - "integrity": "sha512-4CoL/A3hf90V3VIEjeuhSvlGFEHKzOz+Wfc2IVZc+FaUgU0ZQafJTP49fvnULipOPcAfqhyI2duwQyns6xqjYA==", - "dev": true, - "requires": { - "chalk": "1.1.3" - } - }, - "clean-css": { - "version": "3.4.28", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-3.4.28.tgz", - "integrity": "sha1-vxlF6C/ICPVWlebd6uwBQA79A/8=", - "dev": true, - "requires": { - "commander": "2.8.1", - "source-map": "0.4.4" - }, - "dependencies": { - "source-map": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", - "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", - "dev": true, - "requires": { - "amdefine": "1.0.1" - } - } - } - }, - "cli": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/cli/-/cli-0.11.3.tgz", - "integrity": "sha1-ewzT3pkORSklZnwNuv/cn38qmhU=", - "dev": true, - "requires": { - "exit": "0.1.2", - "glob": "7.1.2" - } - }, - "cli-boxes": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", - "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=", - "dev": true - }, - "cliui": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", - "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", - "dev": true, - "requires": { - "center-align": "0.1.3", - "right-align": "0.1.3", - "wordwrap": "0.0.2" - }, - "dependencies": { - "wordwrap": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", - "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", - "dev": true - } - } - }, - "clone": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz", - "integrity": "sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=", - "dev": true - }, - "clone-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", - "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=", - "dev": true - }, - "clone-stats": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", - "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", - "dev": true - }, - "cloneable-readable": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.0.0.tgz", - "integrity": "sha1-pikNQT8hemEjL5XkWP84QYz7ARc=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "process-nextick-args": "1.0.7", - "through2": "2.0.3" - } - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true - }, - "coa": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/coa/-/coa-1.0.4.tgz", - "integrity": "sha1-qe8VNmDWqGqL3sAomlxoTSF0Mv0=", - "dev": true, - "requires": { - "q": "1.5.0" - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, - "color": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/color/-/color-0.11.4.tgz", - "integrity": "sha1-bXtcdPtl6EHNSHkq0e1eB7kE12Q=", - "dev": true, - "requires": { - "clone": "1.0.2", - "color-convert": "1.9.0", - "color-string": "0.3.0" - } - }, - "color-convert": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz", - "integrity": "sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o=", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "color-string": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-0.3.0.tgz", - "integrity": "sha1-J9RvtnAlxcL6JZk7+/V55HhBuZE=", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "dev": true - }, - "colormin": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/colormin/-/colormin-1.1.2.tgz", - "integrity": "sha1-6i90IKcrlogaOKrlnsEkpvcpgTM=", - "dev": true, - "requires": { - "color": "0.11.4", - "css-color-names": "0.0.4", - "has": "1.0.1" - } - }, - "colors": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", - "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", - "dev": true - }, - "combined-stream": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", - "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", - "dev": true, - "requires": { - "delayed-stream": "1.0.0" - } - }, - "commander": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz", - "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=", - "dev": true, - "requires": { - "graceful-readlink": "1.0.1" - } - }, - "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", - "dev": true - }, - "compressible": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.11.tgz", - "integrity": "sha1-FnGKdd4oPtjmBAQWJaIGRYZ5fYo=", - "dev": true, - "requires": { - "mime-db": "1.30.0" - } - }, - "compression": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.5.2.tgz", - "integrity": "sha1-sDuNhub4rSloPLqN+R3cb/x3s5U=", - "dev": true, - "requires": { - "accepts": "1.2.13", - "bytes": "2.1.0", - "compressible": "2.0.11", - "debug": "2.2.0", - "on-headers": "1.0.1", - "vary": "1.0.1" - }, - "dependencies": { - "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", - "dev": true, - "requires": { - "ms": "0.7.1" - } - }, - "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", - "dev": true - } - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", - "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "readable-stream": "2.3.3", - "typedarray": "0.0.6" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - } - } - }, - "concat-with-sourcemaps": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/concat-with-sourcemaps/-/concat-with-sourcemaps-1.0.4.tgz", - "integrity": "sha1-9Vs74q60dgGxCi1SWcz7cP0vHdY=", - "dev": true, - "requires": { - "source-map": "0.5.7" - } - }, - "configstore": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-2.1.0.tgz", - "integrity": "sha1-c3o6cDbpiGECqmCZ5HuzOrGroaE=", - "dev": true, - "requires": { - "dot-prop": "3.0.0", - "graceful-fs": "4.1.11", - "mkdirp": "0.5.1", - "object-assign": "4.1.1", - "os-tmpdir": "1.0.2", - "osenv": "0.1.4", - "uuid": "2.0.3", - "write-file-atomic": "1.3.4", - "xdg-basedir": "2.0.0" - }, - "dependencies": { - "uuid": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", - "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=", - "dev": true - } - } - }, - "connect": { - "version": "2.30.2", - "resolved": "https://registry.npmjs.org/connect/-/connect-2.30.2.tgz", - "integrity": "sha1-jam8vooFTT0xjXTf7JA7XDmhtgk=", - "dev": true, - "requires": { - "basic-auth-connect": "1.0.0", - "body-parser": "1.13.3", - "bytes": "2.1.0", - "compression": "1.5.2", - "connect-timeout": "1.6.2", - "content-type": "1.0.4", - "cookie": "0.1.3", - "cookie-parser": "1.3.5", - "cookie-signature": "1.0.6", - "csurf": "1.8.3", - "debug": "2.2.0", - "depd": "1.0.1", - "errorhandler": "1.4.3", - "express-session": "1.11.3", - "finalhandler": "0.4.0", - "fresh": "0.3.0", - "http-errors": "1.3.1", - "method-override": "2.3.9", - "morgan": "1.6.1", - "multiparty": "3.3.2", - "on-headers": "1.0.1", - "parseurl": "1.3.2", - "pause": "0.1.0", - "qs": "4.0.0", - "response-time": "2.3.2", - "serve-favicon": "2.3.2", - "serve-index": "1.7.3", - "serve-static": "1.10.3", - "type-is": "1.6.15", - "utils-merge": "1.0.0", - "vhost": "3.0.2" - }, - "dependencies": { - "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", - "dev": true, - "requires": { - "ms": "0.7.1" - } - }, - "depd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.0.1.tgz", - "integrity": "sha1-gK7GTJ1tl+ZcwqnKqTwKpqv3Oqo=", - "dev": true - }, - "escape-html": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.2.tgz", - "integrity": "sha1-130y+pjjjC9BroXpJ44ODmuhAiw=", - "dev": true - }, - "etag": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.7.0.tgz", - "integrity": "sha1-A9MLX2fdbmMtKUXTDWZScxo01dg=", - "dev": true - }, - "finalhandler": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-0.4.0.tgz", - "integrity": "sha1-llpS2ejQXSuFdUhUH7ibU6JJfZs=", - "dev": true, - "requires": { - "debug": "2.2.0", - "escape-html": "1.0.2", - "on-finished": "2.3.0", - "unpipe": "1.0.0" - } - }, - "fresh": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.3.0.tgz", - "integrity": "sha1-ZR+DjiJCTnVm3hYdg1jKoZn4PU8=", - "dev": true - }, - "http-errors": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.3.1.tgz", - "integrity": "sha1-GX4izevUGYWF6GlO9nhhl7ke2UI=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "statuses": "1.3.1" - } - }, - "mime": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz", - "integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM=", - "dev": true - }, - "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", - "dev": true - }, - "qs": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-4.0.0.tgz", - "integrity": "sha1-wx2bdOwn33XlQ6hseHKO2NRiNgc=", - "dev": true - }, - "range-parser": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.0.3.tgz", - "integrity": "sha1-aHKCNTXGkuLCoBA4Jq/YLC4P8XU=", - "dev": true - }, - "send": { - "version": "0.13.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.13.2.tgz", - "integrity": "sha1-dl52B8gFVFK7pvCwUllTUJhgNt4=", - "dev": true, - "requires": { - "debug": "2.2.0", - "depd": "1.1.1", - "destroy": "1.0.4", - "escape-html": "1.0.3", - "etag": "1.7.0", - "fresh": "0.3.0", - "http-errors": "1.3.1", - "mime": "1.3.4", - "ms": "0.7.1", - "on-finished": "2.3.0", - "range-parser": "1.0.3", - "statuses": "1.2.1" - }, - "dependencies": { - "depd": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", - "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=", - "dev": true - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true - }, - "statuses": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.2.1.tgz", - "integrity": "sha1-3e1FzBglbVHtQK7BQkidXGECbSg=", - "dev": true - } - } - }, - "serve-static": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.10.3.tgz", - "integrity": "sha1-zlpuzTEB/tXsCYJ9rCKpwpv7BTU=", - "dev": true, - "requires": { - "escape-html": "1.0.3", - "parseurl": "1.3.2", - "send": "0.13.2" - }, - "dependencies": { - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true - } - } - } - } - }, - "connect-livereload": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/connect-livereload/-/connect-livereload-0.5.4.tgz", - "integrity": "sha1-gBV9E3HJ83zBQDmrGJWXDRGdw7w=", - "dev": true - }, - "connect-timeout": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/connect-timeout/-/connect-timeout-1.6.2.tgz", - "integrity": "sha1-3ppexh4zoStu2qt7XwYumMWZuI4=", - "dev": true, - "requires": { - "debug": "2.2.0", - "http-errors": "1.3.1", - "ms": "0.7.1", - "on-headers": "1.0.1" - }, - "dependencies": { - "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", - "dev": true, - "requires": { - "ms": "0.7.1" - } - }, - "http-errors": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.3.1.tgz", - "integrity": "sha1-GX4izevUGYWF6GlO9nhhl7ke2UI=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "statuses": "1.3.1" - } - }, - "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", - "dev": true - } - } - }, - "console-browserify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", - "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", - "dev": true, - "requires": { - "date-now": "0.1.4" - } - }, - "console-stream": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/console-stream/-/console-stream-0.1.1.tgz", - "integrity": "sha1-oJX+B7IEZZVfL6/Si11yvM2UnUQ=", - "dev": true, - "optional": true - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", - "dev": true - }, - "convert-source-map": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.0.tgz", - "integrity": "sha1-ms1whRxtXf3ZPZKC5e35SgP/RrU=", - "dev": true - }, - "cookie": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.1.3.tgz", - "integrity": "sha1-5zSlwUF/zkctWu+Cw4HKu2TRpDU=", - "dev": true - }, - "cookie-parser": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.3.5.tgz", - "integrity": "sha1-nXVVcPtdF4kHcSJ6AjFNm+fPg1Y=", - "dev": true, - "requires": { - "cookie": "0.1.3", - "cookie-signature": "1.0.6" - } - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", - "dev": true - }, - "cookiejar": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.0.6.tgz", - "integrity": "sha1-Cr81atANHFohnYjURRgEbdAmrP4=", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "crc": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.3.0.tgz", - "integrity": "sha1-+mIuG8OIvyVzCQgta2UgDOZwkLo=", - "dev": true - }, - "create-error-class": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", - "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", - "dev": true, - "requires": { - "capture-stack-trace": "1.0.0" - } - }, - "critical": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/critical/-/critical-0.7.3.tgz", - "integrity": "sha1-nli7oritEQLOoI0zCK3HIvke/NQ=", - "dev": true, - "requires": { - "bluebird": "3.5.0", - "cheerio": "0.20.0", - "clean-css": "3.4.28", - "cli": "0.11.3", - "debug": "2.6.9", - "filter-css": "0.1.2", - "finalhandler": "0.4.1", - "fs-extra": "0.26.7", - "get-port": "2.1.0", - "get-stdin": "5.0.1", - "gulp-util": "3.0.8", - "imageinliner": "0.2.4", - "indent-string": "2.1.0", - "inline-critical": "1.0.0", - "lodash": "4.17.4", - "meow": "3.7.0", - "mime-types": "2.1.17", - "object-assign": "4.1.1", - "oust": "0.2.4", - "parseurl": "1.3.2", - "penthouse": "0.9.16", - "postcss": "5.2.17", - "postcss-image-inliner": "0.3.1", - "request": "2.82.0", - "serve-static": "1.12.6", - "slash": "1.0.0", - "tempfile": "1.1.1", - "through2": "2.0.3", - "tmp": "0.0.28" - } - }, - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "dev": true, - "requires": { - "lru-cache": "4.1.1", - "shebang-command": "1.2.0", - "which": "1.2.14" - }, - "dependencies": { - "lru-cache": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", - "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", - "dev": true, - "requires": { - "pseudomap": "1.0.2", - "yallist": "2.1.2" - } - } - } - }, - "cryptiles": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", - "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", - "dev": true, - "requires": { - "boom": "5.2.0" - }, - "dependencies": { - "boom": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", - "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", - "dev": true, - "requires": { - "hoek": "4.2.0" - } - } - } - }, - "csrf": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/csrf/-/csrf-3.0.6.tgz", - "integrity": "sha1-thEg3c7q/JHnbtUxO7XAsmZ7cQo=", - "dev": true, - "requires": { - "rndm": "1.2.0", - "tsscmp": "1.0.5", - "uid-safe": "2.1.4" - } - }, - "css": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/css/-/css-2.2.1.tgz", - "integrity": "sha1-c6TIHehdtmTU7mdPfUcIXjstVdw=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "source-map": "0.1.43", - "source-map-resolve": "0.3.1", - "urix": "0.1.0" - }, - "dependencies": { - "source-map": { - "version": "0.1.43", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", - "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", - "dev": true, - "requires": { - "amdefine": "1.0.1" - } - } - } - }, - "css-color-names": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", - "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=", - "dev": true - }, - "css-mediaquery": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/css-mediaquery/-/css-mediaquery-0.1.2.tgz", - "integrity": "sha1-aiw3NEkoYYYxxUvTPO3TAdoYvqA=", - "dev": true - }, - "css-parse": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-1.7.0.tgz", - "integrity": "sha1-Mh9s9zeCpv91ERE5D8BeLGV9jJs=", - "dev": true - }, - "css-property": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/css-property/-/css-property-2.0.0.tgz", - "integrity": "sha1-ObdyRxpp1IpPSU9gHl4DtBTIHZY=", - "dev": true - }, - "css-rules": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/css-rules/-/css-rules-1.0.2.tgz", - "integrity": "sha1-8tBURMCSfaCeRtHKaVr4Gm/FJdk=", - "dev": true, - "requires": { - "cssom": "0.3.2" - } - }, - "css-select": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", - "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", - "dev": true, - "requires": { - "boolbase": "1.0.0", - "css-what": "2.1.0", - "domutils": "1.5.1", - "nth-check": "1.0.1" - } - }, - "css-stringify": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/css-stringify/-/css-stringify-1.4.1.tgz", - "integrity": "sha1-JSzL8D9yOgCb3Ydw/n6ydBca/fo=", - "dev": true, - "requires": { - "source-map": "0.1.43" - }, - "dependencies": { - "source-map": { - "version": "0.1.43", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", - "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", - "dev": true, - "requires": { - "amdefine": "1.0.1" - } - } - } - }, - "css-what": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.0.tgz", - "integrity": "sha1-lGfQMsOM+u+58teVASUwYvh/ob0=", - "dev": true - }, - "cssnano": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-3.10.0.tgz", - "integrity": "sha1-Tzj2zqK5sX+gFJDyPx3GjqZcHDg=", - "dev": true, - "requires": { - "autoprefixer": "6.7.7", - "decamelize": "1.2.0", - "defined": "1.0.0", - "has": "1.0.1", - "object-assign": "4.1.1", - "postcss": "5.2.17", - "postcss-calc": "5.3.1", - "postcss-colormin": "2.2.2", - "postcss-convert-values": "2.6.1", - "postcss-discard-comments": "2.0.4", - "postcss-discard-duplicates": "2.1.0", - "postcss-discard-empty": "2.1.0", - "postcss-discard-overridden": "0.1.1", - "postcss-discard-unused": "2.2.3", - "postcss-filter-plugins": "2.0.2", - "postcss-merge-idents": "2.1.7", - "postcss-merge-longhand": "2.0.2", - "postcss-merge-rules": "2.1.2", - "postcss-minify-font-values": "1.0.5", - "postcss-minify-gradients": "1.0.5", - "postcss-minify-params": "1.2.2", - "postcss-minify-selectors": "2.1.1", - "postcss-normalize-charset": "1.1.1", - "postcss-normalize-url": "3.0.8", - "postcss-ordered-values": "2.2.3", - "postcss-reduce-idents": "2.4.0", - "postcss-reduce-initial": "1.0.1", - "postcss-reduce-transforms": "1.0.4", - "postcss-svgo": "2.1.6", - "postcss-unique-selectors": "2.0.2", - "postcss-value-parser": "3.3.0", - "postcss-zindex": "2.2.0" - } - }, - "csso": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/csso/-/csso-2.0.0.tgz", - "integrity": "sha1-F4tDpEYhIhwndWCG9THgL0KQDug=", - "dev": true, - "requires": { - "clap": "1.2.3", - "source-map": "0.5.7" - } - }, - "cssom": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.2.tgz", - "integrity": "sha1-uANhcMefB6kP8vFuIihAJ6JDhIs=", - "dev": true - }, - "cssstyle": { - "version": "0.2.37", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-0.2.37.tgz", - "integrity": "sha1-VBCXI0yyUTyDzu06zdwn/yeYfVQ=", - "dev": true, - "optional": true, - "requires": { - "cssom": "0.3.2" - } - }, - "csurf": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/csurf/-/csurf-1.8.3.tgz", - "integrity": "sha1-I/KhO/HY/OHQyZZYg5RELLqGpWo=", - "dev": true, - "requires": { - "cookie": "0.1.3", - "cookie-signature": "1.0.6", - "csrf": "3.0.6", - "http-errors": "1.3.1" - }, - "dependencies": { - "http-errors": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.3.1.tgz", - "integrity": "sha1-GX4izevUGYWF6GlO9nhhl7ke2UI=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "statuses": "1.3.1" - } - } - } - }, - "currently-unhandled": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", - "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", - "dev": true, - "requires": { - "array-find-index": "1.0.2" - } - }, - "dargs": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/dargs/-/dargs-2.1.0.tgz", - "integrity": "sha1-RsJ/+rH/sTeO8hJZchNxn+YCvJM=", - "dev": true - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, - "requires": { - "assert-plus": "1.0.0" - } - }, - "date-now": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", - "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", - "dev": true - }, - "dateformat": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.2.0.tgz", - "integrity": "sha1-QGXiATz5+5Ft39gu+1Bq1MZ2kGI=", - "dev": true - }, - "deap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/deap/-/deap-1.0.0.tgz", - "integrity": "sha1-sUi/gkMKJ2mbdIOgPra2dYW/yIg=", - "dev": true - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "debug-fabulous": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/debug-fabulous/-/debug-fabulous-0.0.4.tgz", - "integrity": "sha1-+gccXYdIRoVCSAdCHKSxawsaB2M=", - "dev": true, - "requires": { - "debug": "2.6.9", - "lazy-debug-legacy": "0.0.1", - "object-assign": "4.1.0" - }, - "dependencies": { - "object-assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz", - "integrity": "sha1-ejs9DpgGPUP0wD8uiubNUahog6A=", - "dev": true - } - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decompress": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/decompress/-/decompress-3.0.0.tgz", - "integrity": "sha1-rx3VDQbjv8QyRh033hGzjA2ZG+0=", - "dev": true, - "requires": { - "buffer-to-vinyl": "1.1.0", - "concat-stream": "1.6.0", - "decompress-tar": "3.1.0", - "decompress-tarbz2": "3.1.0", - "decompress-targz": "3.1.0", - "decompress-unzip": "3.4.0", - "stream-combiner2": "1.1.1", - "vinyl-assign": "1.2.1", - "vinyl-fs": "2.4.4" - }, - "dependencies": { - "glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", - "dev": true, - "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "3.1.0", - "path-dirname": "1.0.2" - } - }, - "glob-stream": { - "version": "5.3.5", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-5.3.5.tgz", - "integrity": "sha1-pVZlqajM3EGRWofHAeMtTgFvrSI=", - "dev": true, - "requires": { - "extend": "3.0.1", - "glob": "5.0.15", - "glob-parent": "3.1.0", - "micromatch": "2.3.11", - "ordered-read-streams": "0.3.0", - "through2": "0.6.5", - "to-absolute-glob": "0.1.1", - "unique-stream": "2.2.1" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" - } - } - } - }, - "gulp-sourcemaps": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-1.6.0.tgz", - "integrity": "sha1-uG/zSdgBzrVuHZ59x7vLS33uYAw=", - "dev": true, - "requires": { - "convert-source-map": "1.5.0", - "graceful-fs": "4.1.11", - "strip-bom": "2.0.0", - "through2": "2.0.3", - "vinyl": "1.2.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "2.1.1" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "ordered-read-streams": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.3.0.tgz", - "integrity": "sha1-cTfmmzKYuzQiR6G77jiByA4v14s=", - "dev": true, - "requires": { - "is-stream": "1.1.0", - "readable-stream": "2.3.3" - } - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - }, - "unique-stream": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.2.1.tgz", - "integrity": "sha1-WqADz76Uxf+GbE59ZouxxNuts2k=", - "dev": true, - "requires": { - "json-stable-stringify": "1.0.1", - "through2-filter": "2.0.0" - } - }, - "vinyl": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", - "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", - "dev": true, - "requires": { - "clone": "1.0.2", - "clone-stats": "0.0.1", - "replace-ext": "0.0.1" - } - }, - "vinyl-fs": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-2.4.4.tgz", - "integrity": "sha1-vm/zJwy1Xf19MGNkDegfJddTIjk=", - "dev": true, - "requires": { - "duplexify": "3.5.1", - "glob-stream": "5.3.5", - "graceful-fs": "4.1.11", - "gulp-sourcemaps": "1.6.0", - "is-valid-glob": "0.3.0", - "lazystream": "1.0.0", - "lodash.isequal": "4.5.0", - "merge-stream": "1.0.1", - "mkdirp": "0.5.1", - "object-assign": "4.1.1", - "readable-stream": "2.3.3", - "strip-bom": "2.0.0", - "strip-bom-stream": "1.0.0", - "through2": "2.0.3", - "through2-filter": "2.0.0", - "vali-date": "1.0.0", - "vinyl": "1.2.0" - } - } - } - }, - "decompress-tar": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-3.1.0.tgz", - "integrity": "sha1-IXx4n5uURQ76rcXF5TeXj8MzxGY=", - "dev": true, - "requires": { - "is-tar": "1.0.0", - "object-assign": "2.1.1", - "strip-dirs": "1.1.1", - "tar-stream": "1.5.4", - "through2": "0.6.5", - "vinyl": "0.4.6" - }, - "dependencies": { - "clone": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz", - "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=", - "dev": true - }, - "object-assign": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz", - "integrity": "sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo=", - "dev": true - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" - } - }, - "vinyl": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz", - "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=", - "dev": true, - "requires": { - "clone": "0.2.0", - "clone-stats": "0.0.1" - } - } - } - }, - "decompress-tarbz2": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-3.1.0.tgz", - "integrity": "sha1-iyOTVoE1X58YnYclag+L3ZbZZm0=", - "dev": true, - "requires": { - "is-bzip2": "1.0.0", - "object-assign": "2.1.1", - "seek-bzip": "1.0.5", - "strip-dirs": "1.1.1", - "tar-stream": "1.5.4", - "through2": "0.6.5", - "vinyl": "0.4.6" - }, - "dependencies": { - "clone": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz", - "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=", - "dev": true - }, - "object-assign": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz", - "integrity": "sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo=", - "dev": true - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" - } - }, - "vinyl": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz", - "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=", - "dev": true, - "requires": { - "clone": "0.2.0", - "clone-stats": "0.0.1" - } - } - } - }, - "decompress-targz": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-3.1.0.tgz", - "integrity": "sha1-ssE9+YFmJomRtxXWRH9kLpaW9aA=", - "dev": true, - "requires": { - "is-gzip": "1.0.0", - "object-assign": "2.1.1", - "strip-dirs": "1.1.1", - "tar-stream": "1.5.4", - "through2": "0.6.5", - "vinyl": "0.4.6" - }, - "dependencies": { - "clone": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz", - "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=", - "dev": true - }, - "object-assign": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz", - "integrity": "sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo=", - "dev": true - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" - } - }, - "vinyl": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz", - "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=", - "dev": true, - "requires": { - "clone": "0.2.0", - "clone-stats": "0.0.1" - } - } - } - }, - "decompress-unzip": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-3.4.0.tgz", - "integrity": "sha1-YUdbQVIGa74/7hL51inRX+ZHjus=", - "dev": true, - "requires": { - "is-zip": "1.0.0", - "read-all-stream": "3.1.0", - "stat-mode": "0.2.2", - "strip-dirs": "1.1.1", - "through2": "2.0.3", - "vinyl": "1.2.0", - "yauzl": "2.4.1" - }, - "dependencies": { - "vinyl": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", - "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", - "dev": true, - "requires": { - "clone": "1.0.2", - "clone-stats": "0.0.1", - "replace-ext": "0.0.1" - } - } - } - }, - "deep-extend": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz", - "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=", - "dev": true - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true, - "optional": true - }, - "defaults": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", - "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", - "dev": true, - "requires": { - "clone": "1.0.2" - } - }, - "defined": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", - "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", - "dev": true - }, - "del": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", - "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", - "dev": true, - "requires": { - "globby": "5.0.0", - "is-path-cwd": "1.0.0", - "is-path-in-cwd": "1.0.0", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "rimraf": "2.6.2" - }, - "dependencies": { - "globby": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", - "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", - "dev": true, - "requires": { - "array-union": "1.0.2", - "arrify": "1.0.1", - "glob": "7.1.2", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" - } - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true - }, - "depd": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", - "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=", - "dev": true - }, - "deprecated": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/deprecated/-/deprecated-0.0.1.tgz", - "integrity": "sha1-+cmvVGSvoeepcUWKi97yqpTVuxk=", - "dev": true - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", - "dev": true - }, - "detect-file": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-0.1.0.tgz", - "integrity": "sha1-STXe39lIhkjgBrASlWbpOGcR6mM=", - "dev": true, - "requires": { - "fs-exists-sync": "0.1.0" - } - }, - "detect-newline": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", - "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=", - "dev": true - }, - "dom-serializer": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", - "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=", - "dev": true, - "requires": { - "domelementtype": "1.1.3", - "entities": "1.1.1" - }, - "dependencies": { - "domelementtype": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", - "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=", - "dev": true - } - } - }, - "domelementtype": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz", - "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=", - "dev": true - }, - "domhandler": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", - "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=", - "dev": true, - "requires": { - "domelementtype": "1.3.0" - } - }, - "domutils": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", - "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", - "dev": true, - "requires": { - "dom-serializer": "0.1.0", - "domelementtype": "1.3.0" - } - }, - "dot-prop": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-3.0.0.tgz", - "integrity": "sha1-G3CK8JSknJoOfbyteQq6U52sEXc=", - "dev": true, - "requires": { - "is-obj": "1.0.1" - } - }, - "download": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/download/-/download-4.4.3.tgz", - "integrity": "sha1-qlX9rTktldS2jowr4D4MKqIbqaw=", - "dev": true, - "requires": { - "caw": "1.2.0", - "concat-stream": "1.6.0", - "each-async": "1.1.1", - "filenamify": "1.2.1", - "got": "5.7.1", - "gulp-decompress": "1.2.0", - "gulp-rename": "1.2.2", - "is-url": "1.2.2", - "object-assign": "4.1.1", - "read-all-stream": "3.1.0", - "readable-stream": "2.3.3", - "stream-combiner2": "1.1.1", - "vinyl": "1.2.0", - "vinyl-fs": "2.4.4", - "ware": "1.3.0" - }, - "dependencies": { - "glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", - "dev": true, - "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "3.1.0", - "path-dirname": "1.0.2" - } - }, - "glob-stream": { - "version": "5.3.5", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-5.3.5.tgz", - "integrity": "sha1-pVZlqajM3EGRWofHAeMtTgFvrSI=", - "dev": true, - "requires": { - "extend": "3.0.1", - "glob": "5.0.15", - "glob-parent": "3.1.0", - "micromatch": "2.3.11", - "ordered-read-streams": "0.3.0", - "through2": "0.6.5", - "to-absolute-glob": "0.1.1", - "unique-stream": "2.2.1" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" - } - } - } - }, - "gulp-sourcemaps": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-1.6.0.tgz", - "integrity": "sha1-uG/zSdgBzrVuHZ59x7vLS33uYAw=", - "dev": true, - "requires": { - "convert-source-map": "1.5.0", - "graceful-fs": "4.1.11", - "strip-bom": "2.0.0", - "through2": "2.0.3", - "vinyl": "1.2.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "2.1.1" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "ordered-read-streams": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.3.0.tgz", - "integrity": "sha1-cTfmmzKYuzQiR6G77jiByA4v14s=", - "dev": true, - "requires": { - "is-stream": "1.1.0", - "readable-stream": "2.3.3" - } - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - }, - "unique-stream": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.2.1.tgz", - "integrity": "sha1-WqADz76Uxf+GbE59ZouxxNuts2k=", - "dev": true, - "requires": { - "json-stable-stringify": "1.0.1", - "through2-filter": "2.0.0" - } - }, - "vinyl": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", - "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", - "dev": true, - "requires": { - "clone": "1.0.2", - "clone-stats": "0.0.1", - "replace-ext": "0.0.1" - } - }, - "vinyl-fs": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-2.4.4.tgz", - "integrity": "sha1-vm/zJwy1Xf19MGNkDegfJddTIjk=", - "dev": true, - "requires": { - "duplexify": "3.5.1", - "glob-stream": "5.3.5", - "graceful-fs": "4.1.11", - "gulp-sourcemaps": "1.6.0", - "is-valid-glob": "0.3.0", - "lazystream": "1.0.0", - "lodash.isequal": "4.5.0", - "merge-stream": "1.0.1", - "mkdirp": "0.5.1", - "object-assign": "4.1.1", - "readable-stream": "2.3.3", - "strip-bom": "2.0.0", - "strip-bom-stream": "1.0.0", - "through2": "2.0.3", - "through2-filter": "2.0.0", - "vali-date": "1.0.0", - "vinyl": "1.2.0" - } - } - } - }, - "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", - "dev": true - }, - "duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", - "dev": true, - "requires": { - "readable-stream": "2.3.3" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - } - } - }, - "duplexify": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.1.tgz", - "integrity": "sha512-j5goxHTwVED1Fpe5hh3q9R93Kip0Bg2KVAt4f8CEYM3UEwYcPSvWbXaUQOzdX/HtiNomipv+gU7ASQPDbV7pGQ==", - "dev": true, - "requires": { - "end-of-stream": "1.4.0", - "inherits": "2.0.3", - "readable-stream": "2.3.3", - "stream-shift": "1.0.0" - }, - "dependencies": { - "end-of-stream": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.0.tgz", - "integrity": "sha1-epDYM+/abPpurA9JSduw+tOmMgY=", - "dev": true, - "requires": { - "once": "1.4.0" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - } - } - }, - "each-async": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/each-async/-/each-async-1.1.1.tgz", - "integrity": "sha1-3uUim98KtrogEqOV4bhpq/iBNHM=", - "dev": true, - "requires": { - "onetime": "1.1.0", - "set-immediate-shim": "1.0.1" - } - }, - "ecc-jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", - "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", - "dev": true, - "optional": true, - "requires": { - "jsbn": "0.1.1" - } - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true - }, - "electron-to-chromium": { - "version": "1.3.22", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.22.tgz", - "integrity": "sha1-QyLVLBUUBuPq73StAmdog+hBZBg=", - "dev": true - }, - "encodeurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz", - "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA=", - "dev": true - }, - "end-of-stream": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-0.1.5.tgz", - "integrity": "sha1-jhdyBsPICDfYVjLouTWd/osvbq8=", - "dev": true, - "requires": { - "once": "1.3.3" - }, - "dependencies": { - "once": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz", - "integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=", - "dev": true, - "requires": { - "wrappy": "1.0.2" - } - } - } - }, - "entities": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", - "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=", - "dev": true - }, - "error-ex": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", - "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", - "dev": true, - "requires": { - "is-arrayish": "0.2.1" - } - }, - "errorhandler": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/errorhandler/-/errorhandler-1.4.3.tgz", - "integrity": "sha1-t7cO2PNZ6duICS8tIMD4MUIK2D8=", - "dev": true, - "requires": { - "accepts": "1.3.4", - "escape-html": "1.0.3" - }, - "dependencies": { - "accepts": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz", - "integrity": "sha1-hiRnWMfdbSGmR0/whKR0DsBesh8=", - "dev": true, - "requires": { - "mime-types": "2.1.17", - "negotiator": "0.6.1" - } - }, - "negotiator": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", - "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", - "dev": true - } - } - }, - "es6-promise": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.0.5.tgz", - "integrity": "sha1-eILzCt3lskDM+n99eMVIMwlRrkI=", - "dev": true - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "escodegen": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.9.0.tgz", - "integrity": "sha512-v0MYvNQ32bzwoG2OSFzWAkuahDQHK92JBN0pTAALJ4RIxEZe766QJPDR8Hqy7XNUy5K3fnVL76OqYAdc4TZEIw==", - "dev": true, - "optional": true, - "requires": { - "esprima": "3.1.3", - "estraverse": "4.2.0", - "esutils": "2.0.2", - "optionator": "0.8.2", - "source-map": "0.5.7" - } - }, - "esprima": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", - "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", - "dev": true, - "optional": true - }, - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true, - "optional": true - }, - "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true, - "optional": true - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "dev": true - }, - "event-stream": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", - "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", - "dev": true, - "requires": { - "duplexer": "0.1.1", - "from": "0.1.7", - "map-stream": "0.1.0", - "pause-stream": "0.0.11", - "split": "0.3.3", - "stream-combiner": "0.0.4", - "through": "2.3.8" - } - }, - "exec-buffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/exec-buffer/-/exec-buffer-2.0.1.tgz", - "integrity": "sha1-ACijG+CxRgth0HX5avRYO54zXqA=", - "dev": true, - "optional": true, - "requires": { - "rimraf": "2.6.2", - "tempfile": "1.1.1" - } - }, - "exec-series": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/exec-series/-/exec-series-1.0.3.tgz", - "integrity": "sha1-bSV6m+rEgqhyx3g7yGFYOfx3FDo=", - "dev": true, - "optional": true, - "requires": { - "async-each-series": "1.1.0", - "object-assign": "4.1.1" - } - }, - "executable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/executable/-/executable-1.1.0.tgz", - "integrity": "sha1-h3mA6REvM5EGbaNyZd562ENKtNk=", - "dev": true, - "optional": true, - "requires": { - "meow": "3.7.0" - } - }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", - "dev": true - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "0.1.1" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { - "fill-range": "2.2.3" - } - }, - "expand-tilde": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-1.2.2.tgz", - "integrity": "sha1-C4HrqJflo9MdHD0QL48BRB5VlEk=", - "dev": true, - "requires": { - "os-homedir": "1.0.2" - } - }, - "express-session": { - "version": "1.11.3", - "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.11.3.tgz", - "integrity": "sha1-XMmPP1/4Ttg1+Ry/CqvQxxB0AK8=", - "dev": true, - "requires": { - "cookie": "0.1.3", - "cookie-signature": "1.0.6", - "crc": "3.3.0", - "debug": "2.2.0", - "depd": "1.0.1", - "on-headers": "1.0.1", - "parseurl": "1.3.2", - "uid-safe": "2.0.0", - "utils-merge": "1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", - "dev": true, - "requires": { - "ms": "0.7.1" - } - }, - "depd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.0.1.tgz", - "integrity": "sha1-gK7GTJ1tl+ZcwqnKqTwKpqv3Oqo=", - "dev": true - }, - "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", - "dev": true - }, - "uid-safe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.0.0.tgz", - "integrity": "sha1-p/PGymSh9qXQTsDvPkw9U2cxcTc=", - "dev": true, - "requires": { - "base64-url": "1.2.1" - } - } - } - }, - "extend": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", - "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", - "dev": true - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "0.1.1" - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "1.0.0" - } - }, - "extract-css": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/extract-css/-/extract-css-1.0.3.tgz", - "integrity": "sha1-rKe4S/fhOKXfqyuQJKSZVJ+TUEY=", - "dev": true, - "requires": { - "batch": "0.5.3", - "href-content": "1.0.2", - "list-stylesheets": "1.1.0", - "style-data": "1.1.2" - } - }, - "extract-zip": { - "version": "1.6.5", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.5.tgz", - "integrity": "sha1-maBnNbbqIOqbcF13ms/8yHz/BEA=", - "dev": true, - "requires": { - "concat-stream": "1.6.0", - "debug": "2.2.0", - "mkdirp": "0.5.0", - "yauzl": "2.4.1" - }, - "dependencies": { - "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", - "dev": true, - "requires": { - "ms": "0.7.1" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, - "mkdirp": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz", - "integrity": "sha1-HXMHam35hs2TROFecfzAWkyavxI=", - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", - "dev": true - } - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true - }, - "fancy-log": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.0.tgz", - "integrity": "sha1-Rb4X0Cu5kX1gzP/UmVyZnmyMmUg=", - "dev": true, - "requires": { - "chalk": "1.1.3", - "time-stamp": "1.1.0" - } - }, - "fast-deep-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", - "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true, - "optional": true - }, - "faye-websocket": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", - "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", - "dev": true, - "requires": { - "websocket-driver": "0.7.0" - } - }, - "fd-slicer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", - "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", - "dev": true, - "requires": { - "pend": "1.2.0" - } - }, - "fg-loadcss": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/fg-loadcss/-/fg-loadcss-0.2.4.tgz", - "integrity": "sha1-9XCvWaBK3xQE4fZ1XEeAO9UNSik=", - "dev": true - }, - "figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", - "dev": true, - "optional": true, - "requires": { - "escape-string-regexp": "1.0.5", - "object-assign": "4.1.1" - } - }, - "file-type": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", - "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=", - "dev": true - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, - "filename-reserved-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-1.0.0.tgz", - "integrity": "sha1-5hz4BfDeHJhFZ9A4bcXfUO5a9+Q=", - "dev": true - }, - "filenamify": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-1.2.1.tgz", - "integrity": "sha1-qfL/0RxQO+0wABUCknI3jx8TZaU=", - "dev": true, - "requires": { - "filename-reserved-regex": "1.0.0", - "strip-outer": "1.0.0", - "trim-repeated": "1.0.0" - } - }, - "filesize": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/filesize/-/filesize-3.3.0.tgz", - "integrity": "sha1-UxSeo0YOOy4CSWKlFkiqVyz5gSI=", - "dev": true - }, - "fill-range": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", - "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", - "dev": true, - "requires": { - "is-number": "2.1.0", - "isobject": "2.1.0", - "randomatic": "1.1.7", - "repeat-element": "1.1.2", - "repeat-string": "1.6.1" - } - }, - "filled-array": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/filled-array/-/filled-array-1.1.0.tgz", - "integrity": "sha1-w8T2xmO5I0WamqKZEtLQMfFQf4Q=", - "dev": true - }, - "filter-css": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/filter-css/-/filter-css-0.1.2.tgz", - "integrity": "sha1-Sk0BWyGhRamWFxA4+AYMAxV17gk=", - "dev": true, - "requires": { - "css": "2.2.1", - "get-stdin": "5.0.1", - "lodash": "4.17.4", - "meow": "3.7.0", - "update-notifier": "0.7.0" - } - }, - "finalhandler": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-0.4.1.tgz", - "integrity": "sha1-haF8bFmpRxfSYtYSMNSw6+PUoU0=", - "dev": true, - "requires": { - "debug": "2.2.0", - "escape-html": "1.0.3", - "on-finished": "2.3.0", - "unpipe": "1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", - "dev": true, - "requires": { - "ms": "0.7.1" - } - }, - "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", - "dev": true - } - } - }, - "find-index": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", - "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=", - "dev": true - }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "2.1.0", - "pinkie-promise": "2.0.1" - } - }, - "find-versions": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-1.2.1.tgz", - "integrity": "sha1-y96fEuOFdaCvG+G5osXV/Y8Ya2I=", - "dev": true, - "optional": true, - "requires": { - "array-uniq": "1.0.3", - "get-stdin": "4.0.1", - "meow": "3.7.0", - "semver-regex": "1.0.0" - }, - "dependencies": { - "get-stdin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", - "dev": true, - "optional": true - } - } - }, - "findup-sync": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.4.3.tgz", - "integrity": "sha1-QAQ5Kee8YK3wt/SCfExudaDeyhI=", - "dev": true, - "requires": { - "detect-file": "0.1.0", - "is-glob": "2.0.1", - "micromatch": "2.3.11", - "resolve-dir": "0.1.1" - } - }, - "fined": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fined/-/fined-1.1.0.tgz", - "integrity": "sha1-s33IRLdqL15wgeiE98CuNE8VNHY=", - "dev": true, - "requires": { - "expand-tilde": "2.0.2", - "is-plain-object": "2.0.4", - "object.defaults": "1.1.0", - "object.pick": "1.3.0", - "parse-filepath": "1.0.1" - }, - "dependencies": { - "expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", - "dev": true, - "requires": { - "homedir-polyfill": "1.0.1" - } - } - } - }, - "first-chunk-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz", - "integrity": "sha1-Wb+1DNkF9g18OUzT2ayqtOatk04=", - "dev": true - }, - "flagged-respawn": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-0.3.2.tgz", - "integrity": "sha1-/xke3c1wiKZ1smEP/8l2vpuAdLU=", - "dev": true - }, - "flatten": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz", - "integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=", - "dev": true - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "1.0.2" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true - }, - "form-data": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz", - "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=", - "dev": true, - "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.17" - } - }, - "formidable": { - "version": "1.0.17", - "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.0.17.tgz", - "integrity": "sha1-71SRSQ+UM7cF+qdyScmQKa40hVk=", - "dev": true - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "dev": true - }, - "from": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", - "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=", - "dev": true - }, - "fs-exists-sync": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz", - "integrity": "sha1-mC1ok6+RjnLQjeyehnP/K1qNat0=", - "dev": true - }, - "fs-extra": { - "version": "0.26.7", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.26.7.tgz", - "integrity": "sha1-muH92UiXeY7at20JGM9C0MMYT6k=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "jsonfile": "2.4.0", - "klaw": "1.3.1", - "path-is-absolute": "1.0.1", - "rimraf": "2.6.2" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "gaze": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/gaze/-/gaze-0.5.2.tgz", - "integrity": "sha1-QLcJU30k0dRXZ9takIaJ3+aaxE8=", - "dev": true, - "requires": { - "globule": "0.1.0" - } - }, - "generate-function": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", - "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", - "dev": true - }, - "generate-object-property": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", - "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", - "dev": true, - "requires": { - "is-property": "1.0.2" - } - }, - "get-port": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-2.1.0.tgz", - "integrity": "sha1-h4P53OvR7qSVozThpqJR54iHqxo=", - "dev": true, - "requires": { - "pinkie-promise": "2.0.1" - } - }, - "get-proxy": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/get-proxy/-/get-proxy-1.1.0.tgz", - "integrity": "sha1-iUhUSRvFkbDxR9euVw9cZ4tyVus=", - "dev": true, - "requires": { - "rc": "1.2.1" - } - }, - "get-stdin": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz", - "integrity": "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, - "requires": { - "assert-plus": "1.0.0" - } - }, - "gifsicle": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/gifsicle/-/gifsicle-3.0.4.tgz", - "integrity": "sha1-9Fy17RAWW2ZdySng6TKLbIId+js=", - "dev": true, - "optional": true, - "requires": { - "bin-build": "2.2.0", - "bin-wrapper": "3.0.2", - "logalot": "2.1.0" - } - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "2.0.0", - "is-glob": "2.0.1" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "2.0.1" - } - }, - "glob-stream": { - "version": "3.1.18", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-3.1.18.tgz", - "integrity": "sha1-kXCl8St5Awb9/lmPMT+PeVT9FDs=", - "dev": true, - "requires": { - "glob": "4.5.3", - "glob2base": "0.0.12", - "minimatch": "2.0.10", - "ordered-read-streams": "0.1.0", - "through2": "0.6.5", - "unique-stream": "1.0.0" - }, - "dependencies": { - "glob": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-4.5.3.tgz", - "integrity": "sha1-xstz0yJsHv7wTePFbQEvAzd+4V8=", - "dev": true, - "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "2.0.10", - "once": "1.4.0" - } - }, - "minimatch": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", - "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=", - "dev": true, - "requires": { - "brace-expansion": "1.1.8" - } - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" - } - } - } - }, - "glob-watcher": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-0.0.6.tgz", - "integrity": "sha1-uVtKjfdLOcgymLDAXJeLTZo7cQs=", - "dev": true, - "requires": { - "gaze": "0.5.2" - } - }, - "glob2base": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", - "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", - "dev": true, - "requires": { - "find-index": "0.1.1" - } - }, - "global-modules": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-0.2.3.tgz", - "integrity": "sha1-6lo77ULG1s6ZWk+KEmm12uIjgo0=", - "dev": true, - "requires": { - "global-prefix": "0.1.5", - "is-windows": "0.2.0" - } - }, - "global-prefix": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-0.1.5.tgz", - "integrity": "sha1-jTvGuNo8qBEqFg2NSW/wRiv+948=", - "dev": true, - "requires": { - "homedir-polyfill": "1.0.1", - "ini": "1.3.4", - "is-windows": "0.2.0", - "which": "1.2.14" - } - }, - "globby": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-4.1.0.tgz", - "integrity": "sha1-CA9UVJ7BuCpsYOYx/ILhIR2+lfg=", - "dev": true, - "requires": { - "array-union": "1.0.2", - "arrify": "1.0.1", - "glob": "6.0.4", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "dev": true, - "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - } - } - }, - "globule": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/globule/-/globule-0.1.0.tgz", - "integrity": "sha1-2cjt3h2nnRJaFRt5UzuXhnY0auU=", - "dev": true, - "requires": { - "glob": "3.1.21", - "lodash": "1.0.2", - "minimatch": "0.2.14" - }, - "dependencies": { - "glob": { - "version": "3.1.21", - "resolved": "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz", - "integrity": "sha1-0p4KBV3qUTj00H7UDomC6DwgZs0=", - "dev": true, - "requires": { - "graceful-fs": "1.2.3", - "inherits": "1.0.2", - "minimatch": "0.2.14" - } - }, - "graceful-fs": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz", - "integrity": "sha1-FaSAaldUfLLS2/J/QuiajDRRs2Q=", - "dev": true - }, - "inherits": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-1.0.2.tgz", - "integrity": "sha1-ykMJ2t7mtUzAuNJH6NfHoJdb3Js=", - "dev": true - }, - "lodash": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-1.0.2.tgz", - "integrity": "sha1-j1dWDIO1n8JwvT1WG2kAQ0MOJVE=", - "dev": true - }, - "minimatch": { - "version": "0.2.14", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz", - "integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=", - "dev": true, - "requires": { - "lru-cache": "2.7.3", - "sigmund": "1.0.1" - } - } - } - }, - "glogg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.0.tgz", - "integrity": "sha1-f+DxmfV6yQbPUS/urY+Q7kooT8U=", - "dev": true, - "requires": { - "sparkles": "1.0.0" - } - }, - "got": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/got/-/got-5.7.1.tgz", - "integrity": "sha1-X4FjWmHkplifGAVp6k44FoClHzU=", - "dev": true, - "requires": { - "create-error-class": "3.0.2", - "duplexer2": "0.1.4", - "is-redirect": "1.0.0", - "is-retry-allowed": "1.1.0", - "is-stream": "1.1.0", - "lowercase-keys": "1.0.0", - "node-status-codes": "1.0.0", - "object-assign": "4.1.1", - "parse-json": "2.2.0", - "pinkie-promise": "2.0.1", - "read-all-stream": "3.1.0", - "readable-stream": "2.3.3", - "timed-out": "3.1.3", - "unzip-response": "1.0.2", - "url-parse-lax": "1.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - } - } - }, - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - }, - "graceful-readlink": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", - "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", - "dev": true - }, - "growly": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", - "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", - "dev": true - }, - "gulp": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/gulp/-/gulp-3.9.1.tgz", - "integrity": "sha1-VxzkWSjdQK9lFPxAEYZgFsE4RbQ=", - "dev": true, - "requires": { - "archy": "1.0.0", - "chalk": "1.1.3", - "deprecated": "0.0.1", - "gulp-util": "3.0.8", - "interpret": "1.0.4", - "liftoff": "2.3.0", - "minimist": "1.2.0", - "orchestrator": "0.3.8", - "pretty-hrtime": "1.0.3", - "semver": "4.3.6", - "tildify": "1.2.0", - "v8flags": "2.1.1", - "vinyl-fs": "0.3.14" - }, - "dependencies": { - "semver": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz", - "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=", - "dev": true - } - } - }, - "gulp-autoprefixer": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/gulp-autoprefixer/-/gulp-autoprefixer-3.1.1.tgz", - "integrity": "sha1-dSMAUc0NFxND14O36bXREg7u+bA=", - "dev": true, - "requires": { - "autoprefixer": "6.7.7", - "gulp-util": "3.0.8", - "postcss": "5.2.17", - "through2": "2.0.3", - "vinyl-sourcemaps-apply": "0.2.1" - } - }, - "gulp-cache": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/gulp-cache/-/gulp-cache-0.4.6.tgz", - "integrity": "sha1-LQO1LbT2pVOuHVvvAeSD6Qfp95Y=", - "dev": true, - "requires": { - "bluebird": "3.5.0", - "cache-swap": "0.3.0", - "gulp-util": "3.0.8", - "object-assign": "4.1.1", - "object.omit": "2.0.1", - "object.pick": "1.3.0", - "readable-stream": "2.3.3", - "try-json-parse": "0.1.1", - "vinyl": "1.2.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - }, - "vinyl": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", - "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", - "dev": true, - "requires": { - "clone": "1.0.2", - "clone-stats": "0.0.1", - "replace-ext": "0.0.1" - } - } - } - }, - "gulp-concat": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/gulp-concat/-/gulp-concat-2.6.1.tgz", - "integrity": "sha1-Yz0WyV2IUEYorQJmVmPO5aR5M1M=", - "dev": true, - "requires": { - "concat-with-sourcemaps": "1.0.4", - "through2": "2.0.3", - "vinyl": "2.1.0" - }, - "dependencies": { - "clone": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz", - "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=", - "dev": true - }, - "clone-stats": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", - "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", - "dev": true - }, - "replace-ext": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", - "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", - "dev": true - }, - "vinyl": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.1.0.tgz", - "integrity": "sha1-Ah+cLPlR1rk5lDyJ617lrdT9kkw=", - "dev": true, - "requires": { - "clone": "2.1.1", - "clone-buffer": "1.0.0", - "clone-stats": "1.0.0", - "cloneable-readable": "1.0.0", - "remove-trailing-separator": "1.1.0", - "replace-ext": "1.0.0" - } - } - } - }, - "gulp-connect": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/gulp-connect/-/gulp-connect-4.2.0.tgz", - "integrity": "sha1-qeoRzty8XBOhY4rH9sgeWBjD1V4=", - "dev": true, - "requires": { - "connect": "2.30.2", - "connect-livereload": "0.5.4", - "event-stream": "3.3.4", - "gulp-util": "3.0.8", - "http2": "3.3.7", - "tiny-lr": "0.2.1" - } - }, - "gulp-cssnano": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/gulp-cssnano/-/gulp-cssnano-2.1.2.tgz", - "integrity": "sha1-4IoJdx7FRUpUnxoAW90lbLjl4KM=", - "dev": true, - "requires": { - "cssnano": "3.10.0", - "gulp-util": "3.0.8", - "object-assign": "4.1.1", - "vinyl-sourcemaps-apply": "0.2.1" - } - }, - "gulp-decompress": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gulp-decompress/-/gulp-decompress-1.2.0.tgz", - "integrity": "sha1-jutlpeAV+O2FMsr+KEVJYGJvDcc=", - "dev": true, - "requires": { - "archive-type": "3.2.0", - "decompress": "3.0.0", - "gulp-util": "3.0.8", - "readable-stream": "2.3.3" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - } - } - }, - "gulp-imagemin": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/gulp-imagemin/-/gulp-imagemin-2.4.0.tgz", - "integrity": "sha1-+FlIp3r1MrQRXcn7+sBK+GOnWLo=", - "dev": true, - "requires": { - "chalk": "1.1.3", - "gulp-util": "3.0.8", - "imagemin": "4.0.0", - "object-assign": "4.1.1", - "plur": "2.1.2", - "pretty-bytes": "2.0.1", - "through2-concurrent": "1.1.1" - } - }, - "gulp-inline-css": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/gulp-inline-css/-/gulp-inline-css-3.1.0.tgz", - "integrity": "sha1-cdbf8q2uW6JB6vVoeY/706nIzwk=", - "dev": true, - "requires": { - "gulp-util": "3.0.8", - "inline-css": "2.2.2", - "through2": "0.6.5" - }, - "dependencies": { - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" - } - } - } - }, - "gulp-jshint": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/gulp-jshint/-/gulp-jshint-2.0.4.tgz", - "integrity": "sha1-84KxhWSxBy3vDJqvdTwUba208Og=", - "dev": true, - "requires": { - "gulp-util": "3.0.8", - "lodash": "4.17.4", - "minimatch": "3.0.4", - "rcloader": "0.2.2", - "through2": "2.0.3" - } - }, - "gulp-livereload": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/gulp-livereload/-/gulp-livereload-3.8.1.tgz", - "integrity": "sha1-APdEstdJ0+njdGWJyKRKysd5tQ8=", - "dev": true, - "requires": { - "chalk": "0.5.1", - "debug": "2.6.9", - "event-stream": "3.3.4", - "gulp-util": "3.0.8", - "lodash.assign": "3.2.0", - "mini-lr": "0.1.9" - }, - "dependencies": { - "ansi-regex": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", - "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=", - "dev": true - }, - "ansi-styles": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz", - "integrity": "sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94=", - "dev": true - }, - "chalk": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz", - "integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=", - "dev": true, - "requires": { - "ansi-styles": "1.1.0", - "escape-string-regexp": "1.0.5", - "has-ansi": "0.1.0", - "strip-ansi": "0.3.0", - "supports-color": "0.2.0" - } - }, - "has-ansi": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz", - "integrity": "sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4=", - "dev": true, - "requires": { - "ansi-regex": "0.2.1" - } - }, - "lodash.assign": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-3.2.0.tgz", - "integrity": "sha1-POnwI0tLIiPilrj6CsH+6OvKZPo=", - "dev": true, - "requires": { - "lodash._baseassign": "3.2.0", - "lodash._createassigner": "3.1.1", - "lodash.keys": "3.1.2" - } - }, - "strip-ansi": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", - "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=", - "dev": true, - "requires": { - "ansi-regex": "0.2.1" - } - }, - "supports-color": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz", - "integrity": "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo=", - "dev": true - } - } - }, - "gulp-notify": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/gulp-notify/-/gulp-notify-3.2.0.tgz", - "integrity": "sha512-qEocs1UVoDKKUjfsxJNMNwkRla0PbsyJwsqNNXpzYWsLQ29LhxRMY3wnTGZcc4hMHtalnvah/Dwlwb4NijH/0A==", - "dev": true, - "requires": { - "ansi-colors": "1.1.0", - "fancy-log": "1.3.2", - "lodash.template": "4.4.0", - "node-notifier": "5.2.1", - "node.extend": "2.0.0", - "plugin-error": "0.1.2", - "through2": "2.0.3" - }, - "dependencies": { - "fancy-log": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.2.tgz", - "integrity": "sha1-9BEl49hPLn2JpD0G2VjI94vha+E=", - "dev": true, - "requires": { - "ansi-gray": "0.1.1", - "color-support": "1.1.3", - "time-stamp": "1.1.0" - } - }, - "lodash.template": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz", - "integrity": "sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A=", - "dev": true, - "requires": { - "lodash._reinterpolate": "3.0.0", - "lodash.templatesettings": "4.1.0" - } - }, - "lodash.templatesettings": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz", - "integrity": "sha1-K01OlbpEDZFf8IvImeRVNmZxMxY=", - "dev": true, - "requires": { - "lodash._reinterpolate": "3.0.0" - } - } - } - }, - "gulp-rename": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/gulp-rename/-/gulp-rename-1.2.2.tgz", - "integrity": "sha1-OtRCh2PwXidk3sHGfYaNsnVoeBc=", - "dev": true - }, - "gulp-ruby-sass": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/gulp-ruby-sass/-/gulp-ruby-sass-2.1.1.tgz", - "integrity": "sha1-6A9lCSEI7kr8tJNgiNxyUzaa3Kw=", - "dev": true, - "requires": { - "convert-source-map": "1.5.0", - "cross-spawn": "5.1.0", - "dargs": "2.1.0", - "each-async": "1.1.1", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "glob2base": "0.0.12", - "gulp-util": "3.0.8", - "md5-hex": "1.3.0", - "object-assign": "4.1.1", - "os-tmpdir": "1.0.2", - "path-exists": "2.1.0", - "rimraf": "2.6.2" - } - }, - "gulp-sourcemaps": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-1.12.0.tgz", - "integrity": "sha1-eG+XyUoPloSSRl1wVY4EJCxnlZg=", - "dev": true, - "requires": { - "@gulp-sourcemaps/map-sources": "1.0.0", - "acorn": "4.0.13", - "convert-source-map": "1.5.0", - "css": "2.2.1", - "debug-fabulous": "0.0.4", - "detect-newline": "2.1.0", - "graceful-fs": "4.1.11", - "source-map": "0.5.7", - "strip-bom": "2.0.0", - "through2": "2.0.3", - "vinyl": "1.2.0" - }, - "dependencies": { - "acorn": { - "version": "4.0.13", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", - "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", - "dev": true - }, - "vinyl": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", - "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", - "dev": true, - "requires": { - "clone": "1.0.2", - "clone-stats": "0.0.1", - "replace-ext": "0.0.1" - } - } - } - }, - "gulp-uglify": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/gulp-uglify/-/gulp-uglify-1.5.4.tgz", - "integrity": "sha1-UkeI2HZm0J+dDCH7IXf5ADmmWMk=", - "dev": true, - "requires": { - "deap": "1.0.0", - "fancy-log": "1.3.0", - "gulp-util": "3.0.8", - "isobject": "2.1.0", - "through2": "2.0.3", - "uglify-js": "2.6.4", - "uglify-save-license": "0.4.1", - "vinyl-sourcemaps-apply": "0.2.1" - }, - "dependencies": { - "uglify-js": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.6.4.tgz", - "integrity": "sha1-ZeovswWck5RpLxX+2HwrNsFrmt8=", - "dev": true, - "requires": { - "async": "0.2.10", - "source-map": "0.5.7", - "uglify-to-browserify": "1.0.2", - "yargs": "3.10.0" - } - } - } - }, - "gulp-util": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.8.tgz", - "integrity": "sha1-AFTh50RQLifATBh8PsxQXdVLu08=", - "dev": true, - "requires": { - "array-differ": "1.0.0", - "array-uniq": "1.0.3", - "beeper": "1.1.1", - "chalk": "1.1.3", - "dateformat": "2.2.0", - "fancy-log": "1.3.0", - "gulplog": "1.0.0", - "has-gulplog": "0.1.0", - "lodash._reescape": "3.0.0", - "lodash._reevaluate": "3.0.0", - "lodash._reinterpolate": "3.0.0", - "lodash.template": "3.6.2", - "minimist": "1.2.0", - "multipipe": "0.1.2", - "object-assign": "3.0.0", - "replace-ext": "0.0.1", - "through2": "2.0.3", - "vinyl": "0.5.3" - }, - "dependencies": { - "object-assign": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", - "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=", - "dev": true - } - } - }, - "gulplog": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", - "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", - "dev": true, - "requires": { - "glogg": "1.0.0" - } - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true - }, - "har-validator": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", - "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", - "dev": true, - "requires": { - "ajv": "5.2.3", - "har-schema": "2.0.0" - } - }, - "has": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", - "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", - "dev": true, - "requires": { - "function-bind": "1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "2.1.1" - } - }, - "has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", - "dev": true - }, - "has-gulplog": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz", - "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=", - "dev": true, - "requires": { - "sparkles": "1.0.0" - } - }, - "hash": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/hash/-/hash-0.2.0.tgz", - "integrity": "sha1-l4ZU+nI7ElLuqETlYMOTHa0nKJs=", - "dev": true - }, - "hasha": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-2.2.0.tgz", - "integrity": "sha1-eNfL/B5tZjA/55g3NlmEUXsvbuE=", - "dev": true, - "requires": { - "is-stream": "1.1.0", - "pinkie-promise": "2.0.1" - } - }, - "hawk": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", - "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", - "dev": true, - "requires": { - "boom": "4.3.1", - "cryptiles": "3.1.2", - "hoek": "4.2.0", - "sntp": "2.0.2" - } - }, - "hoek": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz", - "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==", - "dev": true - }, - "homedir-polyfill": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz", - "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=", - "dev": true, - "requires": { - "parse-passwd": "1.0.0" - } - }, - "hosted-git-info": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", - "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==", - "dev": true - }, - "href-content": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/href-content/-/href-content-1.0.2.tgz", - "integrity": "sha1-jUYiij1VziQwPd+5M0DQ77fd21g=", - "dev": true, - "requires": { - "remote-content": "1.0.1" - } - }, - "html-comment-regex": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.1.tgz", - "integrity": "sha1-ZouTd26q5V696POtRkswekljYl4=", - "dev": true - }, - "htmlparser2": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", - "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=", - "dev": true, - "requires": { - "domelementtype": "1.3.0", - "domhandler": "2.3.0", - "domutils": "1.5.1", - "entities": "1.0.0", - "readable-stream": "1.1.14" - }, - "dependencies": { - "entities": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", - "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=", - "dev": true - } - } - }, - "http-errors": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", - "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", - "dev": true, - "requires": { - "depd": "1.1.1", - "inherits": "2.0.3", - "setprototypeof": "1.0.3", - "statuses": "1.3.1" - } - }, - "http-parser-js": { - "version": "0.4.8", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.8.tgz", - "integrity": "sha512-jmHp99g6/fLx0pRNJqzsQgjsclCHAY7NhIeA3/U+bsGNvgbvUCQFQY9m5AYpqpAxY/2VcikfbKpjQozSTiz0jA==", - "dev": true - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "jsprim": "1.4.1", - "sshpk": "1.13.1" - } - }, - "http2": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/http2/-/http2-3.3.7.tgz", - "integrity": "sha512-puSi8M8WNlFJm9Pk4c/Mbz9Gwparuj3gO9/RRO5zv6piQ0FY+9Qywp0PdWshYgsMJSalixFY7eC6oPu0zRxLAQ==", - "dev": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.11", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.11.tgz", - "integrity": "sha1-LstC/SlHRJIiCaLnxATayHk9it4=", - "dev": true - }, - "imageinliner": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/imageinliner/-/imageinliner-0.2.4.tgz", - "integrity": "sha1-EQ8LstQKEZaPyz202Fohr949v00=", - "dev": true, - "requires": { - "css-parse": "1.7.0", - "css-stringify": "1.4.1", - "mime": "1.2.11", - "mkdirp": "0.3.5", - "optimist": "0.6.1" - }, - "dependencies": { - "mkdirp": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz", - "integrity": "sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc=", - "dev": true - } - } - }, - "imagemin": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/imagemin/-/imagemin-4.0.0.tgz", - "integrity": "sha1-6Q5/CTaDZZXxj6Ff6Qb0+iWeqEc=", - "dev": true, - "requires": { - "buffer-to-vinyl": "1.1.0", - "concat-stream": "1.6.0", - "imagemin-gifsicle": "4.2.0", - "imagemin-jpegtran": "4.3.2", - "imagemin-optipng": "4.3.0", - "imagemin-svgo": "4.2.1", - "optional": "0.1.4", - "readable-stream": "2.3.3", - "stream-combiner2": "1.1.1", - "vinyl-fs": "2.4.4" - }, - "dependencies": { - "glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", - "dev": true, - "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "3.1.0", - "path-dirname": "1.0.2" - } - }, - "glob-stream": { - "version": "5.3.5", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-5.3.5.tgz", - "integrity": "sha1-pVZlqajM3EGRWofHAeMtTgFvrSI=", - "dev": true, - "requires": { - "extend": "3.0.1", - "glob": "5.0.15", - "glob-parent": "3.1.0", - "micromatch": "2.3.11", - "ordered-read-streams": "0.3.0", - "through2": "0.6.5", - "to-absolute-glob": "0.1.1", - "unique-stream": "2.2.1" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" - } - } - } - }, - "gulp-sourcemaps": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-1.6.0.tgz", - "integrity": "sha1-uG/zSdgBzrVuHZ59x7vLS33uYAw=", - "dev": true, - "requires": { - "convert-source-map": "1.5.0", - "graceful-fs": "4.1.11", - "strip-bom": "2.0.0", - "through2": "2.0.3", - "vinyl": "1.2.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "2.1.1" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "ordered-read-streams": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.3.0.tgz", - "integrity": "sha1-cTfmmzKYuzQiR6G77jiByA4v14s=", - "dev": true, - "requires": { - "is-stream": "1.1.0", - "readable-stream": "2.3.3" - } - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - }, - "unique-stream": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.2.1.tgz", - "integrity": "sha1-WqADz76Uxf+GbE59ZouxxNuts2k=", - "dev": true, - "requires": { - "json-stable-stringify": "1.0.1", - "through2-filter": "2.0.0" - } - }, - "vinyl": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", - "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", - "dev": true, - "requires": { - "clone": "1.0.2", - "clone-stats": "0.0.1", - "replace-ext": "0.0.1" - } - }, - "vinyl-fs": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-2.4.4.tgz", - "integrity": "sha1-vm/zJwy1Xf19MGNkDegfJddTIjk=", - "dev": true, - "requires": { - "duplexify": "3.5.1", - "glob-stream": "5.3.5", - "graceful-fs": "4.1.11", - "gulp-sourcemaps": "1.6.0", - "is-valid-glob": "0.3.0", - "lazystream": "1.0.0", - "lodash.isequal": "4.5.0", - "merge-stream": "1.0.1", - "mkdirp": "0.5.1", - "object-assign": "4.1.1", - "readable-stream": "2.3.3", - "strip-bom": "2.0.0", - "strip-bom-stream": "1.0.0", - "through2": "2.0.3", - "through2-filter": "2.0.0", - "vali-date": "1.0.0", - "vinyl": "1.2.0" - } - } - } - }, - "imagemin-gifsicle": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/imagemin-gifsicle/-/imagemin-gifsicle-4.2.0.tgz", - "integrity": "sha1-D++butNHbmt2iFc2zFsLh6CHV8o=", - "dev": true, - "optional": true, - "requires": { - "gifsicle": "3.0.4", - "is-gif": "1.0.0", - "through2": "0.6.5" - }, - "dependencies": { - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "optional": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true, - "optional": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" - } - } - } - }, - "imagemin-jpegtran": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/imagemin-jpegtran/-/imagemin-jpegtran-4.3.2.tgz", - "integrity": "sha1-G8bR4r0T/bZNJFUm1jWn5d/rEvw=", - "dev": true, - "optional": true, - "requires": { - "is-jpg": "1.0.0", - "jpegtran-bin": "3.2.0", - "through2": "2.0.3" - } - }, - "imagemin-optipng": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/imagemin-optipng/-/imagemin-optipng-4.3.0.tgz", - "integrity": "sha1-dgRmOrLuMVczJ0cm/Rw3TStErbY=", - "dev": true, - "optional": true, - "requires": { - "exec-buffer": "2.0.1", - "is-png": "1.1.0", - "optipng-bin": "3.1.4", - "through2": "0.6.5" - }, - "dependencies": { - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "optional": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true, - "optional": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" - } - } - } - }, - "imagemin-svgo": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/imagemin-svgo/-/imagemin-svgo-4.2.1.tgz", - "integrity": "sha1-VPB9xW9HJgRi32phxUvvtEtXvlU=", - "dev": true, - "optional": true, - "requires": { - "is-svg": "1.1.1", - "svgo": "0.6.6", - "through2": "2.0.3" - }, - "dependencies": { - "is-svg": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-1.1.1.tgz", - "integrity": "sha1-rA76r7ZTrFhHNwix+HNjbKEQ4xs=", - "dev": true, - "optional": true - } - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "indent-string": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", - "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", - "dev": true, - "requires": { - "repeating": "2.0.1" - } - }, - "indexes-of": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", - "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "ini": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz", - "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=", - "dev": true - }, - "inline-critical": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/inline-critical/-/inline-critical-1.0.0.tgz", - "integrity": "sha1-TeA+3pI48VMWe/8SByTC+ADwjfo=", - "dev": true, - "requires": { - "cave": "2.0.0", - "cheerio": "0.19.0", - "clean-css": "3.4.8", - "css": "2.2.1", - "dom-serializer": "0.1.0", - "fg-loadcss": "0.2.4", - "get-stdin": "5.0.1", - "indent-string": "2.1.0", - "lodash": "3.10.1", - "meow": "3.5.0", - "normalize-newline": "1.0.2", - "reaver": "2.0.0", - "resolve": "1.1.6", - "slash": "1.0.0", - "uglify-js": "2.6.0" - }, - "dependencies": { - "camelcase": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", - "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", - "dev": true - }, - "camelcase-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-1.0.0.tgz", - "integrity": "sha1-vRoRv5sxoc5JNJOpMN4aC69K1+w=", - "dev": true, - "requires": { - "camelcase": "1.2.1", - "map-obj": "1.0.1" - } - }, - "cheerio": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.19.0.tgz", - "integrity": "sha1-dy5wFfLuKZZQltcepBdbdas1SSU=", - "dev": true, - "requires": { - "css-select": "1.0.0", - "dom-serializer": "0.1.0", - "entities": "1.1.1", - "htmlparser2": "3.8.3", - "lodash": "3.10.1" - } - }, - "clean-css": { - "version": "3.4.8", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-3.4.8.tgz", - "integrity": "sha1-X8A3oUpoIbuU/BI18DybNyZvmpU=", - "dev": true, - "requires": { - "commander": "2.8.1", - "source-map": "0.4.4" - } - }, - "css-select": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.0.0.tgz", - "integrity": "sha1-sRIcpRhI3SZOIkTQWM7iVN7rRLA=", - "dev": true, - "requires": { - "boolbase": "1.0.0", - "css-what": "1.0.0", - "domutils": "1.4.3", - "nth-check": "1.0.1" - } - }, - "css-what": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-1.0.0.tgz", - "integrity": "sha1-18wt9FGAZm+Z0rFEYmOUaeAPc2w=", - "dev": true - }, - "domutils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.4.3.tgz", - "integrity": "sha1-CGVRN5bGswYDGFDhdVFrr4C3Km8=", - "dev": true, - "requires": { - "domelementtype": "1.3.0" - } - }, - "lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", - "dev": true - }, - "meow": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-3.5.0.tgz", - "integrity": "sha1-vFpdi1uEjvaqUBWL4FcBgusNXk0=", - "dev": true, - "requires": { - "camelcase-keys": "1.0.0", - "loud-rejection": "1.6.0", - "minimist": "1.2.0", - "normalize-package-data": "2.4.0", - "object-assign": "4.1.1", - "read-pkg-up": "1.0.1", - "redent": "1.0.0", - "trim-newlines": "1.0.0" - } - }, - "source-map": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", - "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", - "dev": true, - "requires": { - "amdefine": "1.0.1" - } - } - } - }, - "inline-css": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/inline-css/-/inline-css-2.2.2.tgz", - "integrity": "sha1-2h5LFOQqFO9V+TMrWtGy32VxSaY=", - "dev": true, - "requires": { - "bluebird": "2.11.0", - "cheerio": "0.19.0", - "css-property": "2.0.0", - "css-rules": "1.0.2", - "extend": "3.0.1", - "extract-css": "1.0.3", - "flatten": "0.0.1", - "object.pick": "1.3.0", - "style-selector": "2.0.1" - }, - "dependencies": { - "bluebird": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz", - "integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE=", - "dev": true - }, - "cheerio": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.19.0.tgz", - "integrity": "sha1-dy5wFfLuKZZQltcepBdbdas1SSU=", - "dev": true, - "requires": { - "css-select": "1.0.0", - "dom-serializer": "0.1.0", - "entities": "1.1.1", - "htmlparser2": "3.8.3", - "lodash": "3.10.1" - } - }, - "css-select": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.0.0.tgz", - "integrity": "sha1-sRIcpRhI3SZOIkTQWM7iVN7rRLA=", - "dev": true, - "requires": { - "boolbase": "1.0.0", - "css-what": "1.0.0", - "domutils": "1.4.3", - "nth-check": "1.0.1" - } - }, - "css-what": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-1.0.0.tgz", - "integrity": "sha1-18wt9FGAZm+Z0rFEYmOUaeAPc2w=", - "dev": true - }, - "domutils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.4.3.tgz", - "integrity": "sha1-CGVRN5bGswYDGFDhdVFrr4C3Km8=", - "dev": true, - "requires": { - "domelementtype": "1.3.0" - } - }, - "flatten": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/flatten/-/flatten-0.0.1.tgz", - "integrity": "sha1-VURAdm2goNYDmZ9DNFP2wvxqdcE=", - "dev": true - }, - "lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", - "dev": true - } - } - }, - "interpret": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.0.4.tgz", - "integrity": "sha1-ggzdWIuGj/sZGoCVBtbJyPISsbA=", - "dev": true - }, - "ip-regex": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-1.0.3.tgz", - "integrity": "sha1-3FiQdvZZ9BnCIgOaMzFvHHOH7/0=", - "dev": true, - "optional": true - }, - "irregular-plurals": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-1.3.0.tgz", - "integrity": "sha512-njf5A+Mxb3kojuHd1DzISjjIl+XhyzovXEOyPPSzdQozq/Lf2tN27mOrAAsxEPZxpn6I4MGzs1oo9TxXxPFpaA==", - "dev": true - }, - "is": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/is/-/is-3.2.1.tgz", - "integrity": "sha1-0Kwq1V63sL7JJqUmb2xmKqqD3KU=", - "dev": true - }, - "is-absolute": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-0.2.6.tgz", - "integrity": "sha1-IN5p89uULvLYe5wto28XIjWxtes=", - "dev": true, - "requires": { - "is-relative": "0.2.1", - "is-windows": "0.2.0" - } - }, - "is-absolute-url": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", - "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=", - "dev": true - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "is-buffer": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz", - "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=", - "dev": true - }, - "is-builtin-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", - "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", - "dev": true, - "requires": { - "builtin-modules": "1.1.1" - } - }, - "is-bzip2": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-bzip2/-/is-bzip2-1.0.0.tgz", - "integrity": "sha1-XuWOqlounIDiFAe+3yOuWsCRs/w=", - "dev": true - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-finite": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", - "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", - "dev": true, - "requires": { - "number-is-nan": "1.0.1" - } - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "1.0.1" - } - }, - "is-gif": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-gif/-/is-gif-1.0.0.tgz", - "integrity": "sha1-ptKumIkwB7/6l6HYwB1jIFgyCX4=", - "dev": true, - "optional": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "1.0.0" - } - }, - "is-gzip": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-gzip/-/is-gzip-1.0.0.tgz", - "integrity": "sha1-bKiwe5nHeZgCWQDlVc7Y7YCHmoM=", - "dev": true - }, - "is-jpg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-jpg/-/is-jpg-1.0.0.tgz", - "integrity": "sha1-KVnBfnNDDbOCZNp1uQ3VTy2G2hw=", - "dev": true, - "optional": true - }, - "is-my-json-valid": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz", - "integrity": "sha512-ochPsqWS1WXj8ZnMIV0vnNXooaMhp7cyL4FMSIPKTtnV0Ha/T19G2b9kkhcNsabV9bxYkze7/aLZJb/bYuFduQ==", - "dev": true, - "requires": { - "generate-function": "2.0.0", - "generate-object-property": "1.2.0", - "jsonpointer": "4.0.1", - "xtend": "4.0.1" - } - }, - "is-natural-number": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-2.1.1.tgz", - "integrity": "sha1-fUxXKDd+84bD4ZSpkRv1fG3DNec=", - "dev": true - }, - "is-npm": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", - "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=", - "dev": true - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - } - }, - "is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", - "dev": true - }, - "is-path-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", - "dev": true - }, - "is-path-in-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", - "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", - "dev": true, - "requires": { - "is-path-inside": "1.0.0" - } - }, - "is-path-inside": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz", - "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=", - "dev": true, - "requires": { - "path-is-inside": "1.0.2" - } - }, - "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", - "dev": true - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "is-png": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-png/-/is-png-1.1.0.tgz", - "integrity": "sha1-1XSxK/J1wDUEVVcLDltXqwYgd84=", - "dev": true, - "optional": true - }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, - "is-property": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", - "dev": true - }, - "is-redirect": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", - "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=", - "dev": true - }, - "is-relative": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-0.2.1.tgz", - "integrity": "sha1-0n9MfVFtF1+2ENuEu+7yPDvJeqU=", - "dev": true, - "requires": { - "is-unc-path": "0.1.2" - } - }, - "is-retry-allowed": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", - "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=", - "dev": true - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, - "is-svg": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-2.1.0.tgz", - "integrity": "sha1-z2EJDaDZ77yrhyLeum8DIgjbsOk=", - "dev": true, - "requires": { - "html-comment-regex": "1.1.1" - } - }, - "is-tar": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-tar/-/is-tar-1.0.0.tgz", - "integrity": "sha1-L2suF5LB9bs2UZrKqdZcDSb+hT0=", - "dev": true - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "is-unc-path": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-0.1.2.tgz", - "integrity": "sha1-arBTpyVzwQJQ/0FqOBTDUXivObk=", - "dev": true, - "requires": { - "unc-path-regex": "0.1.2" - } - }, - "is-url": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.2.tgz", - "integrity": "sha1-SYkFpZO/R8wtnn9zg3K792lsfyY=", - "dev": true - }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", - "dev": true - }, - "is-valid-glob": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-0.3.0.tgz", - "integrity": "sha1-1LVcafUYhvm2XHDWwmItN+KfSP4=", - "dev": true - }, - "is-windows": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz", - "integrity": "sha1-3hqm1j6indJIc3tp8f+LgALSEIw=", - "dev": true - }, - "is-zip": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-zip/-/is-zip-1.0.0.tgz", - "integrity": "sha1-R7Co/004p2QxzP2ZqOFaTIa6IyU=", - "dev": true - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - } - } - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, - "jpegtran-bin": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jpegtran-bin/-/jpegtran-bin-3.2.0.tgz", - "integrity": "sha1-9g7PSumZwL2tLp+83ytvCYHnops=", - "dev": true, - "optional": true, - "requires": { - "bin-build": "2.2.0", - "bin-wrapper": "3.0.2", - "logalot": "2.1.0" - } - }, - "js-base64": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.3.2.tgz", - "integrity": "sha512-Y2/+DnfJJXT1/FCwUebUhLWb3QihxiSC42+ctHLGogmW2jPY6LCapMdFZXRvVP2z6qyKW7s6qncE/9gSqZiArw==", - "dev": true - }, - "js-yaml": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.6.1.tgz", - "integrity": "sha1-bl/mfYsgXOTSL60Ft3geja3MSzA=", - "dev": true, - "requires": { - "argparse": "1.0.9", - "esprima": "2.7.3" - }, - "dependencies": { - "esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", - "dev": true - } - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true, - "optional": true - }, - "jsdom": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-7.2.2.tgz", - "integrity": "sha1-QLQCdwwr2iNGkJa+6Rq2deOx/G4=", - "dev": true, - "optional": true, - "requires": { - "abab": "1.0.4", - "acorn": "2.7.0", - "acorn-globals": "1.0.9", - "cssom": "0.3.2", - "cssstyle": "0.2.37", - "escodegen": "1.9.0", - "nwmatcher": "1.4.2", - "parse5": "1.5.1", - "request": "2.82.0", - "sax": "1.2.4", - "symbol-tree": "3.2.2", - "tough-cookie": "2.3.3", - "webidl-conversions": "2.0.1", - "whatwg-url-compat": "0.6.5", - "xml-name-validator": "2.0.1" - } - }, - "jsesc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", - "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", - "dev": true - }, - "jshint": { - "version": "2.9.5", - "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.9.5.tgz", - "integrity": "sha1-HnJSkVzmgbQIJ+4UJIxG006apiw=", - "dev": true, - "requires": { - "cli": "1.0.1", - "console-browserify": "1.1.0", - "exit": "0.1.2", - "htmlparser2": "3.8.3", - "lodash": "3.7.0", - "minimatch": "3.0.4", - "shelljs": "0.3.0", - "strip-json-comments": "1.0.4" - }, - "dependencies": { - "cli": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cli/-/cli-1.0.1.tgz", - "integrity": "sha1-IoF1NPJL+klQw01TLUjsvGIbjBQ=", - "dev": true, - "requires": { - "exit": "0.1.2", - "glob": "7.1.2" - } - }, - "lodash": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.7.0.tgz", - "integrity": "sha1-Nni9irmVBXwHreg27S7wh9qBHUU=", - "dev": true - }, - "strip-json-comments": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", - "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=", - "dev": true - } - } - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true - }, - "json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", - "dev": true - }, - "json-stable-stringify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", - "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", - "dev": true, - "requires": { - "jsonify": "0.0.0" - } - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true - }, - "jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11" - } - }, - "jsonify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", - "dev": true - }, - "jsonpointer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", - "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", - "dev": true - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "kew": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz", - "integrity": "sha1-edk9LTM2PW/dKXCzNdkUGtWR15s=", - "dev": true - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.5" - } - }, - "klaw": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", - "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11" - } - }, - "latest-version": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-2.0.0.tgz", - "integrity": "sha1-VvjWE5YghHuAF/jx9NeOIRMkFos=", - "dev": true, - "requires": { - "package-json": "2.4.0" - } - }, - "lazy-cache": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", - "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", - "dev": true - }, - "lazy-debug-legacy": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/lazy-debug-legacy/-/lazy-debug-legacy-0.0.1.tgz", - "integrity": "sha1-U3cWwHduTPeePtG2IfdljCkRsbE=", - "dev": true - }, - "lazy-req": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/lazy-req/-/lazy-req-1.1.0.tgz", - "integrity": "sha1-va6+rTD42CQDnODOFJ1Nqge6H6w=", - "dev": true, - "optional": true - }, - "lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", - "dev": true, - "requires": { - "readable-stream": "2.3.3" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - } - } - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "optional": true, - "requires": { - "prelude-ls": "1.1.2", - "type-check": "0.3.2" - } - }, - "liftoff": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.3.0.tgz", - "integrity": "sha1-qY8v9nGD2Lp8+soQVIvX/wVQs4U=", - "dev": true, - "requires": { - "extend": "3.0.1", - "findup-sync": "0.4.3", - "fined": "1.1.0", - "flagged-respawn": "0.3.2", - "lodash.isplainobject": "4.0.6", - "lodash.isstring": "4.0.1", - "lodash.mapvalues": "4.6.0", - "rechoir": "0.6.2", - "resolve": "1.4.0" - }, - "dependencies": { - "resolve": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz", - "integrity": "sha512-aW7sVKPufyHqOmyyLzg/J+8606v5nevBgaliIlV7nUpVMsDnoBGV/cbSLNjZAg9q0Cfd/+easKVKQ8vOu8fn1Q==", - "dev": true, - "requires": { - "path-parse": "1.0.5" - } - } - } - }, - "list-stylesheets": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/list-stylesheets/-/list-stylesheets-1.1.0.tgz", - "integrity": "sha1-8N/w+xh6ov7KmZgEWZQUHMKdvzE=", - "dev": true, - "requires": { - "cheerio": "0.19.0", - "extend": "3.0.1", - "object.pick": "1.3.0" - }, - "dependencies": { - "cheerio": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.19.0.tgz", - "integrity": "sha1-dy5wFfLuKZZQltcepBdbdas1SSU=", - "dev": true, - "requires": { - "css-select": "1.0.0", - "dom-serializer": "0.1.0", - "entities": "1.1.1", - "htmlparser2": "3.8.3", - "lodash": "3.10.1" - } - }, - "css-select": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.0.0.tgz", - "integrity": "sha1-sRIcpRhI3SZOIkTQWM7iVN7rRLA=", - "dev": true, - "requires": { - "boolbase": "1.0.0", - "css-what": "1.0.0", - "domutils": "1.4.3", - "nth-check": "1.0.1" - } - }, - "css-what": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-1.0.0.tgz", - "integrity": "sha1-18wt9FGAZm+Z0rFEYmOUaeAPc2w=", - "dev": true - }, - "domutils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.4.3.tgz", - "integrity": "sha1-CGVRN5bGswYDGFDhdVFrr4C3Km8=", - "dev": true, - "requires": { - "domelementtype": "1.3.0" - } - }, - "lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", - "dev": true - } - } - }, - "livereload-js": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-2.2.2.tgz", - "integrity": "sha1-bIclfmSKtHW8JOoldFftzB+NC8I=", - "dev": true - }, - "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "parse-json": "2.2.0", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "strip-bom": "2.0.0" - } - }, - "lodash": { - "version": "4.17.4", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", - "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", - "dev": true - }, - "lodash._baseassign": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz", - "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=", - "dev": true, - "requires": { - "lodash._basecopy": "3.0.1", - "lodash.keys": "3.1.2" - } - }, - "lodash._basecopy": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", - "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", - "dev": true - }, - "lodash._basetostring": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz", - "integrity": "sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U=", - "dev": true - }, - "lodash._basevalues": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz", - "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=", - "dev": true - }, - "lodash._bindcallback": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz", - "integrity": "sha1-5THCdkTPi1epnhftlbNcdIeJOS4=", - "dev": true - }, - "lodash._createassigner": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/lodash._createassigner/-/lodash._createassigner-3.1.1.tgz", - "integrity": "sha1-g4pbri/aymOsIt7o4Z+k5taXCxE=", - "dev": true, - "requires": { - "lodash._bindcallback": "3.0.1", - "lodash._isiterateecall": "3.0.9", - "lodash.restparam": "3.6.1" - } - }, - "lodash._getnative": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", - "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", - "dev": true - }, - "lodash._isiterateecall": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", - "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", - "dev": true - }, - "lodash._reescape": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz", - "integrity": "sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo=", - "dev": true - }, - "lodash._reevaluate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz", - "integrity": "sha1-WLx0xAZklTrgsSTYBpltrKQx4u0=", - "dev": true - }, - "lodash._reinterpolate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", - "dev": true - }, - "lodash._root": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz", - "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=", - "dev": true - }, - "lodash.assign": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", - "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=", - "dev": true - }, - "lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", - "dev": true - }, - "lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", - "dev": true - }, - "lodash.escape": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz", - "integrity": "sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg=", - "dev": true, - "requires": { - "lodash._root": "3.0.1" - } - }, - "lodash.escaperegexp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", - "integrity": "sha1-ZHYsSGGAglGKw99Mz11YhtriA0c=", - "dev": true - }, - "lodash.isarguments": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", - "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", - "dev": true - }, - "lodash.isarray": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", - "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", - "dev": true - }, - "lodash.isequal": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", - "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=", - "dev": true - }, - "lodash.isobject": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-3.0.2.tgz", - "integrity": "sha1-PI+41bW/S/kK4G4U8qUwpO2TXh0=", - "dev": true - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", - "dev": true - }, - "lodash.isstring": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=", - "dev": true - }, - "lodash.keys": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", - "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", - "dev": true, - "requires": { - "lodash._getnative": "3.9.1", - "lodash.isarguments": "3.1.0", - "lodash.isarray": "3.0.4" - } - }, - "lodash.last": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash.last/-/lodash.last-3.0.0.tgz", - "integrity": "sha1-JC9mMRLdTG5jcoxgo8kJ0b2tvUw=", - "dev": true - }, - "lodash.map": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", - "integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=", - "dev": true - }, - "lodash.mapvalues": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz", - "integrity": "sha1-G6+lAF3p3W9PJmaMMMo3IwzJaJw=", - "dev": true - }, - "lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", - "dev": true - }, - "lodash.merge": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.0.tgz", - "integrity": "sha1-aYhLoUSsM/5plzemCG3v+t0PicU=", - "dev": true - }, - "lodash.partialright": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/lodash.partialright/-/lodash.partialright-4.2.1.tgz", - "integrity": "sha1-ATDYDoM2MmTUAHTzKbij56ihzEs=", - "dev": true - }, - "lodash.reduce": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz", - "integrity": "sha1-8atrg5KZrUj3hKu/R2WW8DuRTTs=", - "dev": true - }, - "lodash.reject": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.reject/-/lodash.reject-4.6.0.tgz", - "integrity": "sha1-gNZJLcFHCGS79YNTO2UfQqn1JBU=", - "dev": true - }, - "lodash.restparam": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", - "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=", - "dev": true - }, - "lodash.result": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/lodash.result/-/lodash.result-4.5.2.tgz", - "integrity": "sha1-y0Wyf7kU6qjY7m8M57KHC4fLcKo=", - "dev": true - }, - "lodash.template": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz", - "integrity": "sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8=", - "dev": true, - "requires": { - "lodash._basecopy": "3.0.1", - "lodash._basetostring": "3.0.1", - "lodash._basevalues": "3.0.0", - "lodash._isiterateecall": "3.0.9", - "lodash._reinterpolate": "3.0.0", - "lodash.escape": "3.2.0", - "lodash.keys": "3.1.2", - "lodash.restparam": "3.6.1", - "lodash.templatesettings": "3.1.1" - } - }, - "lodash.templatesettings": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz", - "integrity": "sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU=", - "dev": true, - "requires": { - "lodash._reinterpolate": "3.0.0", - "lodash.escape": "3.2.0" - } - }, - "lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", - "dev": true - }, - "logalot": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/logalot/-/logalot-2.1.0.tgz", - "integrity": "sha1-X46MkNME7fElMJUaVVSruMXj9VI=", - "dev": true, - "optional": true, - "requires": { - "figures": "1.7.0", - "squeak": "1.3.0" - } - }, - "longest": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", - "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", - "dev": true - }, - "loud-rejection": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", - "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", - "dev": true, - "requires": { - "currently-unhandled": "0.4.1", - "signal-exit": "3.0.2" - } - }, - "lowercase-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", - "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=", - "dev": true - }, - "lpad-align": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/lpad-align/-/lpad-align-1.1.2.tgz", - "integrity": "sha1-IfYArBwwlcPG5JfuZyce4ISB/p4=", - "dev": true, - "optional": true, - "requires": { - "get-stdin": "4.0.1", - "indent-string": "2.1.0", - "longest": "1.0.1", - "meow": "3.7.0" - }, - "dependencies": { - "get-stdin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", - "dev": true, - "optional": true - } - } - }, - "lru-cache": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", - "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=", - "dev": true - }, - "macaddress": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/macaddress/-/macaddress-0.2.8.tgz", - "integrity": "sha1-WQTcU3w57G2+/q6QIycTX6hRHxI=", - "dev": true - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", - "dev": true - }, - "map-stream": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", - "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=", - "dev": true - }, - "math-expression-evaluator": { - "version": "1.2.17", - "resolved": "https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz", - "integrity": "sha1-3oGf282E3M2PrlnGrreWFbnSZqw=", - "dev": true - }, - "md5-hex": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-1.3.0.tgz", - "integrity": "sha1-0sSv6YPENwZiF5uMrRRSGRNQRsQ=", - "dev": true, - "requires": { - "md5-o-matic": "0.1.1" - } - }, - "md5-o-matic": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/md5-o-matic/-/md5-o-matic-0.1.1.tgz", - "integrity": "sha1-givM1l4RfFFPqxdrJZRdVBAKA8M=", - "dev": true - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", - "dev": true - }, - "mediaquery-text": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/mediaquery-text/-/mediaquery-text-1.0.2.tgz", - "integrity": "sha1-PkWYzDp9t+lvUKuccC8fbPYxgNI=", - "dev": true, - "requires": { - "cssom": "0.3.2" - } - }, - "meow": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", - "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", - "dev": true, - "requires": { - "camelcase-keys": "2.1.0", - "decamelize": "1.2.0", - "loud-rejection": "1.6.0", - "map-obj": "1.0.1", - "minimist": "1.2.0", - "normalize-package-data": "2.4.0", - "object-assign": "4.1.1", - "read-pkg-up": "1.0.1", - "redent": "1.0.0", - "trim-newlines": "1.0.0" - } - }, - "merge-stream": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", - "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=", - "dev": true, - "requires": { - "readable-stream": "2.3.3" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - } - } - }, - "method-override": { - "version": "2.3.9", - "resolved": "https://registry.npmjs.org/method-override/-/method-override-2.3.9.tgz", - "integrity": "sha1-vRUfLONM8Bp2ykAKuVwBKxAtj3E=", - "dev": true, - "requires": { - "debug": "2.6.8", - "methods": "1.1.2", - "parseurl": "1.3.2", - "vary": "1.1.2" - }, - "dependencies": { - "debug": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "dev": true - } - } - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", - "dev": true - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "2.0.0", - "array-unique": "0.2.1", - "braces": "1.8.5", - "expand-brackets": "0.1.5", - "extglob": "0.3.2", - "filename-regex": "2.0.1", - "is-extglob": "1.0.0", - "is-glob": "2.0.1", - "kind-of": "3.2.2", - "normalize-path": "2.1.1", - "object.omit": "2.0.1", - "parse-glob": "3.0.4", - "regex-cache": "0.4.4" - } - }, - "mime": { - "version": "1.2.11", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz", - "integrity": "sha1-WCA+7Ybjpe8XrtK32evUfwpg3RA=", - "dev": true - }, - "mime-db": { - "version": "1.30.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz", - "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=", - "dev": true - }, - "mime-types": { - "version": "2.1.17", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz", - "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=", - "dev": true, - "requires": { - "mime-db": "1.30.0" - } - }, - "mini-lr": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/mini-lr/-/mini-lr-0.1.9.tgz", - "integrity": "sha1-AhmdJzR5U9H9HW297UJh8Yey0PY=", - "dev": true, - "requires": { - "body-parser": "1.14.2", - "debug": "2.6.9", - "faye-websocket": "0.7.3", - "livereload-js": "2.2.2", - "parseurl": "1.3.2", - "qs": "2.2.5" - }, - "dependencies": { - "body-parser": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.14.2.tgz", - "integrity": "sha1-EBXLH+LEQ4WCWVgdtTMy+NDPUPk=", - "dev": true, - "requires": { - "bytes": "2.2.0", - "content-type": "1.0.4", - "debug": "2.2.0", - "depd": "1.1.1", - "http-errors": "1.3.1", - "iconv-lite": "0.4.13", - "on-finished": "2.3.0", - "qs": "5.2.0", - "raw-body": "2.1.7", - "type-is": "1.6.15" - }, - "dependencies": { - "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", - "dev": true, - "requires": { - "ms": "0.7.1" - } - }, - "qs": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-5.2.0.tgz", - "integrity": "sha1-qfMRQq9GjLcrJbMBNrokVoNJFr4=", - "dev": true - } - } - }, - "bytes": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.2.0.tgz", - "integrity": "sha1-/TVGSkA/b5EXwt42Cez/nK4ABYg=", - "dev": true - }, - "faye-websocket": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.7.3.tgz", - "integrity": "sha1-zEB0x/Sk39A69U3WXDVLE1EyzhE=", - "dev": true, - "requires": { - "websocket-driver": "0.7.0" - } - }, - "http-errors": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.3.1.tgz", - "integrity": "sha1-GX4izevUGYWF6GlO9nhhl7ke2UI=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "statuses": "1.3.1" - } - }, - "iconv-lite": { - "version": "0.4.13", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz", - "integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI=", - "dev": true - }, - "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", - "dev": true - }, - "qs": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/qs/-/qs-2.2.5.tgz", - "integrity": "sha1-EIirr53MCuWuRbcJ5sa1iIsjkjw=", - "dev": true - } - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "1.1.8" - } - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } - } - }, - "morgan": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.6.1.tgz", - "integrity": "sha1-X9gYOYxoGcuiinzWZk8pL+HAu/I=", - "dev": true, - "requires": { - "basic-auth": "1.0.4", - "debug": "2.2.0", - "depd": "1.0.1", - "on-finished": "2.3.0", - "on-headers": "1.0.1" - }, - "dependencies": { - "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", - "dev": true, - "requires": { - "ms": "0.7.1" - } - }, - "depd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.0.1.tgz", - "integrity": "sha1-gK7GTJ1tl+ZcwqnKqTwKpqv3Oqo=", - "dev": true - }, - "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", - "dev": true - } - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "multiparty": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/multiparty/-/multiparty-3.3.2.tgz", - "integrity": "sha1-Nd5oBNwZZD5SSfPT473GyM4wHT8=", - "dev": true, - "requires": { - "readable-stream": "1.1.14", - "stream-counter": "0.2.0" - } - }, - "multipipe": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz", - "integrity": "sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s=", - "dev": true, - "requires": { - "duplexer2": "0.0.2" - }, - "dependencies": { - "duplexer2": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", - "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", - "dev": true, - "requires": { - "readable-stream": "1.1.14" - } - } - } - }, - "natives": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/natives/-/natives-1.1.0.tgz", - "integrity": "sha1-6f+EFBimsux6SV6TmYT3jxY+bjE=", - "dev": true - }, - "negotiator": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.5.3.tgz", - "integrity": "sha1-Jp1cR2gQ7JLtvntsLygxY4T5p+g=", - "dev": true - }, - "node-notifier": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.2.1.tgz", - "integrity": "sha512-MIBs+AAd6dJ2SklbbE8RUDRlIVhU8MaNLh1A9SUZDUHPiZkWLFde6UNwG41yQHZEToHgJMXqyVZ9UcS/ReOVTg==", - "dev": true, - "requires": { - "growly": "1.3.0", - "semver": "5.4.1", - "shellwords": "0.1.1", - "which": "1.3.0" - }, - "dependencies": { - "which": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", - "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", - "dev": true, - "requires": { - "isexe": "2.0.0" - } - } - } - }, - "node-status-codes": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-status-codes/-/node-status-codes-1.0.0.tgz", - "integrity": "sha1-WuVUHQJGRdMqWPzdyc7s6nrjrC8=", - "dev": true - }, - "node.extend": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/node.extend/-/node.extend-2.0.0.tgz", - "integrity": "sha1-dSWih1Z36lNHhKXhCseJVhOWFN8=", - "dev": true, - "requires": { - "is": "3.2.1" - } - }, - "normalize-newline": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/normalize-newline/-/normalize-newline-1.0.2.tgz", - "integrity": "sha1-mnp8lnYpN3pKasO0mE9ZDMpiFaM=", - "dev": true, - "requires": { - "get-stdin": "4.0.1", - "minimist": "1.2.0" - }, - "dependencies": { - "get-stdin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", - "dev": true - } - } - }, - "normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", - "dev": true, - "requires": { - "hosted-git-info": "2.5.0", - "is-builtin-module": "1.0.0", - "semver": "5.4.1", - "validate-npm-package-license": "3.0.1" - } - }, - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "1.1.0" - } - }, - "normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", - "dev": true - }, - "normalize-url": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", - "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", - "dev": true, - "requires": { - "object-assign": "4.1.1", - "prepend-http": "1.0.4", - "query-string": "4.3.4", - "sort-keys": "1.1.2" - } - }, - "nth-check": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz", - "integrity": "sha1-mSms32KPwsQQmN6rgqxYDPFJquQ=", - "dev": true, - "requires": { - "boolbase": "1.0.0" - } - }, - "num2fraction": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", - "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=", - "dev": true - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, - "nwmatcher": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.2.tgz", - "integrity": "sha512-QMkCGQFYp5p+zwU3INntLmz1HMfSx9dMVJMYKmE1yuSf/22Wjo6VPFa405mCLUuQn9lbQvH2DZN9lt10ZNvtAg==", - "dev": true, - "optional": true - }, - "oauth-sign": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", - "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", - "dev": true - }, - "object": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/object/-/object-0.1.1.tgz", - "integrity": "sha1-HgLO3orh81iqqHKtdUv2QNd6IsI=", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-hash": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-1.1.8.tgz", - "integrity": "sha1-KKZZz5h9lqTavnhgKJ87UybEoDw=", - "dev": true - }, - "object.defaults": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", - "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", - "dev": true, - "requires": { - "array-each": "1.0.1", - "array-slice": "1.0.0", - "for-own": "1.0.0", - "isobject": "3.0.1" - }, - "dependencies": { - "for-own": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", - "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", - "dev": true, - "requires": { - "for-in": "1.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "0.1.5", - "is-extendable": "0.1.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dev": true, - "requires": { - "ee-first": "1.1.1" - } - }, - "on-headers": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz", - "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1.0.2" - } - }, - "onetime": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", - "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", - "dev": true - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "dev": true, - "requires": { - "minimist": "0.0.10", - "wordwrap": "0.0.3" - }, - "dependencies": { - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", - "dev": true - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", - "dev": true - } - } - }, - "optional": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/optional/-/optional-0.1.4.tgz", - "integrity": "sha512-gtvrrCfkE08wKcgXaVwQVgwEQ8vel2dc5DDBn9RLQZ3YtmtkBss6A2HY6BnJH4N/4Ku97Ri/SF8sNWE2225WJw==", - "dev": true - }, - "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "dev": true, - "optional": true, - "requires": { - "deep-is": "0.1.3", - "fast-levenshtein": "2.0.6", - "levn": "0.3.0", - "prelude-ls": "1.1.2", - "type-check": "0.3.2", - "wordwrap": "1.0.0" - } - }, - "optipng-bin": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/optipng-bin/-/optipng-bin-3.1.4.tgz", - "integrity": "sha1-ldNPLEiHBPb9cGBr/qDGWfHZXYQ=", - "dev": true, - "optional": true, - "requires": { - "bin-build": "2.2.0", - "bin-wrapper": "3.0.2", - "logalot": "2.1.0" - } - }, - "orchestrator": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/orchestrator/-/orchestrator-0.3.8.tgz", - "integrity": "sha1-FOfp4nZPcxX7rBhOUGx6pt+UrX4=", - "dev": true, - "requires": { - "end-of-stream": "0.1.5", - "sequencify": "0.0.7", - "stream-consume": "0.1.0" - } - }, - "ordered-read-streams": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.1.0.tgz", - "integrity": "sha1-/VZamvjrRHO6abbtijQ1LLVS8SY=", - "dev": true - }, - "os-filter-obj": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/os-filter-obj/-/os-filter-obj-1.0.3.tgz", - "integrity": "sha1-WRUzDZDs7VV9LZOKMcbdIU2cY60=", - "dev": true, - "optional": true - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, - "osenv": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.4.tgz", - "integrity": "sha1-Qv5tWVPfBsgGS+bxdsPQWqqjRkQ=", - "dev": true, - "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" - } - }, - "oust": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/oust/-/oust-0.2.4.tgz", - "integrity": "sha1-33nsGZ4Ln9+M8AU3QuQ4t8yIqfw=", - "dev": true, - "requires": { - "cheerio": "0.19.0", - "minimist": "1.2.0" - }, - "dependencies": { - "cheerio": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.19.0.tgz", - "integrity": "sha1-dy5wFfLuKZZQltcepBdbdas1SSU=", - "dev": true, - "requires": { - "css-select": "1.0.0", - "dom-serializer": "0.1.0", - "entities": "1.1.1", - "htmlparser2": "3.8.3", - "lodash": "3.10.1" - } - }, - "css-select": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.0.0.tgz", - "integrity": "sha1-sRIcpRhI3SZOIkTQWM7iVN7rRLA=", - "dev": true, - "requires": { - "boolbase": "1.0.0", - "css-what": "1.0.0", - "domutils": "1.4.3", - "nth-check": "1.0.1" - } - }, - "css-what": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-1.0.0.tgz", - "integrity": "sha1-18wt9FGAZm+Z0rFEYmOUaeAPc2w=", - "dev": true - }, - "domutils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.4.3.tgz", - "integrity": "sha1-CGVRN5bGswYDGFDhdVFrr4C3Km8=", - "dev": true, - "requires": { - "domelementtype": "1.3.0" - } - }, - "lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", - "dev": true - } - } - }, - "package-json": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-2.4.0.tgz", - "integrity": "sha1-DRW9Z9HLvduyyiIv8u24a8sxqLs=", - "dev": true, - "requires": { - "got": "5.7.1", - "registry-auth-token": "3.3.1", - "registry-url": "3.1.0", - "semver": "5.4.1" - } - }, - "parse-filepath": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.1.tgz", - "integrity": "sha1-FZ1hVdQ5BNFsEO9piRHaHpGWm3M=", - "dev": true, - "requires": { - "is-absolute": "0.2.6", - "map-cache": "0.2.2", - "path-root": "0.1.1" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "0.3.0", - "is-dotfile": "1.0.3", - "is-extglob": "1.0.0", - "is-glob": "2.0.1" - } - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "1.3.1" - } - }, - "parse-passwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", - "dev": true - }, - "parse5": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-1.5.1.tgz", - "integrity": "sha1-m387DeMr543CQBsXVzzK8Pb1nZQ=", - "dev": true, - "optional": true - }, - "parseurl": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", - "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "2.0.1" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-parse": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", - "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", - "dev": true - }, - "path-root": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", - "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", - "dev": true, - "requires": { - "path-root-regex": "0.1.2" - } - }, - "path-root-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", - "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", - "dev": true - }, - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" - } - }, - "pause": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/pause/-/pause-0.1.0.tgz", - "integrity": "sha1-68ikqGGf8LioGsFRPDQ0/0af23Q=", - "dev": true - }, - "pause-stream": { - "version": "0.0.11", - "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", - "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", - "dev": true, - "requires": { - "through": "2.3.8" - } - }, - "pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", - "dev": true - }, - "penthouse": { - "version": "0.9.16", - "resolved": "https://registry.npmjs.org/penthouse/-/penthouse-0.9.16.tgz", - "integrity": "sha1-6dt6p7YvedniEy/kxDe9klKe3xA=", - "dev": true, - "requires": { - "apartment": "1.1.1", - "css": "git://github.com/pocketjoso/css.git#8ddea7e3cbc0a183ecf694a7a5fbc84326893893", - "css-mediaquery": "0.1.2", - "jsesc": "1.3.0", - "os-tmpdir": "1.0.2", - "phantomjs-prebuilt": "2.1.15", - "tmp": "0.0.28" - }, - "dependencies": { - "css": { - "version": "git://github.com/pocketjoso/css.git#8ddea7e3cbc0a183ecf694a7a5fbc84326893893", - "dev": true, - "requires": { - "inherits": "2.0.3", - "source-map": "0.1.43", - "source-map-resolve": "0.3.1", - "urix": "0.1.0" - } - }, - "source-map": { - "version": "0.1.43", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", - "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", - "dev": true, - "requires": { - "amdefine": "1.0.1" - } - } - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true - }, - "phantomjs-prebuilt": { - "version": "2.1.15", - "resolved": "https://registry.npmjs.org/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.15.tgz", - "integrity": "sha1-IPhugtM0nFBZF1J3RbekEeCLOQM=", - "dev": true, - "requires": { - "es6-promise": "4.0.5", - "extract-zip": "1.6.5", - "fs-extra": "1.0.0", - "hasha": "2.2.0", - "kew": "0.7.0", - "progress": "1.1.8", - "request": "2.81.0", - "request-progress": "2.0.1", - "which": "1.2.14" - }, - "dependencies": { - "ajv": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", - "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", - "dev": true, - "requires": { - "co": "4.6.0", - "json-stable-stringify": "1.0.1" - } - }, - "assert-plus": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", - "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", - "dev": true - }, - "aws-sign2": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", - "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", - "dev": true - }, - "boom": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", - "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", - "dev": true, - "requires": { - "hoek": "2.16.3" - } - }, - "cryptiles": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", - "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", - "dev": true, - "requires": { - "boom": "2.10.1" - } - }, - "form-data": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", - "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", - "dev": true, - "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.17" - } - }, - "fs-extra": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz", - "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "jsonfile": "2.4.0", - "klaw": "1.3.1" - } - }, - "har-schema": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz", - "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=", - "dev": true - }, - "har-validator": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz", - "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=", - "dev": true, - "requires": { - "ajv": "4.11.8", - "har-schema": "1.0.5" - } - }, - "hawk": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", - "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", - "dev": true, - "requires": { - "boom": "2.10.1", - "cryptiles": "2.0.5", - "hoek": "2.16.3", - "sntp": "1.0.9" - } - }, - "hoek": { - "version": "2.16.3", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", - "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", - "dev": true - }, - "http-signature": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", - "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", - "dev": true, - "requires": { - "assert-plus": "0.2.0", - "jsprim": "1.4.1", - "sshpk": "1.13.1" - } - }, - "performance-now": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", - "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=", - "dev": true - }, - "qs": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", - "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=", - "dev": true - }, - "request": { - "version": "2.81.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", - "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=", - "dev": true, - "requires": { - "aws-sign2": "0.6.0", - "aws4": "1.6.0", - "caseless": "0.12.0", - "combined-stream": "1.0.5", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "2.1.4", - "har-validator": "4.2.1", - "hawk": "3.1.3", - "http-signature": "1.1.1", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.17", - "oauth-sign": "0.8.2", - "performance-now": "0.2.0", - "qs": "6.4.0", - "safe-buffer": "5.1.1", - "stringstream": "0.0.5", - "tough-cookie": "2.3.3", - "tunnel-agent": "0.6.0", - "uuid": "3.1.0" - } - }, - "sntp": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", - "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", - "dev": true, - "requires": { - "hoek": "2.16.3" - } - } - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "2.0.4" - } - }, - "plugin-error": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-0.1.2.tgz", - "integrity": "sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4=", - "dev": true, - "requires": { - "ansi-cyan": "0.1.1", - "ansi-red": "0.1.1", - "arr-diff": "1.1.0", - "arr-union": "2.1.0", - "extend-shallow": "1.1.4" - }, - "dependencies": { - "arr-diff": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-1.1.0.tgz", - "integrity": "sha1-aHwydYFjWI/vfeezb6vklesaOZo=", - "dev": true, - "requires": { - "arr-flatten": "1.1.0", - "array-slice": "0.2.3" - } - }, - "array-slice": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz", - "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=", - "dev": true - }, - "extend-shallow": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-1.1.4.tgz", - "integrity": "sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE=", - "dev": true, - "requires": { - "kind-of": "1.1.0" - } - }, - "kind-of": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz", - "integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=", - "dev": true - } - } - }, - "plur": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/plur/-/plur-2.1.2.tgz", - "integrity": "sha1-dIJFLBoPUI4+NE6uwxLJHCncZVo=", - "dev": true, - "requires": { - "irregular-plurals": "1.3.0" - } - }, - "postcss": { - "version": "5.2.17", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.17.tgz", - "integrity": "sha1-z09Ze4ZNZcikkrLqvp1wbIecOIs=", - "dev": true, - "requires": { - "chalk": "1.1.3", - "js-base64": "2.3.2", - "source-map": "0.5.7", - "supports-color": "3.2.3" - }, - "dependencies": { - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "1.0.0" - } - } - } - }, - "postcss-calc": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-5.3.1.tgz", - "integrity": "sha1-d7rnypKK2FcW4v2kLyYb98HWW14=", - "dev": true, - "requires": { - "postcss": "5.2.17", - "postcss-message-helpers": "2.0.0", - "reduce-css-calc": "1.3.0" - } - }, - "postcss-colormin": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-2.2.2.tgz", - "integrity": "sha1-ZjFBfV8OkJo9fsJrJMio0eT5bks=", - "dev": true, - "requires": { - "colormin": "1.1.2", - "postcss": "5.2.17", - "postcss-value-parser": "3.3.0" - } - }, - "postcss-convert-values": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-2.6.1.tgz", - "integrity": "sha1-u9hZPFwf0uPRwyK7kl3K6Nrk1i0=", - "dev": true, - "requires": { - "postcss": "5.2.17", - "postcss-value-parser": "3.3.0" - } - }, - "postcss-discard-comments": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz", - "integrity": "sha1-vv6J+v1bPazlzM5Rt2uBUUvgDj0=", - "dev": true, - "requires": { - "postcss": "5.2.17" - } - }, - "postcss-discard-duplicates": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-2.1.0.tgz", - "integrity": "sha1-uavye4isGIFYpesSq8riAmO5GTI=", - "dev": true, - "requires": { - "postcss": "5.2.17" - } - }, - "postcss-discard-empty": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz", - "integrity": "sha1-0rS9nVztXr2Nyt52QMfXzX9PkrU=", - "dev": true, - "requires": { - "postcss": "5.2.17" - } - }, - "postcss-discard-overridden": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz", - "integrity": "sha1-ix6vVU9ob7KIzYdMVWZ7CqNmjVg=", - "dev": true, - "requires": { - "postcss": "5.2.17" - } - }, - "postcss-discard-unused": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz", - "integrity": "sha1-vOMLLMWR/8Y0Mitfs0ZLbZNPRDM=", - "dev": true, - "requires": { - "postcss": "5.2.17", - "uniqs": "2.0.0" - } - }, - "postcss-filter-plugins": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/postcss-filter-plugins/-/postcss-filter-plugins-2.0.2.tgz", - "integrity": "sha1-bYWGJTTXNaxCDkqFgG4fXUKG2Ew=", - "dev": true, - "requires": { - "postcss": "5.2.17", - "uniqid": "4.1.1" - } - }, - "postcss-image-inliner": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/postcss-image-inliner/-/postcss-image-inliner-0.3.1.tgz", - "integrity": "sha1-ocLrhcHuINayr+6yC5k+rNmtdOo=", - "dev": true, - "requires": { - "asset-resolver": "0.2.1", - "bluebird": "3.3.5", - "debug": "2.2.0", - "filesize": "3.3.0", - "lodash.defaults": "4.2.0", - "lodash.escaperegexp": "4.1.2", - "lodash.isstring": "4.0.1", - "lodash.last": "3.0.0", - "lodash.map": "4.6.0", - "lodash.partialright": "4.2.1", - "lodash.reduce": "4.6.0", - "lodash.reject": "4.6.0", - "lodash.result": "4.5.2", - "mime": "1.3.4", - "object-hash": "1.1.8", - "postcss": "5.0.21", - "request": "2.72.0", - "svgo": "0.6.6", - "then-fs": "2.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", - "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", - "dev": true - }, - "async": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz", - "integrity": "sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw==", - "dev": true, - "requires": { - "lodash": "4.17.4" - } - }, - "aws-sign2": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", - "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", - "dev": true - }, - "bluebird": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.3.5.tgz", - "integrity": "sha1-XudH8ce9lnZYtoOTZDCu51OVWjQ=", - "dev": true - }, - "boom": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", - "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", - "dev": true, - "requires": { - "hoek": "2.16.3" - } - }, - "caseless": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", - "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=", - "dev": true - }, - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", - "dev": true - }, - "cryptiles": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", - "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", - "dev": true, - "requires": { - "boom": "2.10.1" - } - }, - "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", - "dev": true, - "requires": { - "ms": "0.7.1" - } - }, - "form-data": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-1.0.1.tgz", - "integrity": "sha1-rjFduaSQf6BlUCMEpm13M0de43w=", - "dev": true, - "requires": { - "async": "2.5.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.17" - } - }, - "har-validator": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", - "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=", - "dev": true, - "requires": { - "chalk": "1.1.3", - "commander": "2.11.0", - "is-my-json-valid": "2.16.1", - "pinkie-promise": "2.0.1" - } - }, - "hawk": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", - "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", - "dev": true, - "requires": { - "boom": "2.10.1", - "cryptiles": "2.0.5", - "hoek": "2.16.3", - "sntp": "1.0.9" - } - }, - "hoek": { - "version": "2.16.3", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", - "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", - "dev": true - }, - "http-signature": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", - "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", - "dev": true, - "requires": { - "assert-plus": "0.2.0", - "jsprim": "1.4.1", - "sshpk": "1.13.1" - } - }, - "mime": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz", - "integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM=", - "dev": true - }, - "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", - "dev": true - }, - "node-uuid": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", - "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=", - "dev": true - }, - "postcss": { - "version": "5.0.21", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.0.21.tgz", - "integrity": "sha1-1M9vGXdGSMSSrFfCmPavs8BMrv4=", - "dev": true, - "requires": { - "js-base64": "2.3.2", - "source-map": "0.5.7", - "supports-color": "3.2.3" - } - }, - "qs": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.1.2.tgz", - "integrity": "sha1-tZ2JJdDJme9tY6z0rFq7CtqiS1Q=", - "dev": true - }, - "request": { - "version": "2.72.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.72.0.tgz", - "integrity": "sha1-DOOheVEmILEEQfFMguIcEsDdtOE=", - "dev": true, - "requires": { - "aws-sign2": "0.6.0", - "aws4": "1.6.0", - "bl": "1.1.2", - "caseless": "0.11.0", - "combined-stream": "1.0.5", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "1.0.1", - "har-validator": "2.0.6", - "hawk": "3.1.3", - "http-signature": "1.1.1", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.17", - "node-uuid": "1.4.8", - "oauth-sign": "0.8.2", - "qs": "6.1.2", - "stringstream": "0.0.5", - "tough-cookie": "2.2.2", - "tunnel-agent": "0.4.3" - } - }, - "sntp": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", - "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", - "dev": true, - "requires": { - "hoek": "2.16.3" - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "1.0.0" - } - }, - "tough-cookie": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.2.2.tgz", - "integrity": "sha1-yDoYMPTl7wuT7yo0iOck+N4Basc=", - "dev": true - }, - "tunnel-agent": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", - "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=", - "dev": true - } - } - }, - "postcss-merge-idents": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz", - "integrity": "sha1-TFUwMTwI4dWzu/PSu8dH4njuonA=", - "dev": true, - "requires": { - "has": "1.0.1", - "postcss": "5.2.17", - "postcss-value-parser": "3.3.0" - } - }, - "postcss-merge-longhand": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-2.0.2.tgz", - "integrity": "sha1-I9kM0Sewp3mUkVMyc5A0oaTz1lg=", - "dev": true, - "requires": { - "postcss": "5.2.17" - } - }, - "postcss-merge-rules": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-2.1.2.tgz", - "integrity": "sha1-0d9d+qexrMO+VT8OnhDofGG19yE=", - "dev": true, - "requires": { - "browserslist": "1.7.7", - "caniuse-api": "1.6.1", - "postcss": "5.2.17", - "postcss-selector-parser": "2.2.3", - "vendors": "1.0.1" - } - }, - "postcss-message-helpers": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-message-helpers/-/postcss-message-helpers-2.0.0.tgz", - "integrity": "sha1-pPL0+rbk/gAvCu0ABHjN9S+bpg4=", - "dev": true - }, - "postcss-minify-font-values": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz", - "integrity": "sha1-S1jttWZB66fIR0qzUmyv17vey2k=", - "dev": true, - "requires": { - "object-assign": "4.1.1", - "postcss": "5.2.17", - "postcss-value-parser": "3.3.0" - } - }, - "postcss-minify-gradients": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz", - "integrity": "sha1-Xb2hE3NwP4PPtKPqOIHY11/15uE=", - "dev": true, - "requires": { - "postcss": "5.2.17", - "postcss-value-parser": "3.3.0" - } - }, - "postcss-minify-params": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz", - "integrity": "sha1-rSzgcTc7lDs9kwo/pZo1jCjW8fM=", - "dev": true, - "requires": { - "alphanum-sort": "1.0.2", - "postcss": "5.2.17", - "postcss-value-parser": "3.3.0", - "uniqs": "2.0.0" - } - }, - "postcss-minify-selectors": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz", - "integrity": "sha1-ssapjAByz5G5MtGkllCBFDEXNb8=", - "dev": true, - "requires": { - "alphanum-sort": "1.0.2", - "has": "1.0.1", - "postcss": "5.2.17", - "postcss-selector-parser": "2.2.3" - } - }, - "postcss-normalize-charset": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz", - "integrity": "sha1-757nEhLX/nWceO0WL2HtYrXLk/E=", - "dev": true, - "requires": { - "postcss": "5.2.17" - } - }, - "postcss-normalize-url": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz", - "integrity": "sha1-EI90s/L82viRov+j6kWSJ5/HgiI=", - "dev": true, - "requires": { - "is-absolute-url": "2.1.0", - "normalize-url": "1.9.1", - "postcss": "5.2.17", - "postcss-value-parser": "3.3.0" - } - }, - "postcss-ordered-values": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-2.2.3.tgz", - "integrity": "sha1-7sbCpntsQSqNsgQud/6NpD+VwR0=", - "dev": true, - "requires": { - "postcss": "5.2.17", - "postcss-value-parser": "3.3.0" - } - }, - "postcss-reduce-idents": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz", - "integrity": "sha1-wsbSDMlYKE9qv75j92Cb9AkFmtM=", - "dev": true, - "requires": { - "postcss": "5.2.17", - "postcss-value-parser": "3.3.0" - } - }, - "postcss-reduce-initial": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz", - "integrity": "sha1-aPgGlfBF0IJjqHmtJA343WT2ROo=", - "dev": true, - "requires": { - "postcss": "5.2.17" - } - }, - "postcss-reduce-transforms": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz", - "integrity": "sha1-/3b02CEkN7McKYpC0uFEQCV3GuE=", - "dev": true, - "requires": { - "has": "1.0.1", - "postcss": "5.2.17", - "postcss-value-parser": "3.3.0" - } - }, - "postcss-selector-parser": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz", - "integrity": "sha1-+UN3iGBsPJrO4W/+jYsWKX8nu5A=", - "dev": true, - "requires": { - "flatten": "1.0.2", - "indexes-of": "1.0.1", - "uniq": "1.0.1" - } - }, - "postcss-svgo": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-2.1.6.tgz", - "integrity": "sha1-tt8YqmE7Zm4TPwittSGcJoSsEI0=", - "dev": true, - "requires": { - "is-svg": "2.1.0", - "postcss": "5.2.17", - "postcss-value-parser": "3.3.0", - "svgo": "0.7.2" - }, - "dependencies": { - "csso": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/csso/-/csso-2.3.2.tgz", - "integrity": "sha1-3dUsWHAz9J6Utx/FVWnyUuj/X4U=", - "dev": true, - "requires": { - "clap": "1.2.3", - "source-map": "0.5.7" - } - }, - "esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", - "dev": true - }, - "js-yaml": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.7.0.tgz", - "integrity": "sha1-XJZ93YN6m/3KXy3oQlOr6KHAO4A=", - "dev": true, - "requires": { - "argparse": "1.0.9", - "esprima": "2.7.3" - } - }, - "svgo": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-0.7.2.tgz", - "integrity": "sha1-n1dyQTlSE1xv779Ar+ak+qiLS7U=", - "dev": true, - "requires": { - "coa": "1.0.4", - "colors": "1.1.2", - "csso": "2.3.2", - "js-yaml": "3.7.0", - "mkdirp": "0.5.1", - "sax": "1.2.4", - "whet.extend": "0.9.9" - } - } - } - }, - "postcss-unique-selectors": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz", - "integrity": "sha1-mB1X0p3csz57Hf4f1DuGSfkzyh0=", - "dev": true, - "requires": { - "alphanum-sort": "1.0.2", - "postcss": "5.2.17", - "uniqs": "2.0.0" - } - }, - "postcss-value-parser": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz", - "integrity": "sha1-h/OPnxj3dKSrTIojL1xc6IcqnRU=", - "dev": true - }, - "postcss-zindex": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-2.2.0.tgz", - "integrity": "sha1-0hCd3AVbka9n/EyzsCWUZjnSryI=", - "dev": true, - "requires": { - "has": "1.0.1", - "postcss": "5.2.17", - "uniqs": "2.0.0" - } - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "pretty-bytes": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-2.0.1.tgz", - "integrity": "sha1-FV7E0ANvQTkecEXW2+SWPVJdJk8=", - "dev": true, - "requires": { - "get-stdin": "4.0.1", - "meow": "3.7.0", - "number-is-nan": "1.0.1" - }, - "dependencies": { - "get-stdin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", - "dev": true - } - } - }, - "pretty-hrtime": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", - "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=", - "dev": true - }, - "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", - "dev": true - }, - "progress": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", - "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", - "dev": true - }, - "promise": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", - "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", - "dev": true, - "requires": { - "asap": "2.0.6" - } - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "q": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.0.tgz", - "integrity": "sha1-3QG6ydBtMObyGa7LglPunr3DCPE=", - "dev": true - }, - "qs": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", - "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", - "dev": true - }, - "query-string": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", - "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", - "dev": true, - "requires": { - "object-assign": "4.1.1", - "strict-uri-encode": "1.1.0" - } - }, - "random-bytes": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", - "integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs=", - "dev": true - }, - "randomatic": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", - "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", - "dev": true, - "requires": { - "is-number": "3.0.0", - "kind-of": "4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "1.1.5" - } - } - } - }, - "range-parser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", - "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", - "dev": true - }, - "raw-body": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.1.7.tgz", - "integrity": "sha1-rf6s4uT7MJgFgBTQjActzFl1h3Q=", - "dev": true, - "requires": { - "bytes": "2.4.0", - "iconv-lite": "0.4.13", - "unpipe": "1.0.0" - }, - "dependencies": { - "bytes": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz", - "integrity": "sha1-fZcZb51br39pNeJZhVSe3SpsIzk=", - "dev": true - }, - "iconv-lite": { - "version": "0.4.13", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz", - "integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI=", - "dev": true - } - } - }, - "rc": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.1.tgz", - "integrity": "sha1-LgPo5C7kULjLPc5lvhv4l04d/ZU=", - "dev": true, - "requires": { - "deep-extend": "0.4.2", - "ini": "1.3.4", - "minimist": "1.2.0", - "strip-json-comments": "2.0.1" - } - }, - "rcfinder": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/rcfinder/-/rcfinder-0.1.9.tgz", - "integrity": "sha1-8+gPOH3fmugK4wpBADKWQuroERU=", - "dev": true, - "requires": { - "lodash.clonedeep": "4.5.0" - } - }, - "rcloader": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/rcloader/-/rcloader-0.2.2.tgz", - "integrity": "sha1-WNIpi0YtC5v9ITPSoex0+9cFxxc=", - "dev": true, - "requires": { - "lodash.assign": "4.2.0", - "lodash.isobject": "3.0.2", - "lodash.merge": "4.6.0", - "rcfinder": "0.1.9" - } - }, - "read-all-stream": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/read-all-stream/-/read-all-stream-3.1.0.tgz", - "integrity": "sha1-NcPhd/IHjveJ7kv6+kNzB06u9Po=", - "dev": true, - "requires": { - "pinkie-promise": "2.0.1", - "readable-stream": "2.3.3" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - } - } - }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "dev": true, - "requires": { - "load-json-file": "1.1.0", - "normalize-package-data": "2.4.0", - "path-type": "1.1.0" - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "dev": true, - "requires": { - "find-up": "1.1.2", - "read-pkg": "1.1.0" - } - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "reaver": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/reaver/-/reaver-2.0.0.tgz", - "integrity": "sha1-epBv61vBvNCFZ/wjUV807LEnQQY=", - "dev": true, - "requires": { - "minimist": "1.2.0" - } - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "dev": true, - "requires": { - "resolve": "1.1.6" - } - }, - "redent": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", - "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", - "dev": true, - "requires": { - "indent-string": "2.1.0", - "strip-indent": "1.0.1" - } - }, - "reduce-component": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/reduce-component/-/reduce-component-1.0.1.tgz", - "integrity": "sha1-4Mk1QsV0UhvqE98PlIjtgqt3xdo=", - "dev": true - }, - "reduce-css-calc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz", - "integrity": "sha1-dHyRTgSWFKTJz7umKYca0dKSdxY=", - "dev": true, - "requires": { - "balanced-match": "0.4.2", - "math-expression-evaluator": "1.2.17", - "reduce-function-call": "1.0.2" - }, - "dependencies": { - "balanced-match": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", - "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", - "dev": true - } - } - }, - "reduce-function-call": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/reduce-function-call/-/reduce-function-call-1.0.2.tgz", - "integrity": "sha1-WiAL+S4ON3UXUv5FsKszD9S2vpk=", - "dev": true, - "requires": { - "balanced-match": "0.4.2" - }, - "dependencies": { - "balanced-match": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", - "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", - "dev": true - } - } - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "requires": { - "is-equal-shallow": "0.1.3" - } - }, - "registry-auth-token": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.1.tgz", - "integrity": "sha1-+w0yie4Nmtosu1KvXf5mywcNMAY=", - "dev": true, - "requires": { - "rc": "1.2.1", - "safe-buffer": "5.1.1" - } - }, - "registry-url": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", - "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", - "dev": true, - "requires": { - "rc": "1.2.1" - } - }, - "remote-content": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/remote-content/-/remote-content-1.0.1.tgz", - "integrity": "sha1-DDcONnAe3CKB19FyLUJzCD0TcWM=", - "dev": true, - "requires": { - "superagent": "1.8.5" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", - "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "dev": true, - "requires": { - "is-finite": "1.0.2" - } - }, - "replace-ext": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", - "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", - "dev": true - }, - "request": { - "version": "2.82.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.82.0.tgz", - "integrity": "sha512-/QWqfmyTfQ4OYs6EhB1h2wQsX9ZxbuNePCvCm0Mdz/mxw73mjdg0D4QdIl0TQBFs35CZmMXLjk0iCGK395CUDg==", - "dev": true, - "requires": { - "aws-sign2": "0.7.0", - "aws4": "1.6.0", - "caseless": "0.12.0", - "combined-stream": "1.0.5", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "2.3.1", - "har-validator": "5.0.3", - "hawk": "6.0.2", - "http-signature": "1.2.0", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.17", - "oauth-sign": "0.8.2", - "performance-now": "2.1.0", - "qs": "6.5.1", - "safe-buffer": "5.1.1", - "stringstream": "0.0.5", - "tough-cookie": "2.3.3", - "tunnel-agent": "0.6.0", - "uuid": "3.1.0" - } - }, - "request-progress": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-2.0.1.tgz", - "integrity": "sha1-XTa7V5YcZzqlt4jbyBQf3yO0Tgg=", - "dev": true, - "requires": { - "throttleit": "1.0.0" - } - }, - "resolve": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.6.tgz", - "integrity": "sha1-00kq0FTKgA9b76YS5hvqwe7Jj48=", - "dev": true - }, - "resolve-dir": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-0.1.1.tgz", - "integrity": "sha1-shklmlYC+sXFxJatiUpujMQwJh4=", - "dev": true, - "requires": { - "expand-tilde": "1.2.2", - "global-modules": "0.2.3" - } - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "response-time": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/response-time/-/response-time-2.3.2.tgz", - "integrity": "sha1-/6cbq5UtYvfB1Jt0NDVfvGjf/Fo=", - "dev": true, - "requires": { - "depd": "1.1.1", - "on-headers": "1.0.1" - } - }, - "right-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", - "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", - "dev": true, - "requires": { - "align-text": "0.1.4" - } - }, - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", - "dev": true, - "requires": { - "glob": "7.1.2" - } - }, - "rndm": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/rndm/-/rndm-1.2.0.tgz", - "integrity": "sha1-8z/pz7Urv9UgqhgyO8ZdsRCht2w=", - "dev": true - }, - "safe-buffer": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", - "dev": true - }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true - }, - "seek-bzip": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.5.tgz", - "integrity": "sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w=", - "dev": true, - "requires": { - "commander": "2.8.1" - } - }, - "semver": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", - "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", - "dev": true - }, - "semver-diff": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", - "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", - "dev": true, - "requires": { - "semver": "5.4.1" - } - }, - "semver-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-1.0.0.tgz", - "integrity": "sha1-kqSWkGX5xwxpR1PVUkj8aPj2Usk=", - "dev": true, - "optional": true - }, - "semver-truncate": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/semver-truncate/-/semver-truncate-1.1.2.tgz", - "integrity": "sha1-V/Qd5pcHpicJp+AQS6IRcQnqR+g=", - "dev": true, - "optional": true, - "requires": { - "semver": "5.4.1" - } - }, - "send": { - "version": "0.15.6", - "resolved": "https://registry.npmjs.org/send/-/send-0.15.6.tgz", - "integrity": "sha1-IPI6nJJbdiq4JwX+L52yUqzkfjQ=", - "dev": true, - "requires": { - "debug": "2.6.9", - "depd": "1.1.1", - "destroy": "1.0.4", - "encodeurl": "1.0.1", - "escape-html": "1.0.3", - "etag": "1.8.1", - "fresh": "0.5.2", - "http-errors": "1.6.2", - "mime": "1.3.4", - "ms": "2.0.0", - "on-finished": "2.3.0", - "range-parser": "1.2.0", - "statuses": "1.3.1" - }, - "dependencies": { - "mime": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz", - "integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM=", - "dev": true - } - } - }, - "sequencify": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/sequencify/-/sequencify-0.0.7.tgz", - "integrity": "sha1-kM/xnQLgcCf9dn9erT57ldHnOAw=", - "dev": true - }, - "serve-favicon": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/serve-favicon/-/serve-favicon-2.3.2.tgz", - "integrity": "sha1-3UGeJo3gEqtysxnTN/IQUBP5OB8=", - "dev": true, - "requires": { - "etag": "1.7.0", - "fresh": "0.3.0", - "ms": "0.7.2", - "parseurl": "1.3.2" - }, - "dependencies": { - "etag": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.7.0.tgz", - "integrity": "sha1-A9MLX2fdbmMtKUXTDWZScxo01dg=", - "dev": true - }, - "fresh": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.3.0.tgz", - "integrity": "sha1-ZR+DjiJCTnVm3hYdg1jKoZn4PU8=", - "dev": true - }, - "ms": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", - "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", - "dev": true - } - } - }, - "serve-index": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.7.3.tgz", - "integrity": "sha1-egV/xu4o3GP2RWbl+lexEahq7NI=", - "dev": true, - "requires": { - "accepts": "1.2.13", - "batch": "0.5.3", - "debug": "2.2.0", - "escape-html": "1.0.3", - "http-errors": "1.3.1", - "mime-types": "2.1.17", - "parseurl": "1.3.2" - }, - "dependencies": { - "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", - "dev": true, - "requires": { - "ms": "0.7.1" - } - }, - "http-errors": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.3.1.tgz", - "integrity": "sha1-GX4izevUGYWF6GlO9nhhl7ke2UI=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "statuses": "1.3.1" - } - }, - "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", - "dev": true - } - } - }, - "serve-static": { - "version": "1.12.6", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.12.6.tgz", - "integrity": "sha1-uXN3P2NEmTTaVOW+ul4x2fQhFXc=", - "dev": true, - "requires": { - "encodeurl": "1.0.1", - "escape-html": "1.0.3", - "parseurl": "1.3.2", - "send": "0.15.6" - } - }, - "set-immediate-shim": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", - "dev": true - }, - "setprototypeof": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", - "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=", - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "shelljs": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", - "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=", - "dev": true - }, - "shellwords": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", - "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", - "dev": true - }, - "sigmund": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", - "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", - "dev": true - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true - }, - "slash": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", - "dev": true - }, - "slick": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/slick/-/slick-1.12.2.tgz", - "integrity": "sha1-vQSN23TefRymkV+qSldXCzVQwtc=", - "dev": true - }, - "slide": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", - "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=", - "dev": true - }, - "sntp": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.0.2.tgz", - "integrity": "sha1-UGQRDwr4X3z9t9a2ekACjOUrSys=", - "dev": true, - "requires": { - "hoek": "4.2.0" - } - }, - "sort-keys": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", - "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", - "dev": true, - "requires": { - "is-plain-obj": "1.1.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - }, - "source-map-resolve": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.3.1.tgz", - "integrity": "sha1-YQ9hIqRFuN1RU1oqcbeD38Ekh2E=", - "dev": true, - "requires": { - "atob": "1.1.3", - "resolve-url": "0.2.1", - "source-map-url": "0.3.0", - "urix": "0.1.0" - } - }, - "source-map-url": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.3.0.tgz", - "integrity": "sha1-fsrxO1e80J2opAxdJp2zN5nUqvk=", - "dev": true - }, - "sparkles": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.0.tgz", - "integrity": "sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM=", - "dev": true - }, - "spdx-correct": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", - "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", - "dev": true, - "requires": { - "spdx-license-ids": "1.2.2" - } - }, - "spdx-expression-parse": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", - "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=", - "dev": true - }, - "spdx-license-ids": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", - "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", - "dev": true - }, - "split": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", - "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", - "dev": true, - "requires": { - "through": "2.3.8" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "squeak": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/squeak/-/squeak-1.3.0.tgz", - "integrity": "sha1-MwRQN7ZDiLVnZ0uEMiplIQc5FsM=", - "dev": true, - "optional": true, - "requires": { - "chalk": "1.1.3", - "console-stream": "0.1.1", - "lpad-align": "1.1.2" - } - }, - "sshpk": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", - "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", - "dev": true, - "requires": { - "asn1": "0.2.3", - "assert-plus": "1.0.0", - "bcrypt-pbkdf": "1.0.1", - "dashdash": "1.14.1", - "ecc-jsbn": "0.1.1", - "getpass": "0.1.7", - "jsbn": "0.1.1", - "tweetnacl": "0.14.5" - } - }, - "stat-mode": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-0.2.2.tgz", - "integrity": "sha1-5sgLYjEj19gM8TLOU480YokHJQI=", - "dev": true - }, - "statuses": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", - "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", - "dev": true - }, - "stream-combiner": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", - "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", - "dev": true, - "requires": { - "duplexer": "0.1.1" - } - }, - "stream-combiner2": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", - "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=", - "dev": true, - "requires": { - "duplexer2": "0.1.4", - "readable-stream": "2.3.3" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - } - } - }, - "stream-consume": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/stream-consume/-/stream-consume-0.1.0.tgz", - "integrity": "sha1-pB6tGm1ggc63n2WwYZAbbY89HQ8=", - "dev": true - }, - "stream-counter": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/stream-counter/-/stream-counter-0.2.0.tgz", - "integrity": "sha1-3tJmVWMZyLDiIoErnPOyb6fZR94=", - "dev": true, - "requires": { - "readable-stream": "1.1.14" - } - }, - "stream-shift": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", - "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", - "dev": true - }, - "streamqueue": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/streamqueue/-/streamqueue-1.1.1.tgz", - "integrity": "sha1-0612aGvpJLv5yix0qBSiGCR11tc=", - "dev": true, - "requires": { - "isstream": "0.1.2", - "readable-stream": "1.0.34" - }, - "dependencies": { - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - } - } - }, - "strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", - "dev": true - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, - "stringstream": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", - "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=", - "dev": true - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "2.1.1" - } - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "0.2.1" - } - }, - "strip-bom-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-stream/-/strip-bom-stream-1.0.0.tgz", - "integrity": "sha1-5xRDmFd9Uaa+0PoZlPoF9D/ZiO4=", - "dev": true, - "requires": { - "first-chunk-stream": "1.0.0", - "strip-bom": "2.0.0" - } - }, - "strip-dirs": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-1.1.1.tgz", - "integrity": "sha1-lgu9EoeETzl1pFWKoQOoJV4kVqA=", - "dev": true, - "requires": { - "chalk": "1.1.3", - "get-stdin": "4.0.1", - "is-absolute": "0.1.7", - "is-natural-number": "2.1.1", - "minimist": "1.2.0", - "sum-up": "1.0.3" - }, - "dependencies": { - "get-stdin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", - "dev": true - }, - "is-absolute": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-0.1.7.tgz", - "integrity": "sha1-hHSREZ/MtftDYhfMc39/qtUPYD8=", - "dev": true, - "requires": { - "is-relative": "0.1.3" - } - }, - "is-relative": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-0.1.3.tgz", - "integrity": "sha1-kF/uiuhvRbPsYUvDwVyGnfCHboI=", - "dev": true - } - } - }, - "strip-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", - "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", - "dev": true, - "requires": { - "get-stdin": "4.0.1" - }, - "dependencies": { - "get-stdin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", - "dev": true - } - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "strip-outer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.0.tgz", - "integrity": "sha1-qsC6YNLpDF1PJ1/Yhp/ZotMQ/7g=", - "dev": true, - "requires": { - "escape-string-regexp": "1.0.5" - } - }, - "style-data": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/style-data/-/style-data-1.1.2.tgz", - "integrity": "sha1-2fSoAuy3ZDMWVg02TEta+jk1qJ0=", - "dev": true, - "requires": { - "cheerio": "0.19.0", - "extend": "3.0.1", - "mediaquery-text": "1.0.2", - "object.pick": "1.3.0" - }, - "dependencies": { - "cheerio": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.19.0.tgz", - "integrity": "sha1-dy5wFfLuKZZQltcepBdbdas1SSU=", - "dev": true, - "requires": { - "css-select": "1.0.0", - "dom-serializer": "0.1.0", - "entities": "1.1.1", - "htmlparser2": "3.8.3", - "lodash": "3.10.1" - } - }, - "css-select": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.0.0.tgz", - "integrity": "sha1-sRIcpRhI3SZOIkTQWM7iVN7rRLA=", - "dev": true, - "requires": { - "boolbase": "1.0.0", - "css-what": "1.0.0", - "domutils": "1.4.3", - "nth-check": "1.0.1" - } - }, - "css-what": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-1.0.0.tgz", - "integrity": "sha1-18wt9FGAZm+Z0rFEYmOUaeAPc2w=", - "dev": true - }, - "domutils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.4.3.tgz", - "integrity": "sha1-CGVRN5bGswYDGFDhdVFrr4C3Km8=", - "dev": true, - "requires": { - "domelementtype": "1.3.0" - } - }, - "lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", - "dev": true - } - } - }, - "style-selector": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/style-selector/-/style-selector-2.0.1.tgz", - "integrity": "sha1-bCV/WyFArhhDXp2xXUJOTvY+RGw=", - "dev": true, - "requires": { - "slick": "1.12.2" - } - }, - "sum-up": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sum-up/-/sum-up-1.0.3.tgz", - "integrity": "sha1-HGYfZnBX9jvLeHWqFDi8FiUlFW4=", - "dev": true, - "requires": { - "chalk": "1.1.3" - } - }, - "superagent": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/superagent/-/superagent-1.8.5.tgz", - "integrity": "sha1-HA3cOvMOgOuE68BcshItqP6UC1U=", - "dev": true, - "requires": { - "component-emitter": "1.2.1", - "cookiejar": "2.0.6", - "debug": "2.6.9", - "extend": "3.0.0", - "form-data": "1.0.0-rc3", - "formidable": "1.0.17", - "methods": "1.1.2", - "mime": "1.3.4", - "qs": "2.3.3", - "readable-stream": "1.0.27-1", - "reduce-component": "1.0.1" - }, - "dependencies": { - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true - }, - "extend": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz", - "integrity": "sha1-WkdDU7nzNT3dgXbf03uRyDpG8dQ=", - "dev": true - }, - "form-data": { - "version": "1.0.0-rc3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-1.0.0-rc3.tgz", - "integrity": "sha1-01vGLn+8KTeuePlIqqDTjZBgdXc=", - "dev": true, - "requires": { - "async": "1.5.2", - "combined-stream": "1.0.5", - "mime-types": "2.1.17" - } - }, - "mime": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz", - "integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM=", - "dev": true - }, - "qs": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-2.3.3.tgz", - "integrity": "sha1-6eha2+ddoLvkyOBHaghikPhjtAQ=", - "dev": true - }, - "readable-stream": { - "version": "1.0.27-1", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.27-1.tgz", - "integrity": "sha1-a2eYPCA1fO/QfwFlABoW1xDZEHg=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - } - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - }, - "svgo": { - "version": "0.6.6", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-0.6.6.tgz", - "integrity": "sha1-s0CIkDbyD5tEdUMHfQ9Vc+0ETAg=", - "dev": true, - "requires": { - "coa": "1.0.4", - "colors": "1.1.2", - "csso": "2.0.0", - "js-yaml": "3.6.1", - "mkdirp": "0.5.1", - "sax": "1.2.4", - "whet.extend": "0.9.9" - } - }, - "symbol-tree": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz", - "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=", - "dev": true, - "optional": true - }, - "tar-stream": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.4.tgz", - "integrity": "sha1-NlSc8E7RrumyowwBQyUiONr5QBY=", - "dev": true, - "requires": { - "bl": "1.1.2", - "end-of-stream": "1.4.0", - "readable-stream": "2.3.3", - "xtend": "4.0.1" - }, - "dependencies": { - "end-of-stream": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.0.tgz", - "integrity": "sha1-epDYM+/abPpurA9JSduw+tOmMgY=", - "dev": true, - "requires": { - "once": "1.4.0" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - } - } - }, - "tempfile": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/tempfile/-/tempfile-1.1.1.tgz", - "integrity": "sha1-W8xOrsxKsscH2LwR2ZzMmiyyh/I=", - "dev": true, - "requires": { - "os-tmpdir": "1.0.2", - "uuid": "2.0.3" - }, - "dependencies": { - "uuid": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", - "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=", - "dev": true - } - } - }, - "then-fs": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/then-fs/-/then-fs-2.0.0.tgz", - "integrity": "sha1-cveS3Z0xcFqRrhnr/Piz+WjIHaI=", - "dev": true, - "requires": { - "promise": "7.3.1" - } - }, - "throttleit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz", - "integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=", - "dev": true - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "through2": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", - "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", - "dev": true, - "requires": { - "readable-stream": "2.3.3", - "xtend": "4.0.1" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - } - } - }, - "through2-concurrent": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/through2-concurrent/-/through2-concurrent-1.1.1.tgz", - "integrity": "sha1-EctOpMnjG8puTB5tukjRxyjDUks=", - "dev": true, - "requires": { - "through2": "2.0.3" - } - }, - "through2-filter": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-2.0.0.tgz", - "integrity": "sha1-YLxVoNrLdghdsfna6Zq0P4PWIuw=", - "dev": true, - "requires": { - "through2": "2.0.3", - "xtend": "4.0.1" - } - }, - "tildify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/tildify/-/tildify-1.2.0.tgz", - "integrity": "sha1-3OwD9V3Km3qj5bBPIYF+tW5jWIo=", - "dev": true, - "requires": { - "os-homedir": "1.0.2" - } - }, - "time-stamp": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", - "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=", - "dev": true - }, - "timed-out": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-3.1.3.tgz", - "integrity": "sha1-lYYL/MXHbCd/j4Mm/Q9bLiDrohc=", - "dev": true - }, - "tiny-lr": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-0.2.1.tgz", - "integrity": "sha1-s/26gC5dVqM8L28QeUsy5Hescp0=", - "dev": true, - "requires": { - "body-parser": "1.14.2", - "debug": "2.2.0", - "faye-websocket": "0.10.0", - "livereload-js": "2.2.2", - "parseurl": "1.3.2", - "qs": "5.1.0" - }, - "dependencies": { - "body-parser": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.14.2.tgz", - "integrity": "sha1-EBXLH+LEQ4WCWVgdtTMy+NDPUPk=", - "dev": true, - "requires": { - "bytes": "2.2.0", - "content-type": "1.0.4", - "debug": "2.2.0", - "depd": "1.1.1", - "http-errors": "1.3.1", - "iconv-lite": "0.4.13", - "on-finished": "2.3.0", - "qs": "5.2.0", - "raw-body": "2.1.7", - "type-is": "1.6.15" - }, - "dependencies": { - "qs": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-5.2.0.tgz", - "integrity": "sha1-qfMRQq9GjLcrJbMBNrokVoNJFr4=", - "dev": true - } - } - }, - "bytes": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.2.0.tgz", - "integrity": "sha1-/TVGSkA/b5EXwt42Cez/nK4ABYg=", - "dev": true - }, - "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", - "dev": true, - "requires": { - "ms": "0.7.1" - } - }, - "http-errors": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.3.1.tgz", - "integrity": "sha1-GX4izevUGYWF6GlO9nhhl7ke2UI=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "statuses": "1.3.1" - } - }, - "iconv-lite": { - "version": "0.4.13", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz", - "integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI=", - "dev": true - }, - "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", - "dev": true - }, - "qs": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-5.1.0.tgz", - "integrity": "sha1-TZMuXH6kEcynajEtOaYGIA/VDNk=", - "dev": true - } - } - }, - "tmp": { - "version": "0.0.28", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.28.tgz", - "integrity": "sha1-Fyc1t/YU6nrzlmT6hM8N5OUV0SA=", - "dev": true, - "requires": { - "os-tmpdir": "1.0.2" - } - }, - "to-absolute-glob": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-0.1.1.tgz", - "integrity": "sha1-HN+kcqnvUMI57maZm2YsoOs5k38=", - "dev": true, - "requires": { - "extend-shallow": "2.0.1" - } - }, - "tough-cookie": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", - "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=", - "dev": true, - "requires": { - "punycode": "1.4.1" - } - }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", - "dev": true, - "optional": true - }, - "trim-newlines": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", - "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", - "dev": true - }, - "trim-repeated": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", - "integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=", - "dev": true, - "requires": { - "escape-string-regexp": "1.0.5" - } - }, - "try-json-parse": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/try-json-parse/-/try-json-parse-0.1.1.tgz", - "integrity": "sha1-jbAWIuh35RuDFAyu58gIZK05DII=", - "dev": true - }, - "tsscmp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.5.tgz", - "integrity": "sha1-fcSjOvcVgatDN9qR2FylQn69mpc=", - "dev": true - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true, - "optional": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "requires": { - "prelude-ls": "1.1.2" - } - }, - "type-is": { - "version": "1.6.15", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz", - "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=", - "dev": true, - "requires": { - "media-typer": "0.3.0", - "mime-types": "2.1.17" - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "uglify-js": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.6.0.tgz", - "integrity": "sha1-JeqhzDVQ45QQzu+v0c+7a20V8AE=", - "dev": true, - "requires": { - "async": "0.2.10", - "source-map": "0.5.7", - "uglify-to-browserify": "1.0.2", - "yargs": "3.10.0" - } - }, - "uglify-save-license": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/uglify-save-license/-/uglify-save-license-0.4.1.tgz", - "integrity": "sha1-lXJsF8xv0XHDYX479NjYKqjEzOE=", - "dev": true - }, - "uglify-to-browserify": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", - "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", - "dev": true - }, - "uid-safe": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.4.tgz", - "integrity": "sha1-Otbzg2jG1MjHXsF2I/t5qh0HHYE=", - "dev": true, - "requires": { - "random-bytes": "1.0.0" - } - }, - "unc-path-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", - "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", - "dev": true - }, - "uniq": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", - "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", - "dev": true - }, - "uniqid": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/uniqid/-/uniqid-4.1.1.tgz", - "integrity": "sha1-iSIN32t1GuUrX3JISGNShZa7hME=", - "dev": true, - "requires": { - "macaddress": "0.2.8" - } - }, - "uniqs": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", - "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=", - "dev": true - }, - "unique-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-1.0.0.tgz", - "integrity": "sha1-1ZpKdUJ0R9mqbJHnAmP40mpLEEs=", - "dev": true - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "dev": true - }, - "unzip-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-1.0.2.tgz", - "integrity": "sha1-uYTwh3/AqJwsdzzB73tbIytbBv4=", - "dev": true - }, - "update-notifier": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-0.7.0.tgz", - "integrity": "sha1-FDxFMzg9CJCO9wVGIGOV/htauwY=", - "dev": true, - "requires": { - "ansi-align": "1.1.0", - "boxen": "0.5.1", - "chalk": "1.1.3", - "configstore": "2.1.0", - "is-npm": "1.0.0", - "latest-version": "2.0.0", - "semver-diff": "2.1.0", - "xdg-basedir": "2.0.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url-parse-lax": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", - "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", - "dev": true, - "requires": { - "prepend-http": "1.0.4" - } - }, - "url-regex": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/url-regex/-/url-regex-3.2.0.tgz", - "integrity": "sha1-260eDJ4p4QXdCx8J9oYvf9tIJyQ=", - "dev": true, - "optional": true, - "requires": { - "ip-regex": "1.0.3" - } - }, - "user-home": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", - "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=", - "dev": true - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "utils-merge": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz", - "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg=", - "dev": true - }, - "uuid": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", - "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==", - "dev": true - }, - "v8flags": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz", - "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=", - "dev": true, - "requires": { - "user-home": "1.1.1" - } - }, - "vali-date": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/vali-date/-/vali-date-1.0.0.tgz", - "integrity": "sha1-G5BKWWCfsyjvB4E4Qgk09rhnCaY=", - "dev": true - }, - "validate-npm-package-license": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", - "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", - "dev": true, - "requires": { - "spdx-correct": "1.0.2", - "spdx-expression-parse": "1.0.4" - } - }, - "vary": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.0.1.tgz", - "integrity": "sha1-meSYFWaihhGN+yuBc1ffeZM3bRA=", - "dev": true - }, - "vendors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.1.tgz", - "integrity": "sha1-N61zyO5Bf7PVgOeFMSMH0nSEfyI=", - "dev": true - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "1.3.0" - } - }, - "vhost": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/vhost/-/vhost-3.0.2.tgz", - "integrity": "sha1-L7HezUxGaqiLD5NBrzPcGv8keNU=", - "dev": true - }, - "vinyl": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz", - "integrity": "sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4=", - "dev": true, - "requires": { - "clone": "1.0.2", - "clone-stats": "0.0.1", - "replace-ext": "0.0.1" - } - }, - "vinyl-assign": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/vinyl-assign/-/vinyl-assign-1.2.1.tgz", - "integrity": "sha1-TRmIkbVRWRHXcajNnFSApGoHSkU=", - "dev": true, - "requires": { - "object-assign": "4.1.1", - "readable-stream": "2.3.3" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - } - } - }, - "vinyl-fs": { - "version": "0.3.14", - "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-0.3.14.tgz", - "integrity": "sha1-mmhRzhysHBzqX+hsCTHWIMLPqeY=", - "dev": true, - "requires": { - "defaults": "1.0.3", - "glob-stream": "3.1.18", - "glob-watcher": "0.0.6", - "graceful-fs": "3.0.11", - "mkdirp": "0.5.1", - "strip-bom": "1.0.0", - "through2": "0.6.5", - "vinyl": "0.4.6" - }, - "dependencies": { - "clone": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz", - "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=", - "dev": true - }, - "graceful-fs": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.11.tgz", - "integrity": "sha1-dhPHeKGv6mLyXGMKCG1/Osu92Bg=", - "dev": true, - "requires": { - "natives": "1.1.0" - } - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "strip-bom": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-1.0.0.tgz", - "integrity": "sha1-hbiGLzhEtabV7IRnqTWYFzo295Q=", - "dev": true, - "requires": { - "first-chunk-stream": "1.0.0", - "is-utf8": "0.2.1" - } - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" - } - }, - "vinyl": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz", - "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=", - "dev": true, - "requires": { - "clone": "0.2.0", - "clone-stats": "0.0.1" - } - } - } - }, - "vinyl-sourcemaps-apply": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz", - "integrity": "sha1-q2VJ1h0XLCsbh75cUI0jnI74dwU=", - "dev": true, - "requires": { - "source-map": "0.5.7" - } - }, - "ware": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ware/-/ware-1.3.0.tgz", - "integrity": "sha1-0bFPOdLiy0q4xAmPdW/ksWTkc9Q=", - "dev": true, - "requires": { - "wrap-fn": "0.1.5" - } - }, - "webidl-conversions": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-2.0.1.tgz", - "integrity": "sha1-O/glj30xjHRDw28uFpQCoaZwNQY=", - "dev": true, - "optional": true - }, - "websocket-driver": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz", - "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=", - "dev": true, - "requires": { - "http-parser-js": "0.4.8", - "websocket-extensions": "0.1.2" - } - }, - "websocket-extensions": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.2.tgz", - "integrity": "sha1-Dhh4HeYpoYMIzhSBZQ9n/6JpOl0=", - "dev": true - }, - "whatwg-url-compat": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/whatwg-url-compat/-/whatwg-url-compat-0.6.5.tgz", - "integrity": "sha1-AImBEa9om7CXVBzVpFymyHmERb8=", - "dev": true, - "optional": true, - "requires": { - "tr46": "0.0.3" - } - }, - "whet.extend": { - "version": "0.9.9", - "resolved": "https://registry.npmjs.org/whet.extend/-/whet.extend-0.9.9.tgz", - "integrity": "sha1-+HfVv2SMl+WqVC+twW1qJZucEaE=", - "dev": true - }, - "which": { - "version": "1.2.14", - "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", - "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", - "dev": true, - "requires": { - "isexe": "2.0.0" - } - }, - "widest-line": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-1.0.0.tgz", - "integrity": "sha1-DAnIXCqUaD0Nfq+O4JfVZL8OEFw=", - "dev": true, - "requires": { - "string-width": "1.0.2" - } - }, - "window-size": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", - "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", - "dev": true - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true, - "optional": true - }, - "wrap-fn": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/wrap-fn/-/wrap-fn-0.1.5.tgz", - "integrity": "sha1-8htuQQFv9KfjFyDbxjoJAWvfmEU=", - "dev": true, - "requires": { - "co": "3.1.0" - }, - "dependencies": { - "co": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/co/-/co-3.1.0.tgz", - "integrity": "sha1-TqVOpaCJOBUxheFSEMaNkJK8G3g=", - "dev": true - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "write-file-atomic": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.3.4.tgz", - "integrity": "sha1-+Aek8LHZ6ROuekgRLmzDrxmRtF8=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "imurmurhash": "0.1.4", - "slide": "1.1.6" - } - }, - "xdg-basedir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-2.0.0.tgz", - "integrity": "sha1-7byQPMOF/ARSPZZqM1UEtVBNG9I=", - "dev": true, - "requires": { - "os-homedir": "1.0.2" - } - }, - "xml-name-validator": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-2.0.1.tgz", - "integrity": "sha1-TYuPHszTQZqjYgYb7O9RXh5VljU=", - "dev": true, - "optional": true - }, - "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", - "dev": true - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - }, - "yargs": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", - "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", - "dev": true, - "requires": { - "camelcase": "1.2.1", - "cliui": "2.1.0", - "decamelize": "1.2.0", - "window-size": "0.1.0" - }, - "dependencies": { - "camelcase": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", - "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", - "dev": true - } - } - }, - "yauzl": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", - "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", - "dev": true, - "requires": { - "fd-slicer": "1.0.1" - } - } - } -} diff --git a/helm.sh/package.json b/helm.sh/package.json deleted file mode 100644 index 5ce7abad05..0000000000 --- a/helm.sh/package.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "helm.sh", - "repository": { - "type": "git", - "url": "https://github.com/helm/helm-www.com.git" - }, - "version": "0.0.1", - "devDependencies": { - "critical": "^0.7.3", - "del": "^2.2.2", - "gulp": "^3.9.1", - "gulp-autoprefixer": "^3.1.1", - "gulp-cache": "^0.4.5", - "gulp-concat": "^2.6.0", - "gulp-connect": "^4.2.0", - "gulp-cssnano": "^2.1.2", - "gulp-imagemin": "^2.4.0", - "gulp-inline-css": "^3.1.0", - "gulp-jshint": "^2.0.1", - "gulp-livereload": "^3.8.1", - "gulp-notify": "^3.2.0", - "gulp-rename": "^1.2.2", - "gulp-ruby-sass": "^2.1.0", - "gulp-sourcemaps": "^1.6.0", - "gulp-uglify": "^1.5.4", - "jshint": "^2.9.2", - "streamqueue": "^1.1.1" - } -} diff --git a/helm.sh/rootfs/.dockerignore b/helm.sh/rootfs/.dockerignore deleted file mode 100644 index 1d1fe94df4..0000000000 --- a/helm.sh/rootfs/.dockerignore +++ /dev/null @@ -1 +0,0 @@ -Dockerfile \ No newline at end of file diff --git a/helm.sh/rootfs/Dockerfile b/helm.sh/rootfs/Dockerfile deleted file mode 100644 index 44a7a1a958..0000000000 --- a/helm.sh/rootfs/Dockerfile +++ /dev/null @@ -1,29 +0,0 @@ -FROM alpine:3.5 - -ARG plugins=http.cors,http.ipfilter,http.minify -ARG BUILD_DATE - -RUN apk upgrade --no-cache --available \ - && apk add --no-cache \ - bash \ - ca-certificates \ - curl \ - libressl \ - openssh-client \ - tar \ - && adduser -D -u 1000 caddy - -RUN curl --silent --show-error --fail --location \ - --header "Accept: application/tar+gzip, application/x-gzip, application/octet-stream" -o - \ - "https://caddyserver.com/download/linux/amd64?plugins=${plugins}" \ - | tar --no-same-owner -C /usr/bin/ -xz caddy \ - && chmod 0755 /usr/bin/caddy \ - && /usr/bin/caddy -version - -COPY . / - -EXPOSE 2015 - -USER caddy -ENTRYPOINT ["/usr/bin/caddy"] -CMD ["--conf", "/etc/caddy/Caddyfile", "--log", "stdout"] diff --git a/helm.sh/rootfs/etc/caddy/Caddyfile b/helm.sh/rootfs/etc/caddy/Caddyfile deleted file mode 100644 index 78cfb81871..0000000000 --- a/helm.sh/rootfs/etc/caddy/Caddyfile +++ /dev/null @@ -1,8 +0,0 @@ -:2015 { - root /svc - tls off - status 200 /healthz -} -:2015/docs { - redir / https://helm-classic.readthedocs.io/en/latest{uri} -} \ No newline at end of file diff --git a/helm.sh/script/build b/helm.sh/script/build deleted file mode 100755 index 00c2e1d2c0..0000000000 --- a/helm.sh/script/build +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env bash - -set -e -set -x - -build_dest=$1 - -cd /app/ - -/src/script/copy-source /src /app -/src/script/link-dependencies -/src/script/install - -gulp -bundle exec jekyll build -d ${build_dest} diff --git a/helm.sh/script/copy-source b/helm.sh/script/copy-source deleted file mode 100755 index 0316fa3984..0000000000 --- a/helm.sh/script/copy-source +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash - -set -e -set -x - -SOURCE=$1 -DEST=$2 - -rsync -a --stats ${SOURCE}/ ${DEST}/ \ - --exclude=.git \ - --exclude=_site \ - --exclude=rootfs \ - --exclude=node_modules \ - --exclude=.sass-cache \ No newline at end of file diff --git a/helm.sh/script/install b/helm.sh/script/install deleted file mode 100755 index 8a5297437e..0000000000 --- a/helm.sh/script/install +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash - -set -x -set -e - -npm install gulp -npm install -bundle install --deployment --path ${HOME}/_bundle diff --git a/helm.sh/script/link-dependencies b/helm.sh/script/link-dependencies deleted file mode 100755 index dc814f92fd..0000000000 --- a/helm.sh/script/link-dependencies +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash - -set -e -set -x - -cd /app -ln -sf ${HOME}/node_modules ./node_modules -ln -sf ${HOME}/sass-cache ./.sass-cache diff --git a/helm.sh/script/prep b/helm.sh/script/prep deleted file mode 100755 index 525e03f1cb..0000000000 --- a/helm.sh/script/prep +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash - -set -x -set -e - -build_dest=$1 - -# detect if we are running in Jenkins and fix-up the path -if [[ ! -z "${JENKINS_HOME}" ]]; then - if [[ ! -d ${build_dest} ]]; then - mkdir -p ${build_dest} - fi - chown -R ${USER}:${USER} ${build_dest} -fi diff --git a/helm.sh/script/serve b/helm.sh/script/serve deleted file mode 100755 index f077f26d9d..0000000000 --- a/helm.sh/script/serve +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash - -set -e -set -x - -cd /app/ - -/src/script/copy-source /src /app -/src/script/link-dependencies -/src/script/install - -bundle exec jekyll serve --host=0.0.0.0 diff --git a/i18n/de.toml b/i18n/de.toml new file mode 100644 index 0000000000..bcb7a94a8f --- /dev/null +++ b/i18n/de.toml @@ -0,0 +1,223 @@ +# site-wide copy + +## actions and labels +[action_get_started] +other = "Loslegen" + +[action_get_started_link] +other = "/de/docs/intro/quickstart" + +[action_translate] +other = "Diese Seite übersetzen" + +[action_translate_link] +other = "https://github.com/helm/helm-www#internationalization--translation" + +[action_copy] +other = "Kopieren" + +## site-wide banner about versioning +[banner_1] +other = "" + +## footer +[footer_support_title] +other = "Helm wird entwickelt und unterstützt von einer Gemeinschaft von über 400 Entwickler." + +[footer_support_subtitle] +other = "...und viele andere wundervolle [helm](https://github.com/helm/helm/blob/main/OWNERS) and [charts](https://github.com/helm/charts/blob/master/OWNERS) Hauptentwickler." + +[footer_cncf_status] +other = "Wir sind ein promoviertes Projekt der Cloud Native Computing Foundation." + +# homepage copy + +## homepage intro +[main_title] +other = "**Der** **Paket Manager** **für Kubernetes**" + +[main_subtitle] +other = "Helm ist der beste Weg, um erstellte Software für [Kubernetes](https://kubernetes.io) zu finden, teilen und benutzen." + +## homepage about helm +[main_what_is_helm_title] +other = "Was ist Helm?" + +[main_what_is_helm_description] +other = """ +Helm hilft bei der Verwaltung von Kubernetes Anwendungen — Helm Charts helfen, die kompliziertes Kubernetes Anwendungen zu definieren, installieren und aktualisieren. + +Charts sind einfach zu erstellen, versionieren, teilen und publizieren - fangen Sie an Charts zu erstellen und hören Sie auf, Software zu kopieren. + +Helm ist ein promoviertes Projekt der [CNCF](https://cncf.io) und wird verwaltet von der [Helm Gemeinschaft](https://github.com/helm/community). + +### Mehr lernen: + +* [Helm Architektur](/docs/topics/architecture/) +* [Schnellstarthandbuch](./docs/intro/quickstart/) +* [Video: An Introduction to Helm](https://www.youtube.com/watch?v=Zzwq9FmZdsU&t=2s) +""" + +[main_why_teams_love] +other = 'Warum Teams Helm ' + +[feature_01_title] +other = "Komplexität verwalten" + +[feature_01_desc] +other = "Charts beschreiben selbst die kompliziertesten Applikationen und stellen wiederholbare Installationsprozeduren mit einem Einzelpunkt der Autorität zur Verfügung." + +[feature_02_title] +other = "Einfache Aktualisierungen" + +[feature_02_desc] +other = "Nimmt den Schmerz von Updates mit In-Platz-Aktualisierungen und angepassten Hooks." + +[feature_03_title] +other = "Einfaches Teilen" + +[feature_03_desc] +other = "Charts können einfach versioniert, geteilt und in öffentlichen oder privaten Servern gespeichert werden." + +[feature_04_title] +other = "Zurückrollen" + +[feature_04_desc] +other = "Benutzen Sie `helm rollback` um einfach zu älteren Versionen einer Veröffentlichung zurückzurollen." + +## homepage get helm +[get_helm_title] +other = "Helm bekommen!" + +[get_helm_desc] +other = "Helm mit einem Paket Manager installieren oder [ein Binary herunterladen](https://github.com/helm/helm/releases/latest)." + +[get_helm_next] +other = "Einmal installiert, packen Sie das Helm Binary aus, fügen es Ihrem PATH zu und fertig ist es zur Benutzung! Überprüfen Sie [die Dokumentationen](./docs/intro/install/) für weitere [Installationen](./docs/intro/install/) und [Gebrauchsanweisungen](./docs/intro/using_helm/)." + +[get_charts_title] +other = "Charts bekommen" + +[get_charts_desc] +other = "Besuchen Sie [Artifact Hub](https://artifacthub.io) zur Erkundung von [Helm Charts](https://artifacthub.io/packages/search?kind=0) von zahlreichen öffentlichen Verzeichnissen." + +[get_upgrade_title] +other = "[Aktualisierung von v2 zu v3?](https://helm.sh/de/docs/topics/v2_v3_migration/)" + +[get_upgrade_desc] +other = "[Lesen Sie die Migrationsanleitung für mehr Details.](https://helm.sh/de/docs/topics/v2_v3_migration/)" + +## homepage community +[community_title] +other = "Der Gemeinschaft beitreten" + +[community_desc] +other = "Mehr Information über das Helm Project und wie beizutragen ist." + +[community_next_release] +other = "Nächstes Funktions-Release" + +[community_next_release_version] +other = "__Version:__ " + +[community_next_release_date] +other = "__Date:__ " + +[community_release_calendar] +other = "[Release Kalendar](https://helm.sh/calendar/release)" + +[community_events_title] +other = "Veranstaltungen" + +[community_upcoming_events_title] +other = "Kommende Veranstaltungen" + +[community_upcoming_events_desc] +other = "Beobachten Sie dieses Verzeichnis..." + +[community_past_events_title] +other = "Vergangene Veranstaltungen" + +[community_past_event_01] +other = "_Feb 25th 2020_ - [Helm Security Webinar](https://www.cncf.io/webinars/helm-security-a-look-below-deck/)" + +[community_past_event_02] +other = "_Nov 18th 2019_ - [KubeCon North America](https://events19.linuxfoundation.org/events/kubecon-cloudnativecon-north-america-2019/)" + +[community_past_event_03] +other = "_Sep 11th 2019_ - [Helm Summit 2019](https://events19.linuxfoundation.org/events/helm-summit-2019/)" + +[community_sig_title] +other = "SIG Apps" + +[community_sig_subtitle] +other = "A Special Interest Group for deploying and operating apps in Kubernetes." + +[community_sig_desc] +other = """ +[SIG-Apps](https://github.com/kubernetes/community/blob/master/sig-apps/README.md) is a Special Interest Group for deploying and operating apps in Kubernetes. + +They [meet each week](https://github.com/kubernetes/community/blob/master/sig-apps/README.md) to demo and discuss tools and projects. Community meetings are recorded and [shared to YouTube](https://www.youtube.com/results?search_query=kubernetes+sig+apps). +""" + +[community_standup_title] +other = "Developer Standups" + +[community_standup_time] +other = "Donnerstags 16:30-17:00 UTC" + +[community_standup_desc] +other = "Diese [Meetings](https://www.timeanddate.com/worldclock/fixedtime.html?hour=16&min=30&sec=0) sind offen für alle. Überprüfen Sie das [Gemeinschaftsverzeichnis](https://github.com/helm/community/blob/main/communication.md#meetings) für Notizen und Details." + +[community_slack_title] +other = "Slack" + +[community_slack_group_01_title] +other = "Helm Nutzer" + +[community_slack_group_01_desc] +other = "Diskussionen rund um Helm, arbeiten mit Charts und Fehler lösen." + +[community_slack_group_02_title] +other = "Helm Entwicklung" + +[community_slack_group_02_desc] +other = "Themen zur Helm Entwicklung, laufende PRs, Veröffentlichungen usw." + +[community_slack_group_03_title] +other = "Charts" + +[community_slack_group_03_desc] +other = "Diskussionen für Nutzer und Beitragende zu Helm Charts." + +[community_slack_join] +other = "[Zugriff hier erfragen](https://slack.k8s.io/)." + +[community_contrib_title] +other = "Beitragen" + +[community_contrib_subtitle] +other = "Helm heisst immer neue Beitragende zum Projekt willkommen!" + + +[community_contrib_desc] +other = """ +### Wo anfangen? + +Helm ist ein grosses Projekt mit einer Menge Nutzer und Beitragende. Es kann viel zu sehen geben! + +Wir haben eine Liste mit [guten ersten Problemen](https://github.com/helm/helm/issues?utf8=%E2%9C%93&q=is%3Aopen%20is%3Aissue%20label%3A%22good+first+issue%22), wenn Sie anfangen möchten zu helfen aber nicht wissen wo. + +### Was hab ich zu tun? + +Bevor Sie Code beisteuern, lesen Sie bitte den [Beitragungsleitfaden](https://github.com/helm/helm/blob/main/CONTRIBUTING.md). Er geht über den Prozess zum Erstellen und Überprüfen von Pull Requests. + +Immer wenn Sie Code beisteuern, [signieren Sie bitte Ihre Commits](https://helm.sh/blog/helm-dco/index.html), um sicherzustellen, dass Helm für die [DCO](https://developercertificate.org/) Vereinbarung benutzt von der [CNCF](https://www.cncf.io/) haftet. +""" + +# 404 page +[404_title] +other = "**404** **Seite nicht gefunden.**" + +[404_subtitle] +other = "Entschuldigung für die Unannehmlichkeiten. Wenn ein Link falsch ist, [melden Sie es bitte hier](https://github.com/helm/helm-www/issues/new)." diff --git a/i18n/en.toml b/i18n/en.toml new file mode 100644 index 0000000000..524533eabf --- /dev/null +++ b/i18n/en.toml @@ -0,0 +1,223 @@ +# site-wide copy + +## actions and labels +[action_get_started] +other = "Get Started" + +[action_get_started_link] +other = "/docs/intro/quickstart" + +[action_translate] +other = "Translate this page" + +[action_translate_link] +other = "https://github.com/helm/helm-www#internationalization--translation" + +[action_copy] +other = "Copy" + +## site-wide banner about versioning +[banner_1] +other = "" + +## footer +[footer_support_title] +other = "Helm is supported by and built with a community of over 400 developers." + +[footer_support_subtitle] +other = "...and many other wonderful [helm](https://github.com/helm/helm/blob/main/OWNERS) core maintainers." + +[footer_cncf_status] +other = "We are a Cloud Native Computing Foundation graduated project." + +# homepage copy + +## homepage intro +[main_title] +other = "**The** **package manager** **for Kubernetes**" + +[main_subtitle] +other = "Helm is the best way to find, share, and use software built for [Kubernetes](https://kubernetes.io)." + +## homepage about helm +[main_what_is_helm_title] +other = "What is Helm?" + +[main_what_is_helm_description] +other = """ +Helm helps you manage Kubernetes applications — Helm Charts help you define, install, and upgrade even the most complex Kubernetes application. + +Charts are easy to create, version, share, and publish — so start using Helm and stop the copy-and-paste. + +Helm is a graduated project in the [CNCF](https://cncf.io) and is maintained by the [Helm community](https://github.com/helm/community). + +### Learn more: + +* [Helm Architecture](./docs/topics/architecture/) +* [Quick Start Guide](./docs/intro/quickstart/) +* [Video: An Introduction to Helm](https://www.youtube.com/watch?v=Zzwq9FmZdsU&t=2s) +""" + +[main_why_teams_love] +other = 'Why Teams Helm' + +[feature_01_title] +other = "Manage Complexity" + +[feature_01_desc] +other = "Charts describe even the most complex apps, provide repeatable application installation, and serve as a single point of authority." + +[feature_02_title] +other = "Easy Updates" + +[feature_02_desc] +other = "Take the pain out of updates with in-place upgrades and custom hooks." + +[feature_03_title] +other = "Simple Sharing" + +[feature_03_desc] +other = "Charts are easy to version, share, and host on public or private servers." + +[feature_04_title] +other = "Rollbacks" + +[feature_04_desc] +other = "Use `helm rollback` to roll back to an older version of a release with ease." + +## homepage get helm +[get_helm_title] +other = "Get Helm!" + +[get_helm_desc] +other = "Install Helm with a package manager, or [download a binary](https://github.com/helm/helm/releases/latest)." + +[get_helm_next] +other = "Once installed, unpack the helm binary and add it to your PATH and you are good to go! Check the [docs](./docs/intro/install/) for further [installation](./docs/intro/install/) and [usage instructions](./docs/intro/using_helm/)." + +[get_charts_title] +other = "Get Charts" + +[get_charts_desc] +other = "Visit [Artifact Hub](https://artifacthub.io) to explore [Helm charts](https://artifacthub.io/packages/search?kind=0) from numerous public repositories." + +[get_upgrade_title] +other = "[Upgrading from v2 to v3?](https://helm.sh/docs/topics/v2_v3_migration/)" + +[get_upgrade_desc] +other = "[Read the migration doc for more details.](https://helm.sh/docs/topics/v2_v3_migration/)" + +## homepage community +[community_title] +other = "Join the Community" + +[community_desc] +other = "More information about the Helm project, and how to contribute." + +[community_next_release] +other = "Next Feature Release" + +[community_next_release_version] +other = "__Version:__ " + +[community_next_release_date] +other = "__Date:__ " + +[community_release_calendar] +other = "[Release Calendar](https://helm.sh/calendar/release)" + +[community_events_title] +other = "Events" + +[community_upcoming_events_title] +other = "Upcoming Events" + +[community_upcoming_events_desc] +other = "Watch this space..." + +[community_past_events_title] +other = "Past Events" + +[community_past_event_01] +other = "_Feb 25th 2020_ - [Helm Security Webinar](https://www.cncf.io/webinars/helm-security-a-look-below-deck/)" + +[community_past_event_02] +other = "_Nov 18th 2019_ - [KubeCon North America](https://events19.linuxfoundation.org/events/kubecon-cloudnativecon-north-america-2019/)" + +[community_past_event_03] +other = "_Sep 11th 2019_ - [Helm Summit 2019](https://events19.linuxfoundation.org/events/helm-summit-2019/)" + +[community_sig_title] +other = "SIG Apps" + +[community_sig_subtitle] +other = "A Special Interest Group for deploying and operating apps in Kubernetes." + +[community_sig_desc] +other = """ +[SIG-Apps](https://github.com/kubernetes/community/blob/master/sig-apps/README.md) is a Special Interest Group for deploying and operating apps in Kubernetes. + +They [meet each week](https://github.com/kubernetes/community/blob/master/sig-apps/README.md) to demo and discuss tools and projects. Community meetings are recorded and [shared to YouTube](https://www.youtube.com/results?search_query=kubernetes+sig+apps). +""" + +[community_standup_title] +other = "Developer Standups" + +[community_standup_time] +other = "Thursdays 9:30-10am (PT)" + +[community_standup_desc] +other = "These meetings are open to all. Check the [community repo](https://github.com/helm/community/blob/main/communication.md#meetings) for notes and details." + +[community_slack_title] +other = "Slack" + +[community_slack_group_01_title] +other = "Helm Users" + +[community_slack_group_01_desc] +other = "Discussion around using Helm, working with charts and solving common errors." + +[community_slack_group_02_title] +other = "Helm Development" + +[community_slack_group_02_desc] +other = "Topics regarding Helm development, ongoing PRs, releases, etc." + +[community_slack_group_03_title] +other = "Charts" + +[community_slack_group_03_desc] +other = "Discussion for users and contributors to Helm Charts." + +[community_slack_join] +other = "[Request access here](https://slack.k8s.io/) to join the Kubernetes Slack team." + +[community_contrib_title] +other = "Contributing" + +[community_contrib_subtitle] +other = "Helm always welcomes new contributions to the project!" + + +[community_contrib_desc] +other = """ +### Where to begin? + +Helm is a big project with a lot of users and contributors. It can be a lot to take in! + +We have a list of [good first issues](https://github.com/helm/helm/issues?utf8=%E2%9C%93&q=is%3Aopen%20is%3Aissue%20label%3A%22good+first+issue%22) if you want to help but don't know where to start. + +### What do I do? + +Before you contribute some code, please read our [Contribution Guide](https://github.com/helm/helm/blob/main/CONTRIBUTING.md). It goes over the processes around creating and reviewing pull requests. + +Once you write some code, please [sign your commits](https://helm.sh/blog/helm-dco/index.html) to ensure Helm adheres to the [DCO](https://developercertificate.org/) agreement used by the [CNCF](https://www.cncf.io/). +""" + +# 404 page +[404_title] +other = "**404** **Page not found.**" + +[404_subtitle] +other = "Sorry about that. If something is broken please [report it here](https://github.com/helm/helm-www/issues/new)." diff --git a/i18n/es.toml b/i18n/es.toml new file mode 100644 index 0000000000..f7212e97e1 --- /dev/null +++ b/i18n/es.toml @@ -0,0 +1,223 @@ +# site-wide copy + +## actions and labels +[action_get_started] +other = "Empieza" + +[action_get_started_link] +other = "/es/docs/intro/quickstart" + +[action_translate] +other = "Traduzca esta pagina" + +[action_translate_link] +other = "https://github.com/helm/helm-www#internationalization--translation" + +[action_copy] +other = "Copiar" + +## site-wide banner about versioning +[banner_1] +other = "" + +## footer +[footer_support_title] +other = "Helm cuenta con el apoyo y es construido por una comunidad de más de 400 desarrolladores." + +[footer_support_subtitle] +other = "...y muchos otros maravilloso martenedores principales de [helm](https://github.com/helm/helm/blob/main/OWNERS) y [charts](https://github.com/helm/charts/blob/master/OWNERS)." + +[footer_cncf_status] +other = "Somos un proyecto graduado de Cloud Native Computing Foundation." + +# homepage copy + +## homepage intro +[main_title] +other = "**El** **administrador de paquetes** **para Kubernetes**" + +[main_subtitle] +other = "Helm es la mejor manera de buscar, compartir y utilizar software creado para [Kubernetes](https://kubernetes.io)." + +## homepage about helm +[main_what_is_helm_title] +other = "¿Qué es Helm?" + +[main_what_is_helm_description] +other = """ +Helm te ayuda a administrar las aplicaciones de Kubernetes - Los Charts de Helm te ayudan a definir, instalar y actualizar incluso la aplicación de Kubernetes más compleja. + +Los Charts son fáciles de crear, versionar, compartir y publicar - así que comienza a utilizar Helm y deja de copiar y pegar. + +Helm es proyecto graduado de la [CNCF](https://cncf.io) y es mantenido por [Comunidad de Helm](https://github.com/helm/community). + +### Aprende más: + +* [Arquitectura de Helm](/docs/topics/architecture/) +* [Guía de inicio rápido](./docs/intro/quickstart/) +* [Video: Una introducción a Helm](https://www.youtube.com/watch?v=Zzwq9FmZdsU&t=2s) +""" + +[main_why_teams_love] +other = '¿Por qué los Equipos Helm' + +[feature_01_title] +other = "Administra la Complejidad" + +[feature_01_desc] +other = "Los Charts describen incluso las aplicaciones más complejas, proporcionan una instalación de aplicaciones repetible y sirven como un único punto de autoridad." + +[feature_02_title] +other = "Actualizaciones Fáciles" + +[feature_02_desc] +other = "Elimine el dolor de las actualizaciones con actualizaciones in situ y ganchos personalizados." + +[feature_03_title] +other = "Uso Compartido Simple" + +[feature_03_desc] +other = "Los Charts son fáciles de versionar, compartir y servir en servidores públicos o privados." + +[feature_04_title] +other = "Retrocesos" + +[feature_04_desc] +other = "Utiliza `helm rollback` to retroceder con facilidad a una versión anterior de un lanzamiento." + +## homepage get helm +[get_helm_title] +other = "Obtener Helm!" + +[get_helm_desc] +other = "Instalar Helm con un administrador de paquetes, o [descargar un binario](https://github.com/helm/helm/releases/latest)." + +[get_helm_next] +other = "Una vez instalado, descomprima el binario de helm y agréguelo a su PATH y ¡listo! Consulte los [docs](./docs/intro/install/) para obtener más información sobre [instalación](./docs/intro/install/) e [instrucciones de uso](./docs/intro/using_helm/)." + +[get_charts_title] +other = "Obtener Charts" + +[get_charts_desc] +other = "Visita [Artifact Hub](https://artifacthub.io) para explorar [Helm charts](https://artifacthub.io/packages/search?kind=0) desde numerosos repositorios públicos." + +[get_upgrade_title] +other = "[Actualizar desde v2 a v3?](https://helm.sh/docs/topics/v2_v3_migration/)" + +[get_upgrade_desc] +other = "[Lea el documento de migración para obtener más detalles.](https://helm.sh/docs/topics/v2_v3_migration/)" + +## homepage community +[community_title] +other = "Unete a la communidad" + +[community_desc] +other = "Más información sobre el proyecto Helm y cómo contribuir." + +[community_next_release] +other = "Próxima Liberación de Características" + +[community_next_release_version] +other = "__Versión:__ " + +[community_next_release_date] +other = "__Fecha:__ " + +[community_release_calendar] +other = "[Calendario de Lanzamiento](https://helm.sh/calendar/release)" + +[community_events_title] +other = "Eventos" + +[community_upcoming_events_title] +other = "Próximos Eventos" + +[community_upcoming_events_desc] +other = "Watch this space..." + +[community_past_events_title] +other = "Eventos Pasados" + +[community_past_event_01] +other = "_Feb 25th 2020_ - [Helm Security Webinar](https://www.cncf.io/webinars/helm-security-a-look-below-deck/)" + +[community_past_event_02] +other = "_Nov 18th 2019_ - [KubeCon North America](https://events19.linuxfoundation.org/events/kubecon-cloudnativecon-north-america-2019/)" + +[community_past_event_03] +other = "_Sep 11th 2019_ - [Helm Summit 2019](https://events19.linuxfoundation.org/events/helm-summit-2019/)" + +[community_sig_title] +other = "SIG Apps" + +[community_sig_subtitle] +other = "Un Grupo de Interés Especial (SIG) para implementar y operar aplicaciones en Kubernetes." + +[community_sig_desc] +other = """ +[SIG-Apps](https://github.com/kubernetes/community/blob/master/sig-apps/README.md) es Grupo de Interés Especial (SIG) para implementar y operar aplicaciones en Kubernetes. + +Ellos [se reúnen cada semana](https://github.com/kubernetes/community/blob/master/sig-apps/README.md) para hacer demostraciones y discutir herramientas y proyectos. Las reuniones de la comunidad se graban y [se comparten en YouTube](https://www.youtube.com/results?search_query=kubernetes+sig+apps). +""" + +[community_standup_title] +other = "Standups para desarrolladores" + +[community_standup_time] +other = "Jueves 9:30-10am (PT)" + +[community_standup_desc] +other = "Estas reuniones están abiertas a todos. Consulta el [repositorio de la comunidad](https://github.com/helm/community/blob/main/communication.md#meetings) para notas y detalles." + +[community_slack_title] +other = "Slack" + +[community_slack_group_01_title] +other = "Usuarios de Helm" + +[community_slack_group_01_desc] +other = "Discusión sobre el uso de Helm, el trabajo con Charts y la resolución de errores comunes." + +[community_slack_group_02_title] +other = "Desarrollo de Helm" + +[community_slack_group_02_desc] +other = "Temas relacionados con el desarrollo de Helm, PR en curso, lanzamientos, etc." + +[community_slack_group_03_title] +other = "Charts" + +[community_slack_group_03_desc] +other = "Discusión para usuarios y colaboradores de Helm Charts." + +[community_slack_join] +other = "[Solicita acceso aquí](https://slack.k8s.io/) para unirse al equipo de Kubernetes Slack." + +[community_contrib_title] +other = "Contribuyendo" + +[community_contrib_subtitle] +other = "¡Helm siempre da la bienvenida a nuevas contribuciones al proyecto!" + + +[community_contrib_desc] +other = """ +### ¿Dónde empezar? + +Helm es un gran proyecto con muchos usuarios y colaboradores. ¡Puede ser mucho para asimilar! + +Tenemos una lista de [buenos primeros tickets](https://github.com/helm/helm/issues?utf8=%E2%9C%93&q=is%3Aopen%20is%3Aissue%20label%3A%22good+first+issue%22) si desea ayudar pero no sabe por dónde empezar. + +### ¿Qué debo hacer? + +Antes de contribuir con algún código, lee nuestra [Guía de Contribución](https://github.com/helm/helm/blob/main/CONTRIBUTING.md). Repasa los procesos relacionados con la creación y revisión de pull-requests. + +Una vez que escribas código, [firme tus commits](https://helm.sh/blog/helm-dco/index.html) para garantizar que Helm se adhiera al convenio [DCO](https://developercertificate.org/) utilizado por la [CNCF](https://www.cncf.io/). +""" + +# 404 page +[404_title] +other = "**404** **Página no encontrada.**" + +[404_subtitle] +other = "Lo sientimos por eso. Si algo está roto, [infórmalo aquí](https://github.com/helm/helm-www/issues/new)." diff --git a/i18n/fr.toml b/i18n/fr.toml new file mode 100644 index 0000000000..90c712855a --- /dev/null +++ b/i18n/fr.toml @@ -0,0 +1,223 @@ +# site-wide copy + +## actions and labels +[action_get_started] +other = "Commencer" + +[action_get_started_link] +other = "/fr/docs/intro/quickstart" + +[action_translate] +other = "Traduire cette page" + +[action_translate_link] +other = "https://github.com/helm/helm-www#internationalization--translation" + +[action_copy] +other = "Copier" + +## site-wide banner about versioning +[banner_1] +other = "" + +## footer +[footer_support_title] +other = "Helm est supporté et construit grâce à une communauté de plus de 400 développeurs." + +[footer_support_subtitle] +other = "...et bien d'autre responsables géniaux de la mise à jour de [helm](https://github.com/helm/helm/blob/main/OWNERS) et des [charts](https://github.com/helm/charts/blob/master/OWNERS)." + +[footer_cncf_status] +other = "Nous sommes un projet diplômé de la Cloud Native Computing Foundation." + +# homepage copy + +## homepage intro +[main_title] +other = "**Le** **gestionnaire de paquets** **pour Kubernetes**" + +[main_subtitle] +other = "Helm est le meilleur outils pour trouver, partager et utiliser des logiciels fait pour [Kubernetes](https://kubernetes.io)." + +## homepage about helm +[main_what_is_helm_title] +other = "Qu'est ce que Helm ?" + +[main_what_is_helm_description] +other = """ +Helm vous aide a gérer vos applications Kubernetes — Les Charts de Helm peuvent même vous aider à définir, installer et mettre à jour les architectures Kubernetes les plus complexes. + +Les Charts de Helm sont faciles à créer, versionner et partager — Alors commencer à utiliser Helm et arrêter de faire du copier-coller ! + +Helm est un projet diplômé de la [CNCF](https://cncf.io) et est maintenu par la [communauté de Helm](https://github.com/helm/community). + +### Pour aller plus loin: + +* [Architecture de Helm](/docs/topics/architecture/) +* [Guide pour débutant](./docs/intro/quickstart/) +* [Video: Une introduction à Helm (Anglais)](https://www.youtube.com/watch?v=Zzwq9FmZdsU&t=2s) +""" + +[main_why_teams_love] +other = 'Pourquoi Teams Helm' + +[feature_01_title] +other = "Gérer la complexité" + +[feature_01_desc] +other = "Les Charts décrivent même les applications les plus complexes, fournissent une installation d'application répétable et servent de point d'autorité unique." + +[feature_02_title] +other = "Mises à jours faciles" + +[feature_02_desc] +other = "Simplifiez les mises à jour avec des mises à niveau sur place et des crochets personnalisés." + +[feature_03_title] +other = "Partage simple" + +[feature_03_desc] +other = "Les Charts sont faciles à versionner, partager et héberger sur des serveurs publique ou privé." + +[feature_04_title] +other = "Retour en arrière" + +[feature_04_desc] +other = "Utilisez `helm rollback` pour revenir facilement à une ancienne version d'une release." + +## homepage get helm +[get_helm_title] +other = "Télécharger Helm !" + +[get_helm_desc] +other = "Installez Helm avec un manageur de paquets, ou [téléchargez un binaire](https://github.com/helm/helm/releases/latest)." + +[get_helm_next] +other = "Une fois installé, décompressez le binaire de Helm et ajoutez le dans votre variable PATH et vous serez prêt ! Jetez un oeil aux [docs](./docs/intro/install/) pour plus d'information sur [l'installation](./docs/intro/install/) et [les instructions d'usage](./docs/intro/using_helm/)." + +[get_charts_title] +other = "Télécharger des Charts" + +[get_charts_desc] +other = "Visitez le [Artifact Hub](https://artifacthub.io) afin de trouver vos [charts Helm](https://artifacthub.io/packages/search?kind=0) à partir de nombreux répertoires publique." + +[get_upgrade_title] +other = "[Passage de v2 à v3 de Kubernetes](https://helm.sh/docs/topics/v2_v3_migration/)" + +[get_upgrade_desc] +other = "[Lisez la documentation de migration pour plus de détails.](https://helm.sh/docs/topics/v2_v3_migration/)" + +## homepage community +[community_title] +other = "Rejoignez la communauté !" + +[community_desc] +other = "Plus d'informations sur le projet Helm et comment y contribuer." + +[community_next_release] +other = "Prochaine Feature Release" + +[community_next_release_version] +other = "__Version:__ " + +[community_next_release_date] +other = "__Date:__ " + +[community_release_calendar] +other = "[Calendrier des Release](https://helm.sh/calendar/release)" + +[community_events_title] +other = "Evenements" + +[community_upcoming_events_title] +other = "Evenements à venir" + +[community_upcoming_events_desc] +other = "Regardez ici..." + +[community_past_events_title] +other = "Evenements passés" + +[community_past_event_01] +other = "_25 Fevrier 2020_ - [Helm Security Webinar](https://www.cncf.io/webinars/helm-security-a-look-below-deck/)" + +[community_past_event_02] +other = "_18 Novembre 2019_ - [KubeCon North America](https://events19.linuxfoundation.org/events/kubecon-cloudnativecon-north-america-2019/)" + +[community_past_event_03] +other = "_11 Septembre 2019_ - [Helm Summit 2019](https://events19.linuxfoundation.org/events/helm-summit-2019/)" + +[community_sig_title] +other = "Applications SIG" + +[community_sig_subtitle] +other = "Un pôle d'intérêt commun SIG (Special Interest Group) pour le déployement et l'exploitation d'applications dans Kubernetes." + +[community_sig_desc] +other = """ +[SIG-Apps](https://github.com/kubernetes/community/blob/master/sig-apps/README.md) est un pôle d'intérêt commun pour le déploiement et l'exploitation d'applications dans Kubernetes. + +Ils se [rencontrent chaque semaines](https://github.com/kubernetes/community/blob/master/sig-apps/README.md) pour montrer et discuter l'avancement des outils et du projet. Les rencontrent communautaires sont enregistrés et [partagés sur Youtube](https://www.youtube.com/results?search_query=kubernetes+sig+apps). +""" + +[community_standup_title] +other = "Rencontres Développeur" + +[community_standup_time] +other = "Le Jeudi de 9h30 à 10h (PT)" + +[community_standup_desc] +other = "Ces rencontres sont ouvertes à tous. Visitez le [répo communautaire](https://github.com/helm/community/blob/main/communication.md#meetings) pour plus de détails." + +[community_slack_title] +other = "Slack" + +[community_slack_group_01_title] +other = "Utilisateurs de Helm" + +[community_slack_group_01_desc] +other = "Discutez de Helm, travaillez avec des charts et résolvez vos erreurs." + +[community_slack_group_02_title] +other = "Développement de Helm" + +[community_slack_group_02_desc] +other = "Sujets concernant le développement de Helm, Pull Request en cours, releases, etc." + +[community_slack_group_03_title] +other = "Charts" + +[community_slack_group_03_desc] +other = "Discussions pour les utilisateurs et les contributeurs de Charts Helm." + +[community_slack_join] +other = "[Faites une demande ici](https://slack.k8s.io/) pour rejoindre l'équipe Slack de Kubernetes" + +[community_contrib_title] +other = "Contribuer" + +[community_contrib_subtitle] +other = "Helm accueil toujours les contributeurs avec plaisir !" + + +[community_contrib_desc] +other = """ +### Où commencer ? + +Helm est un gros projet avec de nombreux utilisateurs et contributeurs. Cela peut prendre du temps à prendre en main ! + +Nous avons une liste de [problème non résolus](https://github.com/helm/helm/issues?utf8=%E2%9C%93&q=is%3Aopen%20is%3Aissue%20label%3A%22good+first+issue%22) si vous voulez aider mais ne savez pas par où commencer. + +### Comment faire ? + +Avant de contribuer au code, merci de lire le [Guide de Contribution](https://github.com/helm/helm/blob/main/CONTRIBUTING.md). Il vous guidera à travers le processus de création et de revue des pulls requests. + +Une fois que vous aurez écrit du code, merci de [signer vos commits](https://helm.sh/blog/helm-dco/index.html) afin de s'assurer que Helm adhère à l'accord [DCO](https://developercertificate.org/) utilisé par la [CNCF](https://www.cncf.io/). +""" + +# 404 page +[404_title] +other = "**404** **Page introuvable.**" + +[404_subtitle] +other = "Désolé pour ce soucis. Si quelque chose ne fonctionne pas merci de faire un [rapport ici](https://github.com/helm/helm-www/issues/new)." diff --git a/i18n/gr.toml b/i18n/gr.toml new file mode 100644 index 0000000000..de594ee922 --- /dev/null +++ b/i18n/gr.toml @@ -0,0 +1,222 @@ +# site-wide copy + +## actions and labels +[action_get_started] +other = "Ξεκίνα" +[action_get_started_link] +other = "/docs/intro/quickstart" + +[action_translate] +other = "Μετάφρασε αυτή την σελίδα" + +[action_translate_link] +other = "https://github.com/helm/helm-www#internationalization--translation" + +[action_copy] +other = "Αντιγραφή" + +## site-wide banner about versioning +[banner_1] +other = "" + +## footer +[footer_support_title] +other = "Το Helm υποστηρίζεται και είναι κατασκευασμένο από μια κοινότητα από παραπάνω από 400 developers." + +[footer_support_subtitle] +other = "...and πολλούς/ες υπέροχους/ες core maintainers του [helm](https://github.com/helm/helm/blob/main/OWNERS) και των [charts](https://github.com/helm/charts/blob/master/OWNERS)." + +[footer_cncf_status] +other = "Είμαστε ένα graduated project του Cloud Native Computing Foundation." + +# homepage copy + +## homepage intro +[main_title] +other = "**Ο** **package manager** **του Kubernetes**" + +[main_subtitle] +other = "Το Helm είναι ο καλύτερος τρόπος να βρείς, να μοιραστείς και να χρησιμοποιήσεις λογισμικό το οποίο έχει κατασκευαστεί για το [Kubernetes](https://kubernetes.io)." + +## homepage about helm +[main_what_is_helm_title] +other = "Τι είναι το Helm;" + +[main_what_is_helm_description] +other = """ +Το Helm σε βοηθάει να διαχειριστείς εφαρμογές του Kubernetes — Τα Helm Charts σε βοηθάνε να ορίσεις, να εγκαταστήσεις, και να αναβαθμίσεις ακόμα και τις πιο περίπλοκες εφαρμογές του Kubernetes. + +Τα charts ( χαρτογραφήσεις ) μπορούν εύκολα να δημιουργηθούν, να αποκτήσουν εκδόσεις, να διαμοιραστούν, και να γίνουν κοινόχρηστα. — οπότε ξεκίνα να χρησιμοποιείς το Helm και σταμάτα την αντιγραφή-επικόλληση. + +Το Helm είναι ένα graduated project στο [CNCF](https://cncf.io) και συντηρείται από την [Κοινότητα του Helm](https://github.com/helm/community). + +### Μάθε περισσότερα: + +* [Αρχιτεκτονική του Helm](/docs/topics/architecture/) +* [Οδηγός για να Ξεκινήσεις Γρήγορα](/docs/intro/quickstart/) +* [Video: Μια εισαγωγή στο Helm](https://www.youtube.com/watch?v=Zzwq9FmZdsU&t=2s) +""" + +[main_why_teams_love] +other = 'Γιατί οι Ομάδες το Helm' + +[feature_01_title] +other = "Διαχειρίσου την Περιπλοκότητα" + +[feature_01_desc] +other = "Τα charts ( χαρτογραφήσεις ) περιγράφουν ακόμα και τις πιο σύνθετες εφαρμογές, παρέχουν εγκατάσταση των εφαρμογών η οποία εύκολα επαναλαμβάνεται, και λειτουργούν ως ένα κεντρικό σημείο ελέγχου." + +[feature_02_title] +other = "Εύκολα Updates" + +[feature_02_desc] +other = "Κάνε πιο εύκολα τα updates με upgrades επιτόπου και custom hooks." + +[feature_03_title] +other = "Μοιράσου Εύκολα" + +[feature_03_desc] +other = "Τα charts είναι εύκολο να αποκτήσουν εκδόσεις, να διαμοιραστούν, και να φιλοξενηθούν σε κοινόχρηστους και μη-κοινόχρηστους servers." + +[feature_04_title] +other = "Rollbacks" + +[feature_04_desc] +other = "Χρησιμοποίησε το `helm rollback` για να πας εύκολα πίσω σε ένα παλιότερο release." + +## homepage get helm +[get_helm_title] +other = "Κατέβασε το Helm!" + +[get_helm_desc] +other = "Εγκατέστησε το Helm μέσω ενός package manager, ή [κατέβασε το binary](https://github.com/helm/helm/releases/latest)." + +[get_helm_next] +other = "Μόλις εγκατασταθεί, κάνε unpack το helm binary και προσθεσέ το στο PATH και είσαι έτοιμος/η! Έλεγξε τα [docs](/docs/intro/install/) για περισσότερες πληροφορίες για την [εγκατάσταση](/docs/intro/install/) και τις [οδηγίες χρήσης](/docs/intro/using_helm/)." + +[get_charts_title] +other = "Κατέβασε Charts" + +[get_charts_desc] +other = "Επισκέψου το [Artifact Hub](https://artifacthub.io) και εξερεύνησε τα [Helm charts](https://artifacthub.io/packages/search?kind=0) από μία μεγάλη συλλογή κοινόχρηστων repositories." + +[get_upgrade_title] +other = "[Κάνεις upgrade από το v2 στο v3?](https://helm.sh/docs/topics/v2_v3_migration/)" + +[get_upgrade_desc] +other = "[Διάβασε τα κείμενα για το migration για περισσότερες λεπτομέρειες.](https://helm.sh/docs/topics/v2_v3_migration/)" + +## homepage community +[community_title] +other = "Μπες στην κοινότητα" + +[community_desc] +other = "Περισσότερες πληροφορίες για το Helm project, και πως να συνεισφέρεις." + +[community_next_release] +other = "Επόμενο Feature Release" + +[community_next_release_version] +other = "__Έκδοση:__ " + +[community_next_release_date] +other = "__Ημερομηνία:__ " + +[community_release_calendar] +other = "[Ημερολόγιο για τα Release](https://helm.sh/calendar/release)" + +[community_events_title] +other = "Events" + +[community_upcoming_events_title] +other = "Επερχόμενα Events" + +[community_upcoming_events_desc] +other = "Έχε τον νου σου εδώ πέρα..." + +[community_past_events_title] +other = "Παλιά Events" + +[community_past_event_01] +other = "_25 Φεβ 2020_ - [Webinar για την ασφάλεια στο Helm](https://www.cncf.io/webinars/helm-security-a-look-below-deck/)" + +[community_past_event_02] +other = "_18 Νοε 2019_ - [KubeCon North America](https://events19.linuxfoundation.org/events/kubecon-cloudnativecon-north-america-2019/)" + +[community_past_event_03] +other = "_11 Σεπ 2019_ - [Helm Summit 2019](https://events19.linuxfoundation.org/events/helm-summit-2019/)" + +[community_sig_title] +other = "SIG Apps" + +[community_sig_subtitle] +other = "Ένα Special Interest Group (Ομάδα ειδικού Ενδιαφέροντος) για το deploy και την λειτουργία εφαρμογών Kubernetes." + +[community_sig_desc] +other = """ +To [SIG-Apps](https://github.com/kubernetes/community/blob/master/sig-apps/README.md) είναι ένα Special Interest Group ( Ομάδα Ειδικού Ενδιαφέροντος ) για το deploy και την λειτουργία εφαρμογών στο Kubernetes. + +Τα SIG [συναντιούνται κάθε εβδομάδα](https://github.com/kubernetes/community/blob/master/sig-apps/README.md) για να δείξουν demo και να συζητήσουν για εργαλεία και projects. Οι συναντήσεις της κοινότητας καταγράφονται και [κοινοποιούνται στο YouTube](https://www.youtube.com/results?search_query=kubernetes+sig+apps). +""" + +[community_standup_title] +other = "Developer Standups" + +[community_standup_time] +other = "Πέμπτες 9:30-10am (PT)" + +[community_standup_desc] +other = "Αυτές οι συναντήσεις είναι ανοιχτές σε όλους/όλες. Ελέγξτε το [community repo](https://github.com/helm/community/blob/main/communication.md#meetings) για σημειώσεις και λεπτομέρειες." + +[community_slack_title] +other = "Slack" + +[community_slack_group_01_title] +other = "Helm Users" + +[community_slack_group_01_desc] +other = "Συζήτηση γύρω από την χρήση του Helm, πως δουλεύουμε με τα charts και επίλυση κοινών σφαλμάτων." + +[community_slack_group_02_title] +other = "Helm Development" + +[community_slack_group_02_desc] +other = "Θέματα σχετικά με την ανάπτυξη του Helm, τρέχοντα PRs, releases, κλπ." + +[community_slack_group_03_title] +other = "Charts" + +[community_slack_group_03_desc] +other = "Συζήτηση για χρήστες και contributors των Helm Charts." + +[community_slack_join] +other = "[Ζήτησε πρόσβαση εδώ](https://slack.k8s.io/) για να συμμετέχες στην ομάδα του Kubernetes στο Slack." + +[community_contrib_title] +other = "Συνεισφορά" + +[community_contrib_subtitle] +other = "Το Helm πάντα καλωσορίζει νέες συνεισφορές στο project!" + + +[community_contrib_desc] +other = """ +### Από που να ξεκινήσω; + +Το Helm είναι ένα μεγάλο project με πολλούς χρήστες και contributors. Έχεις πολλά να μάθεις! + +Έχουμε μια λίστα από [καλά αρχικά issues](https://github.com/helm/helm/issues?utf8=%E2%9C%93&q=is%3Aopen%20is%3Aissue%20label%3A%22good+first+issue%22) αν θες να βοηθήσεις και δεν ξέρεις από που να ξεκινήσεις. + +### Τι κάνω; + +Πριν συνεισφέρεις τον κώδικά σου, παρακαλούμε διάβασε τον [Οδηγό Συνεισφοράς](https://github.com/helm/helm/blob/main/CONTRIBUTING.md). Αναλύει τις διαδικασίες γύρω από την δημιουργία και το reviewing των pull requests. + +Μόλις γράψεις λίγο κώδικα, παρακαλούμε [υπόγραψε τα commits σου](https://helm.sh/blog/helm-dco/index.html) για να διασφαλιστεί ότι το Helm συμβαδίζει με την συμφωνία [DCO](https://developercertificate.org/) η οποία χρησιμοποιείται από το [CNCF](https://www.cncf.io/). +""" + +# 404 page +[404_title] +other = "**404** **Δεν βρέθηκε η σελίδα.**" + +[404_subtitle] +other = "Συγγνώμη γι αυτό. Αν κάτι έχει σπάσει παρακαλούμε [ανάφερέ το εδώ](https://github.com/helm/helm-www/issues/new)." diff --git a/i18n/ja.toml b/i18n/ja.toml new file mode 100644 index 0000000000..a9d5fe079e --- /dev/null +++ b/i18n/ja.toml @@ -0,0 +1,211 @@ +# site-wide copy + +## actions and labels +[action_get_started] +other = "始めましょう" + +[action_get_started_link] +other = "/ja/docs/intro/quickstart" + +[action_translate] +other = "このページを翻訳" + +[action_translate_link] +other = "https://github.com/helm/helm-www#internationalization--translation" + +[action_copy] +other = "コピー" + +## site-wide banner about versioning +[banner_1] +other = "" + +## footer +[footer_support_title] +other = "Helm は、400人を超える開発者のコミュニティによってサポートされ、構築されています。" + +[footer_support_subtitle] +other = "...そして他の多くの素晴らしい [helm](https://github.com/helm/helm/blob/main/OWNERS) と [charts](https://github.com/helm/charts/blob/master/OWNERS) コアメンテナー。" + +[footer_cncf_status] +other = "私たちは Cloud Native Computing Foundation の Graduated プロジェクトです。" + +# homepage copy + +## homepage intro +[main_title] +other = "**Kubernetes 用** **パッケージマネージャー**" + +[main_subtitle] +other = "Helm は、[Kubernetes](https://kubernetes.io) 用に構築されたソフトウェアを検索、共有、使用するための最良の方法です。" + +## homepage about helm +[main_what_is_helm_title] +other = "Helm とは何ですか?" + +[main_what_is_helm_description] +other = """ +Helm は、Kubernetes アプリケーションの管理を支援します。Helm チャートは、最も複雑な Kubernetes アプリケーションの定義、インストール、およびアップグレードを支援します。 + +チャートは簡単に作成、バージョン管理、共有、公開できるので、Helm の使用を開始し、コピー & ペーストはやめましょう。 + +Helm は [CNCF](https://cncf.io) の Graduated プロジェクトであり、[Helm コミュニティ](https://github.com/helm/community)によって管理されています。 + +### Learn more: + +* [Helm アーキテクチャ](./docs/topics/architecture/) +* [クイックスタートガイド](./docs/intro/quickstart/) +* [ビデオ: Helm の概要](https://www.youtube.com/watch?v=Zzwq9FmZdsU&t=2s) +""" + +[main_why_teams_love] +other = 'Why Teams Helm' + +[feature_01_title] +other = "複雑さを管理する" + +[feature_01_desc] +other = "チャートは最も複雑なアプリについても説明し、繰り返し可能なアプリケーションのインストールを提供し、単一の権限ポイントとして機能します。" + +[feature_02_title] +other = "簡単なアップデート" + +[feature_02_desc] +other = "in-place アップグレードとカスタムフックを使用して、更新の手間を省きます。" + +[feature_03_title] +other = "簡単な共有" + +[feature_03_desc] +other = "チャートは、バージョン管理、共有、パブリックサーバーまたはプライベートサーバーでのホストが簡単です。" + +[feature_04_title] +other = "ロールバック" + +[feature_04_desc] +other = "`helm rollback` を使用すると、リリースの古いバージョンに簡単にロールバックできます。" + +## homepage get helm +[get_helm_title] +other = "ヘルムを入手!" + +[get_helm_desc] +other = "Helm をパッケージマネージャーでインストールするか、[バイナリをダウンロード](https://github.com/helm/helm/releases/latest)します。" + +[get_helm_next] +other = "インストールしたら、helm バイナリを解凍して PATH に追加すれば準備完了です。[インストール](./docs/intro/install/)と[使用手順](./docs/intro/using_helm/)については、[docs](./docs/intro/install/) を確認してください。" + +[get_charts_title] +other = "チャートを取得" + +[get_charts_desc] +other = "[Helm Hub](https://hub.helm.sh) にアクセスして、多くの公開 Helm リポジトリからチャートを探索してください。" + +[get_upgrade_title] +other = "[v2 から v3 にアップグレードしますか?](https://helm.sh/docs/topics/v2_v3_migration/)" + +[get_upgrade_desc] +other = "[詳細については、移行ドキュメントをご覧ください。](https://helm.sh/docs/topics/v2_v3_migration/)" + +## homepage community +[community_title] +other = "コミュニティに参加" + +[community_desc] +other = "Helm プロジェクトの詳細と貢献方法。" + +[community_events_title] +other = "イベント" + +[community_upcoming_events_title] +other = "今後のイベント" + +[community_upcoming_events_desc] +other = "このスペースをご覧ください..." + +[community_past_events_title] +other = "過去のイベント" + +[community_past_event_01] +other = "_Feb 25th 2020_ - [Helm Security Webinar](https://www.cncf.io/webinars/helm-security-a-look-below-deck/)" + +[community_past_event_02] +other = "_Nov 18th 2019_ - [KubeCon North America](https://events19.linuxfoundation.org/events/kubecon-cloudnativecon-north-america-2019/)" + +[community_past_event_03] +other = "_Sep 11th 2019_ - [Helm Summit 2019](https://events19.linuxfoundation.org/events/helm-summit-2019/)" + +[community_sig_title] +other = "SIG Apps" + +[community_sig_subtitle] +other = "Kubernetes でアプリをデプロイして操作するための特に興味深いグループ。" + +[community_sig_desc] +other = """ +[SIG-Apps](https://github.com/kubernetes/community/blob/master/sig-apps/README.md) は、Kubernetes でアプリをデプロイして操作するための特に興味深いグループです。 + +彼らは[毎週会って](https://github.com/kubernetes/community/blob/master/sig-apps/README.md)デモやツールやプロジェクトについて議論します。コミュニティミーティングは記録され、[YouTube で共有されます](https://www.youtube.com/results?search_query=kubernetes+sig+apps)。 +""" + +[community_standup_title] +other = "開発者スタンドアップ" + +[community_standup_time] +other = "Thursdays 9:30-10am (PT)" + +[community_standup_desc] +other = "これらの会議は誰でも参加できます。メモと詳細については、[コミュニティリポジトリ](https://github.com/helm/community/blob/main/communication.md#meetings) を確認してください。" + +[community_slack_title] +other = "Slack" + +[community_slack_group_01_title] +other = "Helm ユーザ" + +[community_slack_group_01_desc] +other = "Helm の使用、チャートの操作、一般的なエラーの解決に関するディスカッション。" + +[community_slack_group_02_title] +other = "Helm 開発" + +[community_slack_group_02_desc] +other = "Helm 開発、進行中の PR、リリースなどに関するトピック" + +[community_slack_group_03_title] +other = "チャート" + +[community_slack_group_03_desc] +other = "Helm チャートのユーザと貢献者のためのディスカッション。" + +[community_slack_join] +other = "[ここからアクセスをリクエスト](https://slack.k8s.io/)して、Kubernetes Slack チームに参加してください。" + +[community_contrib_title] +other = "貢献" + +[community_contrib_subtitle] +other = "Helm は常にプロジェクトへの新しい貢献を歓迎します!" + + +[community_contrib_desc] +other = """ +### どこから始めますか? + +Helm は、多くのユーザーと貢献者がいる大きなプロジェクトです。 取り込むのは大変です! + +貢献したいがどこから始めればよいかわからない場合は、[good first issues](https://github.com/helm/helm/issues?utf8=%E2%9C%93&q=is%3Aopen%20is%3Aissue%20label%3A%22good+first+issue%22) のリストを用意しています。 + +### 何をしますか? + +コードを投稿する前に、[貢献ガイド](https://github.com/helm/helm/blob/main/CONTRIBUTING.md)をお読みください。プルリクエストの作成と確認に関するプロセスについて説明します。 + +コードを書いたら、[コミットに署名](https://helm.sh/blog/helm-dco/index.html)して、[CNCF](https://www.cncf.io/) が使用する [DCO](https://developercertificate.org/) 契約に Helm が確実に準拠するようにしてください。 +""" + +# 404 page +[404_title] +other = "**404** **ページが見つかりません。**" + +[404_subtitle] +other = "申し訳ありません。何かが壊れている場合は、[ここに報告してください](https://github.com/helm/helm-www/issues/new)。" diff --git a/i18n/ko.toml b/i18n/ko.toml new file mode 100644 index 0000000000..752539e99b --- /dev/null +++ b/i18n/ko.toml @@ -0,0 +1,212 @@ +# site-wide copy + +## actions and labels +[action_get_started] +other = "시작" + +[action_get_started_link] +other = "/ko/docs/intro/quickstart" + +[action_translate] +other = "이 페이지 번역" + +[action_translate_link] +other = "https://github.com/helm/helm-www#internationalization--translation" + +[action_copy] +other = "복사" + +## site-wide banner about versioning +[banner_1] +other = "" + +## footer +[footer_support_title] +other = "헬름은 개발자 400명 이상의 커뮤니티가 개발 및 지원에 참여하고 있습니다." + +[footer_support_subtitle] +other = "[헬름](https://github.com/helm/helm/blob/main/OWNERS) 및 [차트](https://github.com/helm/charts/blob/master/OWNERS) 유지 관리자들 역시 도움을 주고 있습니다." + +[footer_cncf_status] +other = "헬름은 Cloud Native Computing Foundation의 졸업 프로젝트 중 하나입니다." +# homepage copy + +## homepage intro +[main_title] +other = "**쿠버네티스** **패키지 매니저**" + +[main_subtitle] +other = "헬름은 [쿠버네티스](https://kubernetes.io)용 소프트웨어를 검색하거나, 공유하고 사용하기에 가장 좋은 방법입니다." + +## homepage about helm +[main_what_is_helm_title] +other = "헬름이란?" + +[main_what_is_helm_description] +other = """ +헬름을 통한 쿠버네티스 애플리케이션 관리 — 헬름 차트는 복잡한 쿠버네티스 애플리케이션도 편리하게 정의하여 설치하거나 업그레이드할 수 있습니다. + +편리한 차트 작성, 버전 관리, 공유 및 게시 - 복사, 붙이기 대신 헬름을 사용해 보세요. + +헬름은 [CNCF](https://cncf.io)의 졸업 프로젝트 중 하나로 [헬름 커뮤니티](https://github.com/helm/community)에서 관리합니다. + +### 자세한 정보: + +* [헬름 아키텍처](./docs/topics/architecture/) +* [퀵스타트 가이드](./docs/intro/quickstart/) +* [비디오: 헬름 소개](https://www.youtube.com/watch?v=Zzwq9FmZdsU&t=2s) +""" + +[main_why_teams_love] +other = '헬름이 받는 이유' + +[feature_01_title] +other = "복잡성 관리" + +[feature_01_desc] +other = "차트는 매우 복잡한 앱도 표현하고, 반복적인 애플리케이션 설치를 제공하며, 단일 권한으로 서비스할 수 있습니다." + +[feature_02_title] +other = "쉬운 업데이트" + +[feature_02_desc] +other = "즉석(in-place) 업그레이드와 커스텀 훅을 통해 업데이트하는 수고를 덜어줍니다." + +[feature_03_title] +other = "간단한 공유" + +[feature_03_desc] +other = "차트는 버전 관리, 공유, 퍼블릭이나 프라이빗 서버 호스팅이 편리합니다." + +[feature_04_title] +other = "롤백" + +[feature_04_desc] +other = "`helm rollback`을 사용하여 릴리스를 예전 버전으로 간편하게 되돌리세요." + +## homepage get helm +[get_helm_title] +other = "헬름 설치하기!" + +[get_helm_desc] +other = "패키지 매니저로 헬름을 설치하거나, [바이너리로 다운로드](https://github.com/helm/helm/releases/latest)하세요." + +[get_helm_next] +other = "설치 후에는, 헬름 바이너리를 풀고 PATH를 추가하여 사용할 수 있습니다! 상세 [설치방법](./docs/intro/install/)과 [사용 설명서](./docs/intro/using_helm/) 등 [문서](./docs/intro/install/)를 참고하세요." + +[get_charts_title] +other = "차트 받기" + +[get_charts_desc] +other = "[헬름 허브](https://hub.helm.sh)를 방문하여 공개된 수많은 헬름 저장소의 차트들을 둘러보세요." + +[get_upgrade_title] +other = "[v2에서 v3으로 업그레이드하기?](https://helm.sh/docs/topics/v2_v3_migration/)" + +[get_upgrade_desc] +other = "[자세한 내용은 마이그레이션 문서를 참고하세요.](https://helm.sh/docs/topics/v2_v3_migration/)" + +## homepage community +[community_title] +other = "커뮤니티 참여" + +[community_desc] +other = "헬름 프로젝트와 기여하는 방법에 관한 추가 정보" + +[community_events_title] +other = "행사" + +[community_upcoming_events_title] +other = "예정된 행사" + +[community_upcoming_events_desc] +other = "행사 정보..." + +[community_past_events_title] +other = "지난 행사" + +[community_past_event_01] +other = "_Feb 25th 2020_ - [헬름 보안 웨비나](https://www.cncf.io/webinars/helm-security-a-look-below-deck/)" + +[community_past_event_02] +other = "_Nov 18th 2019_ - [KubeCon 북아메리카](https://events19.linuxfoundation.org/events/kubecon-cloudnativecon-north-america-2019/)" + +[community_past_event_03] +other = "_Sep 11th 2019_ - [헬름 서밋 2019](https://events19.linuxfoundation.org/events/helm-summit-2019/)" + +[community_sig_title] +other = "SIG 앱" + +[community_sig_subtitle] +other = "쿠버네티스 내 앱 배포 및 운영에 관한 분과회(SIG)." + +[community_sig_desc] +other = """ +[SIG-앱](https://github.com/kubernetes/community/blob/master/sig-apps/README.md) 쿠버네티스 내에 앱의 배포와 운영에 관한 분과회입니다. + +도구와 프로젝트에 관해 설명하고 논의하기 위해 [매주 회의](https://github.com/kubernetes/community/blob/master/sig-apps/README.md)를 합니다. 커뮤니티 회의는 녹화되어 [유튜브에 공유](https://www.youtube.com/results?search_query=kubernetes+sig+apps)됩니다. +""" + +[community_standup_title] +other = "개발자 스탠드업 회의" + +[community_standup_time] +other = "목요일 9:30-10am (PT)" + +[community_standup_desc] +other = "이 회의는 모두에게 열려 있습니다. 자세한 내용은 [커뮤니티 저장소](https://github.com/helm/community/blob/main/communication.md#meetings)을 참고하세요." + +[community_slack_title] +other = "슬랙" + +[community_slack_group_01_title] +other = "헬름 사용자" + +[community_slack_group_01_desc] +other = "헬름 사용, 차트 작업, 일반적인 오류 해결에 관한 의견 나누기." + +[community_slack_group_02_title] +other = "헬름 개발" + +[community_slack_group_02_desc] +other = "헬름 개발, 진행 중인 PR, 릴리스 등에 관한 주제." + +[community_slack_group_03_title] +other = "차트" + +[community_slack_group_03_desc] +other = "헬름 차트 사용자 및 기여자들과 의견 나누기." + +[community_slack_join] +other = "쿠버네티스 슬랙 팀에 가입하려면 [이곳에서 요청하세요](https://slack.k8s.io/)." + +[community_contrib_title] +other = "기여" + +[community_contrib_subtitle] +other = "헬름은 프로젝트에 대한 기여를 항상 환영합니다!" + + +[community_contrib_desc] +other = """ +### 어디서 시작해야 할까요? + +헬름은 많은 사용자와 기여자가 있는 거대 프로젝트입니다. 참여할 거리는 많을 겁니다! +도움을 주고 싶지만 어디서 시작해야 할지 모르겠다면, [적당한 첫번째 이슈](https://github.com/helm/helm/issues?utf8=%E2%9C%93&q=is%3Aopen%20is%3Aissue%20label%3A%22good+first+issue%22) 목록을 참고해보세요. + +### 무엇을 할 수 있을까요? + +코드를 기여하기 전에, [기여 가이드](https://github.com/helm/helm/blob/main/CONTRIBUTING.md)를 읽어보세요. +풀 요청의 작성 및 검토에 관한 프로세스를 다룹니다. + +코드를 작성했다면, +헬름에서 [CNCF](https://www.cncf.io/)의 [DCO](https://developercertificate.org/) 동의서를 준수한다는 것을 확인할 수 있도록 +[커밋에 서명](https://helm.sh/blog/helm-dco/index.html)해주세요. +""" + +# 404 page +[404_title] +other = "**404** **페이지를 찾을 수 없습니다.**" + +[404_subtitle] +other = "죄송합니다. 뭔가 오류가 있다면 [이곳에 알려주세요](https://github.com/helm/helm-www/issues/new)." diff --git a/i18n/pt.toml b/i18n/pt.toml new file mode 100644 index 0000000000..a81930c148 --- /dev/null +++ b/i18n/pt.toml @@ -0,0 +1,223 @@ +# site-wide copy + +## actions and labels +[action_get_started] +other = "Primeiros Passos" + +[action_get_started_link] +other = "/docs/intro/quickstart" + +[action_translate] +other = "Traduza esta página" + +[action_translate_link] +other = "https://github.com/helm/helm-www#internationalization--translation" + +[action_copy] +other = "Copiar" + +## site-wide banner about versioning +[banner_1] +other = "" + +## footer +[footer_support_title] +other = "Helm é construído e mantido por uma comunidade de mais de 400 desenvolvedores" + +[footer_support_subtitle] +other = "...e muitos outros maravilhosos mantenedores dos [helm](https://github.com/helm/helm/blob/main/OWNERS) [charts](https://github.com/helm/charts/blob/master/OWNERS)." + +[footer_cncf_status] +other = "Nós somos um projeto graduado da Cloud Native Computing Foundation." + +# homepage copy + +## homepage intro +[main_title] +other = "**O** **gerenciador de pacotes** **para o Kubernetes**" + +[main_subtitle] +other = "Helm é a melhor maneira de descobrir, compartilhar e utilizar aplicações construídas para o [Kubernetes](https://kubernetes.io)." + +## homepage about helm +[main_what_is_helm_title] +other = "O que é o Helm?" + +[main_what_is_helm_description] +other = """ +O Helm lhe auxilia no gerenciamento de aplicações para Kubernetes — Charts do Helm ajudam a definir, instalar, e atualizar até a mais complexa aplicação para o Kubernetes. + +Os Charts são fáceis de criar, versionar, compartilhar e publicar — comece agora a utilizar o Helm e pare de copiar e colar manifestos. + +Helm é um projeto graduado da [CNCF](https://cncf.io) e é mantido pela [Comunidade do Helm](https://github.com/helm/community). + +### Saiba mais: + +* [Architetura do Helm](/docs/topics/architecture/) +* [Guia de Início Rápido](/docs/intro/quickstart/) +* [Vídeo: Uma introdução ao Helm](https://www.youtube.com/watch?v=Zzwq9FmZdsU&t=2s) +""" + +[main_why_teams_love] +other = 'O Porquê dos times o Helm' + +[feature_01_title] +other = "Gerencie Complexidade" + +[feature_01_desc] +other = "Os Charts do Helm descrevem até mesmo a mais complexa applicação, estabelecem repetibilidade na instalação de apps, e servem como um único ponto de autoridade." + +[feature_02_title] +other = "Atualizações Tranquilas" + +[feature_02_desc] +other = "Livre-se de atualizações traumáticas com upgrades no local e hooks customizáveis." + +[feature_03_title] +other = "Compartilhamento Simples" + +[feature_03_desc] +other = "Charts do Helm são fáceis de se versionar, compartilhar e hospedar em servidores públicos e/ou privados." + +[feature_04_title] +other = "Rollbacks" + +[feature_04_desc] +other = "Use o comando `helm rollback` para retornar às versões antigas da aplicação com tranquilidade." + +## homepage get helm +[get_helm_title] +other = "Baixe o Helm!" + +[get_helm_desc] +other = "Instale o Helm via gerenciador de pacotes, ou [baixe o binário](https://github.com/helm/helm/releases/latest)." + +[get_helm_next] +other = "Depois de instalado, descompacte o binário do Helm, adicione-o ao seu PATH e seja feliz! Confira a [documentação](/docs/intro/install/) para outras formas de [instalação](/docs/intro/install/) e [instruções de uso](/docs/intro/using_helm/)." + +[get_charts_title] +other = "Baixe os Charts do Helm" + +[get_charts_desc] +other = "Visite o [Artifact Hub](https://artifacthub.io) para encontrar mais [Charts do Helm](https://artifacthub.io/packages/search?kind=0) de inúmeros repositórios públicos." + +[get_upgrade_title] +other = "[Saindo da v2 para a v3?](https://helm.sh/docs/topics/v2_v3_migration/)" + +[get_upgrade_desc] +other = "[Leia a documentação de migração para mais detalhes.](https://helm.sh/docs/topics/v2_v3_migration/)" + +## homepage community +[community_title] +other = "Entre na Comunidade" + +[community_desc] +other = "Para mais informações sobre o projeto Helm e como contribuir." + +[community_next_release] +other = "Próximos Lançamentos de Funcionalidades" + +[community_next_release_version] +other = "__Versão:__ " + +[community_next_release_date] +other = "__Data:__ " + +[community_release_calendar] +other = "[Calendário de Lançamentos](https://helm.sh/calendar/release)" + +[community_events_title] +other = "Eventos" + +[community_upcoming_events_title] +other = "Próximos eventos" + +[community_upcoming_events_desc] +other = "Fique ligado..." + +[community_past_events_title] +other = "Eventos passados" + +[community_past_event_01] +other = "_Feb 25th 2020_ - [Webinar de Segurança no Helm](https://www.cncf.io/webinars/helm-security-a-look-below-deck/)" + +[community_past_event_02] +other = "_Nov 18th 2019_ - [KubeCon North America](https://events19.linuxfoundation.org/events/kubecon-cloudnativecon-north-america-2019/)" + +[community_past_event_03] +other = "_Sep 11th 2019_ - [Helm Summit 2019](https://events19.linuxfoundation.org/events/helm-summit-2019/)" + +[community_sig_title] +other = "SIG Apps" + +[community_sig_subtitle] +other = "Um Grupo de Interesse Especial (SIG) para entregar e operar aplicações no Kubernetes." + +[community_sig_desc] +other = """ +[SIG-Apps](https://github.com/kubernetes/community/blob/master/sig-apps/README.md) é um Grupo de Interesse Especial para entregar e operar aplicações no Kubernetes. + +Eles se [encontram toda a semana](https://github.com/kubernetes/community/blob/master/sig-apps/README.md) para testar e discutir ferramentas e projetos. Os encontros da comunidade são gravados e [compartilhados no YouTube](https://www.youtube.com/results?search_query=kubernetes+sig+apps). +""" + +[community_standup_title] +other = "Encontro com Desenvolvedores" + +[community_standup_time] +other = "Quintas-feiras de 1:30-2pm (BRT)" + +[community_standup_desc] +other = "Os encontros são abertos a todos. Confira o [repositório da comunidade](https://github.com/helm/community/blob/main/communication.md#meetings) para mais informações e detalhes." + +[community_slack_title] +other = "Slack" + +[community_slack_group_01_title] +other = "Helm Users" + +[community_slack_group_01_desc] +other = "Discussão sobre o uso do Helm, charts e resolução de problemas comuns." + +[community_slack_group_02_title] +other = "Helm Development" + +[community_slack_group_02_desc] +other = "Tópicos relacionados ao desenvolvimento do Helm, PRs em aberto, releases, etc." + +[community_slack_group_03_title] +other = "Charts" + +[community_slack_group_03_desc] +other = "Discussão para usuários e colaboradores de Charts do Helm." + +[community_slack_join] +other = "[Solicite seu acesso aqui](https://slack.k8s.io/) para ingressar no grupo do Kubernetes no Slack." + +[community_contrib_title] +other = "Contribuindo" + +[community_contrib_subtitle] +other = "O Helm é sempre aberto com novas contribuições ao projeto!" + + +[community_contrib_desc] +other = """ +### Por onde começar? + +Helm é um grande projeto com muitos usuários e colaboradores. É muita coisa para se lidar! + +Temos uma lista de [boas issues](https://github.com/helm/helm/issues?utf8=%E2%9C%93&q=is%3Aopen%20is%3Aissue%20label%3A%22good+first+issue%22) se você quiser ajudar mas não sabe por onde começar. + +### O que tenho que fazer? + +Antes de contribuir com seu código, por favor leia atentamente nosso [Guia de Contribuição](https://github.com/helm/helm/blob/main/CONTRIBUTING.md). Este será submetido ao processo de criação e revisão de pull requests. + +Toda vez que escrever seu código, por favor [assine seus commits](https://helm.sh/blog/helm-dco/index.html) para garantir que o projeto Helm adira ao acordo [DCO](https://developercertificate.org/) utilizado pela [CNCF](https://www.cncf.io/). +""" + +# 404 page +[404_title] +other = "**404** **Página não encontrada.**" + +[404_subtitle] +other = "Desculpe-nos. Se algo está fora do ar por favor [reporte aqui](https://github.com/helm/helm-www/issues/new)." diff --git a/i18n/ru.toml b/i18n/ru.toml new file mode 100644 index 0000000000..f0b1193b0d --- /dev/null +++ b/i18n/ru.toml @@ -0,0 +1,223 @@ +# site-wide copy + +## actions and labels +[action_get_started] +other = "Приступить к работе" + +[action_get_started_link] +other = "/ru/docs/intro/quickstart" + +[action_translate] +other = "Переведите эту страницу" + +[action_translate_link] +other = "https://github.com/helm/helm-www#internationalization--translation" + +[action_copy] +other = "Скопировать" + +## site-wide banner about versioning +[banner_1] +other = "" + +## footer +[footer_support_title] +other = "Helm поддерживается и создается сообществом из более чем 400 разработчиков.." + +[footer_support_subtitle] +other = "...и много других замечательных [helm](https://github.com/helm/helm/blob/main/OWNERS) и [charts](https://github.com/helm/charts/blob/master/OWNERS) core maintainers." + +[footer_cncf_status] +other = "Мы являемся выпускным проектом Cloud Native Computing Foundation." + +# homepage copy + +## homepage intro +[main_title] +other = "**Это** **менеджер пакетов** **для Kubernetes**" + +[main_subtitle] +other = "Helm – это лучший способ найти, поделиться и использовать программное обеспечение, созданное для [Kubernetes](https://kubernetes.io)." + +## homepage about helm +[main_what_is_helm_title] +other = "Что такое Helm?" + +[main_what_is_helm_description] +other = """ +Helm помогает управлять приложениями Kubernetes — Helm Charts помогут вам определить, установить и обновить даже самое сложное приложение Kubernetes. + +Charts легко создавать, версионировать, публиковать и делиться ими – так что начните использовать Helm и остановите копирование и вставку. + +Helm – дипломный проект в [CNCF](https://cncf.io) и обслуживается [Helm сообществом](https://github.com/helm/community). + +### Узнать больше: + +* [Helm Архитектура](https://helm.sh/docs/topics/architecture/) +* [Краткое руководство по эксплуатации](./docs/intro/quickstart/) +* [Видео: Введение в Helm](https://www.youtube.com/watch?v=Zzwq9FmZdsU&t=2s) +""" + +[main_why_teams_love] +other = 'Почему команды Helm' + +[feature_01_title] +other = "Избавьтесь от сложностей" + +[feature_01_desc] +other = "Charts описывают даже самые сложные приложения, обеспечивают повторяемость установки приложений и служат единой точкой отсчета." + +[feature_02_title] +other = "Простые обновления" + +[feature_02_desc] +other = "Избавьтесь от боли при обновлениях с помощью встроенных обновлений и пользовательских hooks." + +[feature_03_title] +other = "Простое распостранение" + +[feature_03_desc] +other = "Charts легко версовать, совместно использовать и размещать на общедоступных или частных серверах." + +[feature_04_title] +other = "Откаты" + +[feature_04_desc] +other = "Используйте `helm rollback` чтобы с легкостью откатиться на старую версию релиза." + +## homepage get helm +[get_helm_title] +other = "Скачайте Helm!" + +[get_helm_desc] +other = "Установите Helm менеджером пакетов, или [скачайте binary](https://github.com/helm/helm/releases/latest)." + +[get_helm_next] +other = "После установки, распакуйте двоичный файл Helm и добавьте его в свой PATH! Проверьте [документацию](./docs/intro/install/) для получения информацию об [уставновке](./docs/intro/install/) и [использовании](./docs/intro/using_helm/)." + +[get_charts_title] +other = "Скачайте Chart-ы" + +[get_charts_desc] +other = "Посетите [Artifact Hub](https://artifacthub.io) чтобы познакомиться [Helm charts](https://artifacthub.io/packages/search?kind=0) из многочисленных публичных репозиториев." + +[get_upgrade_title] +other = "[Обновляетесь с v2 на v3?](https://helm.sh/docs/topics/v2_v3_migration/)" + +[get_upgrade_desc] +other = "[Для получения более подробной информации ознакомьтесь с документом миграции.](https://helm.sh/docs/topics/v2_v3_migration/)" + +## homepage community +[community_title] +other = "Присоединиться к сообществу" + +[community_desc] +other = "Дополнительная информация о проекте Helm и о том, как внести свой вклад." + +[community_next_release] +other = "Следующая версия" + +[community_next_release_version] +other = "__Version:__ " + +[community_next_release_date] +other = "__Date:__ " + +[community_release_calendar] +other = "[Календарь выхода в свет](https://helm.sh/calendar/release)" + +[community_events_title] +other = "События" + +[community_upcoming_events_title] +other = "Предстоящие события" + +[community_upcoming_events_desc] +other = "Следите за этим пространством..." + +[community_past_events_title] +other = "Прошлые события" + +[community_past_event_01] +other = "_Feb 25th 2020_ - [Helm Security Webinar](https://www.cncf.io/webinars/helm-security-a-look-below-deck/)" + +[community_past_event_02] +other = "_Nov 18th 2019_ - [KubeCon North America](https://events19.linuxfoundation.org/events/kubecon-cloudnativecon-north-america-2019/)" + +[community_past_event_03] +other = "_Sep 11th 2019_ - [Helm Summit 2019](https://events19.linuxfoundation.org/events/helm-summit-2019/)" + +[community_sig_title] +other = "SIG Apps" + +[community_sig_subtitle] +other = "Специальная группа по интересам развертывания и эксплуатации приложений в Kubernetes." + +[community_sig_desc] +other = """ +[SIG-Apps](https://github.com/kubernetes/community/blob/master/sig-apps/README.md) является специальной группой по интересам развертывания и эксплуатации приложений в Kubernetes. + +Они [встречаются каждую неделю](https://github.com/kubernetes/community/blob/master/sig-apps/README.md) для демонстрации и обсуждения инструментов и проектов. Встречи сообщества записываются и [передаются на YouTube](https://www.youtube.com/results?search_query=kubernetes+sig+apps). +""" + +[community_standup_title] +other = "Стендапы разработчиков" + +[community_standup_time] +other = "Thursdays 9:30-10am (PT)" + +[community_standup_desc] +other = "Эти встречи открыты для всех. Проверьте [репозиторий сообщества](https://github.com/helm/community/blob/main/communication.md#meetings) для получения заметок и подробностей." + +[community_slack_title] +other = "Slack" + +[community_slack_group_01_title] +other = "Helm Users" + +[community_slack_group_01_desc] +other = "Обсуждение использования Helm, работы с charts и решения распространенных ошибок." + +[community_slack_group_02_title] +other = "Helm Development" + +[community_slack_group_02_desc] +other = "Tемы, касающиеся разработки Helm, текущих PRs, релизов и т.д." + +[community_slack_group_03_title] +other = "Charts" + +[community_slack_group_03_desc] +other = "Обсуждение для пользователей и участников Helm Charts." + +[community_slack_join] +other = "[Запросите доступ](https://slack.k8s.io/) для присоединения к Kubernetes Slack team." + +[community_contrib_title] +other = "Вклад" + +[community_contrib_subtitle] +other = "Helm всегда рад новым вкладам в проект!" + + +[community_contrib_desc] +other = """ +### С чего начать? + +Helm -–большой проект с большим количеством пользователей и соавторов. Это может быть много, чтобы принять в нем участие! + +У нас есть список [хороших первых issues](https://github.com/helm/helm/issues?utf8=%E2%9C%93&q=is%3Aopen%20is%3Aissue%20label%3A%22good+first+issue%22) для тех кто хочет поучаствовать, но не знает с чего начать. + +### Что мне делать? + +Прежде чем вы внесете свой вклад в какой-то код, пожалуйста, прочтите наш [Руководство по вкладам](https://github.com/helm/helm/blob/main/CONTRIBUTING.md). Он описывает процессы, связанные с созданием и анализом pull requests. + +Как только вы напишете какой-нибудь код, пожалуйста [подпишите свои коммиты](https://helm.sh/blog/helm-dco/index.html) что бы гарантировать, что Helm придерживается [DCO](https://developercertificate.org/) используемого [CNCF](https://www.cncf.io/). +""" + +# 404 page +[404_title] +other = "**404** **Страница не найдена.**" + +[404_subtitle] +other = "Извините за это. Если что-то сломано, пожалуйста, [сообщите об этом сюда](https://github.com/helm/helm-www/issues/new)." diff --git a/i18n/zh.toml b/i18n/zh.toml new file mode 100644 index 0000000000..b3311f433c --- /dev/null +++ b/i18n/zh.toml @@ -0,0 +1,223 @@ +# site-wide copy + +## actions and labels +[action_get_started] +other = "从这里开始" + +[action_get_started_link] +other = "/zh/docs/intro/quickstart" + +[action_translate] +other = "翻译这个页面" + +[action_translate_link] +other = "https://github.com/helm/helm-www#internationalization--translation" + +[action_copy] +other = "复制" + +## site-wide banner about versioning +[banner_1] +other = "" + +## footer +[footer_support_title] +other = "Helm 项目受到社区超过 400 开发者构建和支持。" + +[footer_support_subtitle] +other = "...还有很多其他精彩内容包括 [helm](https://github.com/helm/helm/blob/main/OWNERS) 和 [charts](https://github.com/helm/charts/blob/master/OWNERS) 的核心开发者." + +[footer_cncf_status] +other = "我们是 CNCF 的毕业项目。" + +# homepage copy + +## homepage intro +[main_title] +other = "**Kubernetes** **包管理器**" + +[main_subtitle] +other = "Helm 是查找、分享和使用软件构建 [Kubernetes](https://kubernetes.io) 的最优方式。" + +## homepage about helm +[main_what_is_helm_title] +other = "Helm 是什么?" + +[main_what_is_helm_description] +other = """ +Helm 帮助您管理 Kubernetes 应用—— Helm Chart,即使是最复杂的 Kubernetes 应用程序,都可以帮助您定义,安装和升级。 + +Helm Chart 易于创建、发版、分享和发布,所以停止复制粘贴,开始使用 Helm 吧。 + +Helm 是 [CNCF](https://cncf.io) 的毕业项目,由 [Helm 社区](https://github.com/helm/community)维护。 + +### Learn more: + +* [Helm 架构](https://helm.sh/docs/topics/architecture/) +* [快速开始 指引](https://helm.sh/docs/intro/quickstart/) +* [Helm 视频介绍(YouTube)](https://www.youtube.com/watch?v=Zzwq9FmZdsU&t=2s) +""" + +[main_why_teams_love] +other = '为什么团队 Helm' + +[feature_01_title] +other = "复杂性管理" + +[feature_01_desc] +other = "即使是最复杂的应用,Helm Chart 依然可以描述, 提供使用单点授权的可重复安装应用程序。" + +[feature_02_title] +other = "易于升级" + +[feature_02_desc] +other = "随时随地升级和自定义的钩子消除您升级的痛苦。" + +[feature_03_title] +other = "分发简单" + +[feature_03_desc] +other = "Helm Chart 很容易在公共或私有化服务器上发版,分发和部署站点。" + +[feature_04_title] +other = "回滚" + +[feature_04_desc] +other = "使用 `helm rollback` 可以轻松回滚到之前的发布版本。" + +## homepage get helm +[get_helm_title] +other = "获取 Helm!" + +[get_helm_desc] +other = "使用包管理器安装 Helm 或者 [下载二进制包](https://github.com/helm/helm/releases/latest)." + +[get_helm_next] +other = "安装完成后,解压二进制包并添加到PATH,就可以使用了! 可以在[安装](https://helm.sh/docs/intro/install/)查看更多[安装步骤](https://helm.sh/docs/intro/install/)和[使用说明](https://helm.sh/docs/intro/using_helm/)." + +[get_charts_title] +other = "获取 Chart" + +[get_charts_desc] +other = "访问 [Helm 应用中心](https://hub.helm.sh) 浏览公共库大量的 Charts。" + +[get_upgrade_title] +other = "[从 v2 升级到 v3](https://helm.sh/docs/topics/v2_v3_migration/)" + +[get_upgrade_desc] +other = "[阅读迁移文档了解更多信息](https://helm.sh/docs/topics/v2_v3_migration/)" + +## homepage community +[community_title] +other = "加入社区" + +[community_desc] +other = "关于 Helm 项目的更多信息,以及如何参与。" + +[community_next_release] +other = "下一个功能版本" + +[community_next_release_version] +other = "__Version:__ " + +[community_next_release_date] +other = "__Date:__ " + +[community_release_calendar] +other = "[发布日志](https://helm.sh/calendar/release)" + +[community_events_title] +other = "大事记" + +[community_upcoming_events_title] +other = "即将到来的内容" + +[community_upcoming_events_desc] +other = "了解该部分..." + +[community_past_events_title] +other = "以往事迹" + +[community_past_event_01] +other = "_Feb 25th 2020_ - [Helm Security Webinar](https://www.cncf.io/webinars/helm-security-a-look-below-deck/)" + +[community_past_event_02] +other = "_Nov 18th 2019_ - [KubeCon North America](https://events19.linuxfoundation.org/events/kubecon-cloudnativecon-north-america-2019/)" + +[community_past_event_03] +other = "_Sep 11th 2019_ - [Helm Summit 2019](https://events19.linuxfoundation.org/events/helm-summit-2019/)" + +[community_sig_title] +other = "SIG Apps" + +[community_sig_subtitle] +other = "在 Kubernetes 中部署和操作应用的特别兴趣小组。" + +[community_sig_desc] +other = """ +[SIG-Apps](https://github.com/kubernetes/community/blob/master/sig-apps/README.md) 是在 Kubernetes 中部署和操作应用的特别兴趣小组。 + +他们[每周会面](https://github.com/kubernetes/community/blob/master/sig-apps/README.md) 演示和讨论工具及项目。 社区会议会被记录并[分享到 YouTube](https://www.youtube.com/results?search_query=kubernetes+sig+apps)。 +""" + +[community_standup_title] +other = "开发者站立会" + +[community_standup_time] +other = "周四上午 9:30-10 (PT)" + +[community_standup_desc] +other = "会议向大众开放,查看[社区记录](https://github.com/helm/community/blob/main/communication.md#meetings)了解公告和细节。" + +[community_slack_title] +other = "Slack" + +[community_slack_group_01_title] +other = "Helm 用户" + +[community_slack_group_01_desc] +other = "围绕使用 Helm,chart 和解决一般性错误进行讨论。" + +[community_slack_group_02_title] +other = "Helm 开发" + +[community_slack_group_02_desc] +other = "议题涉及 Helm 开发,正在进行的 PR,发版等等。" + +[community_slack_group_03_title] +other = "Helm Chart" + +[community_slack_group_03_desc] +other = "关于 Helm Chart 的用户和贡献者的讨论。" + +[community_slack_join] +other = "[从此处请求访问](https://slack.k8s.io/)加入 Kubernetes Slack 组." + +[community_contrib_title] +other = "贡献" + +[community_contrib_subtitle] +other = "Helm 一直欢迎对此项目的新贡献!" + + +[community_contrib_desc] +other = """ +### 从哪里开始? + +Helm 是一个有着大量用户和开发者的大型项目,还会有更多人加入! + +如果您想帮助我们但是不知道从哪里开始,我们有个[首要任务列表](https://github.com/helm/helm/issues?utf8=%E2%9C%93&q=is%3Aopen%20is%3Aissue%20label%3A%22good+first+issue%22)。 + +### 我该做什么? + +在开始贡献代码之前,请阅读我们的[贡献指南](https://github.com/helm/helm/blob/main/CONTRIBUTING.md)。它涵盖了创建和查看拉取请求的内容。 + +一旦你开始写代码,请[签名你的提交](https://helm.sh/blog/helm-dco/index.html)来保证 Helm 使用 [CNCF](https://www.cncf.io/) 坚持使用的 [DCO](https://developercertificate.org/) 协议。 +""" + +# 404 page +[404_title] +other = "**404** **页面未找到。**" + +[404_subtitle] +other = "抱歉。如果有问题请 [在这里报告](https://github.com/helm/helm-www/issues/new)。" diff --git a/netlify.toml b/netlify.toml new file mode 100755 index 0000000000..478ffb090e --- /dev/null +++ b/netlify.toml @@ -0,0 +1,46 @@ +[build] + command = "make build" + publish = "app" + +[build.environment] + HUGO_VERSION = "0.94.0" + HUGO_ENABLEGITINFO = "true" + +[context.production.environment] + HUGO_ENV = "production" + +[context.deploy-preview] + command = "make build-preview" + +[context.branch-deploy] + command = "make build-preview" + +# redirect docs homepage +[[redirects]] + from = "https://docs.helm.sh/" + to = "https://helm.sh/docs/" + +# redirect docs subpages +[[redirects]] + from = "https://docs.helm.sh/*" + to = "https://helm.sh/docs/:splat" + +[[redirects]] + from = "/docs/developing_charts/" + to = "https://v2.helm.sh/docs/developing_charts/" + +# redirect Go package lookups +[[redirects]] + from = "/helm/v3/*" + to = "/helm/v3" + status = 200 + +[[redirects]] + from = "/helm/v2/*" + to = "/helm/v2" + status = 200 + +[[redirects]] + from = "/calendar/release" + to = "https://calendar.google.com/calendar/u/0/embed?src=8tji8e0obp5skr2pval9g55ftk@group.calendar.google.com" + status = 302 diff --git a/package.json b/package.json new file mode 100755 index 0000000000..5f495623a0 --- /dev/null +++ b/package.json @@ -0,0 +1,22 @@ +{ + "name": "helm-docs", + "version": "0.0.1", + "description": "Helm Docs", + "main": "gulpfile.js/index.js", + "author": "Ronan Flynn-Curran", + "license": "MIT", + "repository": { + "type": "git", + "url": "git+https://github.com/helm/helm-www" + }, + "devDependencies": { + "autoprefixer": "9.7.4", + "postcss-cli": "7.1.0" + }, + "browserslist": [ + "> 0.5%", + "last 2 versions", + "Firefox ESR", + "not dead" + ] +} diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000000..fb3e54c892 --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,5 @@ +module.exports = { + plugins: { + autoprefixer: {} + }, +} diff --git a/themes/helm/assets/js/app.js b/themes/helm/assets/js/app.js new file mode 100755 index 0000000000..a517e46a0a --- /dev/null +++ b/themes/helm/assets/js/app.js @@ -0,0 +1,128 @@ +$(document).ready(function() { + $(document).foundation(); + + // custom theme js for sidebar links + var allClosed; + + // close all accordions, besides that of the page that is currently active + var doclocation = window.location.pathname; + var docpath = doclocation.substring(0, doclocation.lastIndexOf("/")); + var parentName = docpath.replace(/\/[^\/]+$/, '') + var pageName = docpath.substring(docpath.lastIndexOf("/")+1); + $(".toctree-l1 > a[href*='" + parentName + "']").addClass("active"); + $(".toctree-12 > a[href$='/" + pageName + "/']").addClass("active"); + + if (allClosed === true) { } + + // if menu is closed when clicked, expand it + $('.toctree-l1 > a').click(function() { + + //Make the titles of open accordions dead links + if ($(this).attr('state') == 'open') {return false;} + + //Clicking on a title of a closed accordion + if($(this).attr('state') != 'open' && $(this).siblings().size() > 0) { + $('.toctree-l1 > ul').hide(); + $('.toctree-l1 > a').attr('state', ''); + $(this).attr('state', 'open'); + $(this).next().slideDown(function(){}); + return false; + } + }); +}); // document ready + + +// navbar Clone +if ($('.navbar-top-fixed').length) { + $(window).scroll(function() { // this will work when your window scrolled. + var height = $(window).scrollTop(); //getting the scrolling height of window + if(height > 200) { + $(".navbar-top-fixed").addClass('is-active'); + } else{ + $(".navbar-top-fixed").removeClass('is-active'); + } + }); +} + +// navbar mobile burger menu (bulma) +$(".navbar-burger").click(function() { + $(".navbar-burger").toggleClass("is-active"); + $(".navbar-menu").toggleClass("is-active"); + $("#banner").toggleClass("is-active"); + $(".sidebar-wrapper").toggleClass("is-active"); +}); + +// a life at sea +if ($('.home').length) { + $(window).scroll(function() { // this will work when your window scrolled. + var height = $(window).scrollTop(); //getting the scrolling height of window + if(height > 600) { + $(".boat").addClass('boat-badge'); + } else{ + $(".boat").removeClass('boat-badge'); + } + }); +}; + +if ($('.page-docs').length) { + // adjust docs sidebar after scroll + $(window).scroll(function() { // this will work when your window scrolled. + var height = $(window).scrollTop(); //getting the scrolling height of window + if(height > 50) { + $(".sidebar-wrapper").addClass('is-scrolled'); + } else{ + $(".sidebar-wrapper").removeClass('is-scrolled'); + } + }); + + // toggle sidebar menu for mobile devices + $("#sidebar-toggle").click(function() { + $(this).toggleClass("active"); + $(".sidebar-content-wrapper").toggleClass("active"); + }); + + // add permalinks to titles + $(function() { + return $("h1, h2, h3, h4, h5, h6").each(function(i, el) { + var $el, icon, id; + $el = $(el); + id = $el.attr('id'); + icon = ''; + if (id) { + return $el.prepend($("").addClass("header-link").attr("href", "#" + id).html(icon)); + } + }); + }); +} + +// homepage download tabs +if ($('.home').length) { + $('div.tabcontent').hide(); + $('div.tabcontent:first-of-type').show(); + $('.tabs a').click(function(e){ + e.preventDefault(); + var $this = $(this), + tabgroup = $this.parents('.tabs').data('tab-group'), + others = $this.closest('li').siblings().children('a'), + target = $this.attr('href'); + others.removeClass('active'); + console.log('the tabgroup is ' + tabgroup); + $this.addClass('active'); + $('.tabgroup').children('div').hide(); + $(target).show(); + }) + + var clipboard = new ClipboardJS('.button'); + clipboard.on('success', function(e) { + e.clearSelection(); + console.info('Action:', e.action); + console.info('Text:', e.text); + console.info('Trigger:', e.trigger); + showTooltip(e.trigger, 'Copied!'); + }); + clipboard.on('error', function(e) { + console.error('Action:', e.action); + console.error('Trigger:', e.trigger); + showTooltip(e.trigger, fallbackMessage(e.action)); + }); +}; \ No newline at end of file diff --git a/themes/helm/assets/js/clipboard.min.js b/themes/helm/assets/js/clipboard.min.js new file mode 100644 index 0000000000..02c549e35c --- /dev/null +++ b/themes/helm/assets/js/clipboard.min.js @@ -0,0 +1,7 @@ +/*! + * clipboard.js v2.0.4 + * https://zenorocha.github.io/clipboard.js + * + * Licensed MIT © Zeno Rocha + */ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return function(n){var o={};function r(t){if(o[t])return o[t].exports;var e=o[t]={i:t,l:!1,exports:{}};return n[t].call(e.exports,e,e.exports,r),e.l=!0,e.exports}return r.m=n,r.c=o,r.d=function(t,e,n){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},r.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=0)}([function(t,e,n){"use strict";var r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},i=function(){function o(t,e){for(var n=0;n'; + } + })); + }; + + header_helpers([ + 'foundation-mq-small', + 'foundation-mq-small-only', + 'foundation-mq-medium', + 'foundation-mq-medium-only', + 'foundation-mq-large', + 'foundation-mq-large-only', + 'foundation-mq-xlarge', + 'foundation-mq-xlarge-only', + 'foundation-mq-xxlarge', + 'foundation-data-attribute-namespace']); + + // Enable FastClick if present + + $(function () { + if (typeof FastClick !== 'undefined') { + // Don't attach to body if undefined + if (typeof document.body !== 'undefined') { + FastClick.attach(document.body); + } + } + }); + + // private Fast Selector wrapper, + // returns jQuery object. Only use where + // getElementById is not available. + var S = function (selector, context) { + if (typeof selector === 'string') { + if (context) { + var cont; + if (context.jquery) { + cont = context[0]; + if (!cont) { + return context; + } + } else { + cont = context; + } + return $(cont.querySelectorAll(selector)); + } + + return $(document.querySelectorAll(selector)); + } + + return $(selector, context); + }; + + // Namespace functions. + + var attr_name = function (init) { + var arr = []; + if (!init) { + arr.push('data'); + } + if (this.namespace.length > 0) { + arr.push(this.namespace); + } + arr.push(this.name); + + return arr.join('-'); + }; + + var add_namespace = function (str) { + var parts = str.split('-'), + i = parts.length, + arr = []; + + while (i--) { + if (i !== 0) { + arr.push(parts[i]); + } else { + if (this.namespace.length > 0) { + arr.push(this.namespace, parts[i]); + } else { + arr.push(parts[i]); + } + } + } + + return arr.reverse().join('-'); + }; + + // Event binding and data-options updating. + + var bindings = function (method, options) { + var self = this, + bind = function(){ + var $this = S(this), + should_bind_events = !$this.data(self.attr_name(true) + '-init'); + $this.data(self.attr_name(true) + '-init', $.extend({}, self.settings, (options || method), self.data_options($this))); + + if (should_bind_events) { + self.events(this); + } + }; + + if (S(this.scope).is('[' + this.attr_name() +']')) { + bind.call(this.scope); + } else { + S('[' + this.attr_name() +']', this.scope).each(bind); + } + // # Patch to fix #5043 to move this *after* the if/else clause in order for Backbone and similar frameworks to have improved control over event binding and data-options updating. + if (typeof method === 'string') { + return this[method].call(this, options); + } + + }; + + var single_image_loaded = function (image, callback) { + function loaded () { + callback(image[0]); + } + + function bindLoad () { + this.one('load', loaded); + + if (/MSIE (\d+\.\d+);/.test(navigator.userAgent)) { + var src = this.attr( 'src' ), + param = src.match( /\?/ ) ? '&' : '?'; + + param += 'random=' + (new Date()).getTime(); + this.attr('src', src + param); + } + } + + if (!image.attr('src')) { + loaded(); + return; + } + + if (image[0].complete || image[0].readyState === 4) { + loaded(); + } else { + bindLoad.call(image); + } + }; + + /*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas, David Knight. Dual MIT/BSD license */ + + window.matchMedia || (window.matchMedia = function() { + "use strict"; + + // For browsers that support matchMedium api such as IE 9 and webkit + var styleMedia = (window.styleMedia || window.media); + + // For those that don't support matchMedium + if (!styleMedia) { + var style = document.createElement('style'), + script = document.getElementsByTagName('script')[0], + info = null; + + style.type = 'text/css'; + style.id = 'matchmediajs-test'; + + script.parentNode.insertBefore(style, script); + + // 'style.currentStyle' is used by IE <= 8 and 'window.getComputedStyle' for all other browsers + info = ('getComputedStyle' in window) && window.getComputedStyle(style, null) || style.currentStyle; + + styleMedia = { + matchMedium: function(media) { + var text = '@media ' + media + '{ #matchmediajs-test { width: 1px; } }'; + + // 'style.styleSheet' is used by IE <= 8 and 'style.textContent' for all other browsers + if (style.styleSheet) { + style.styleSheet.cssText = text; + } else { + style.textContent = text; + } + + // Test if media query is true or false + return info.width === '1px'; + } + }; + } + + return function(media) { + return { + matches: styleMedia.matchMedium(media || 'all'), + media: media || 'all' + }; + }; + }()); + + /* + * jquery.requestAnimationFrame + * https://github.com/gnarf37/jquery-requestAnimationFrame + * Requires jQuery 1.8+ + * + * Copyright (c) 2012 Corey Frang + * Licensed under the MIT license. + */ + + (function(jQuery) { + + + // requestAnimationFrame polyfill adapted from Erik Möller + // fixes from Paul Irish and Tino Zijdel + // http://paulirish.com/2011/requestanimationframe-for-smart-animating/ + // http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating + + var animating, + lastTime = 0, + vendors = ['webkit', 'moz'], + requestAnimationFrame = window.requestAnimationFrame, + cancelAnimationFrame = window.cancelAnimationFrame, + jqueryFxAvailable = 'undefined' !== typeof jQuery.fx; + + for (; lastTime < vendors.length && !requestAnimationFrame; lastTime++) { + requestAnimationFrame = window[ vendors[lastTime] + 'RequestAnimationFrame' ]; + cancelAnimationFrame = cancelAnimationFrame || + window[ vendors[lastTime] + 'CancelAnimationFrame' ] || + window[ vendors[lastTime] + 'CancelRequestAnimationFrame' ]; + } + + function raf() { + if (animating) { + requestAnimationFrame(raf); + + if (jqueryFxAvailable) { + jQuery.fx.tick(); + } + } + } + + if (requestAnimationFrame) { + // use rAF + window.requestAnimationFrame = requestAnimationFrame; + window.cancelAnimationFrame = cancelAnimationFrame; + + if (jqueryFxAvailable) { + jQuery.fx.timer = function (timer) { + if (timer() && jQuery.timers.push(timer) && !animating) { + animating = true; + raf(); + } + }; + + jQuery.fx.stop = function () { + animating = false; + }; + } + } else { + // polyfill + window.requestAnimationFrame = function (callback) { + var currTime = new Date().getTime(), + timeToCall = Math.max(0, 16 - (currTime - lastTime)), + id = window.setTimeout(function () { + callback(currTime + timeToCall); + }, timeToCall); + lastTime = currTime + timeToCall; + return id; + }; + + window.cancelAnimationFrame = function (id) { + clearTimeout(id); + }; + + } + + }( $ )); + + function removeQuotes (string) { + if (typeof string === 'string' || string instanceof String) { + string = string.replace(/^['\\/"]+|(;\s?})+|['\\/"]+$/g, ''); + } + + return string; + } + + function MediaQuery(selector) { + this.selector = selector; + this.query = ''; + } + + MediaQuery.prototype.toString = function () { + return this.query || (this.query = S(this.selector).css('font-family').replace(/^[\/\\'"]+|(;\s?})+|[\/\\'"]+$/g, '')); + }; + + window.Foundation = { + name : 'Foundation', + + version : '5.5.3', + + media_queries : { + 'small' : new MediaQuery('.foundation-mq-small'), + 'small-only' : new MediaQuery('.foundation-mq-small-only'), + 'medium' : new MediaQuery('.foundation-mq-medium'), + 'medium-only' : new MediaQuery('.foundation-mq-medium-only'), + 'large' : new MediaQuery('.foundation-mq-large'), + 'large-only' : new MediaQuery('.foundation-mq-large-only'), + 'xlarge' : new MediaQuery('.foundation-mq-xlarge'), + 'xlarge-only' : new MediaQuery('.foundation-mq-xlarge-only'), + 'xxlarge' : new MediaQuery('.foundation-mq-xxlarge') + }, + + stylesheet : $('').appendTo('head')[0].sheet, + + global : { + namespace : undefined + }, + + init : function (scope, libraries, method, options, response) { + var args = [scope, method, options, response], + responses = []; + + // check RTL + this.rtl = /rtl/i.test(S('html').attr('dir')); + + // set foundation global scope + this.scope = scope || this.scope; + + this.set_namespace(); + + if (libraries && typeof libraries === 'string' && !/reflow/i.test(libraries)) { + if (this.libs.hasOwnProperty(libraries)) { + responses.push(this.init_lib(libraries, args)); + } + } else { + for (var lib in this.libs) { + responses.push(this.init_lib(lib, libraries)); + } + } + + S(window).load(function () { + S(window) + .trigger('resize.fndtn.clearing') + .trigger('resize.fndtn.dropdown') + .trigger('resize.fndtn.equalizer') + .trigger('resize.fndtn.interchange') + .trigger('resize.fndtn.joyride') + .trigger('resize.fndtn.magellan') + .trigger('resize.fndtn.topbar') + .trigger('resize.fndtn.slider'); + }); + + return scope; + }, + + init_lib : function (lib, args) { + if (this.libs.hasOwnProperty(lib)) { + this.patch(this.libs[lib]); + + if (args && args.hasOwnProperty(lib)) { + if (typeof this.libs[lib].settings !== 'undefined') { + $.extend(true, this.libs[lib].settings, args[lib]); + } else if (typeof this.libs[lib].defaults !== 'undefined') { + $.extend(true, this.libs[lib].defaults, args[lib]); + } + return this.libs[lib].init.apply(this.libs[lib], [this.scope, args[lib]]); + } + + args = args instanceof Array ? args : new Array(args); + return this.libs[lib].init.apply(this.libs[lib], args); + } + + return function () {}; + }, + + patch : function (lib) { + lib.scope = this.scope; + lib.namespace = this.global.namespace; + lib.rtl = this.rtl; + lib['data_options'] = this.utils.data_options; + lib['attr_name'] = attr_name; + lib['add_namespace'] = add_namespace; + lib['bindings'] = bindings; + lib['S'] = this.utils.S; + }, + + inherit : function (scope, methods) { + var methods_arr = methods.split(' '), + i = methods_arr.length; + + while (i--) { + if (this.utils.hasOwnProperty(methods_arr[i])) { + scope[methods_arr[i]] = this.utils[methods_arr[i]]; + } + } + }, + + set_namespace : function () { + + // Description: + // Don't bother reading the namespace out of the meta tag + // if the namespace has been set globally in javascript + // + // Example: + // Foundation.global.namespace = 'my-namespace'; + // or make it an empty string: + // Foundation.global.namespace = ''; + // + Foundation.global.namespace = 'helm-www'; + + // If the namespace has not been set (is undefined), try to read it out of the meta element. + // Otherwise use the globally defined namespace, even if it's empty ('') + var namespace = ( this.global.namespace === undefined ) ? $('.foundation-data-attribute-namespace').css('font-family') : this.global.namespace; + + // Finally, if the namsepace is either undefined or false, set it to an empty string. + // Otherwise use the namespace value. + this.global.namespace = ( namespace === undefined || /false/i.test(namespace) ) ? '' : namespace; + }, + + libs : {}, + + // methods that can be inherited in libraries + utils : { + + // Description: + // Fast Selector wrapper returns jQuery object. Only use where getElementById + // is not available. + // + // Arguments: + // Selector (String): CSS selector describing the element(s) to be + // returned as a jQuery object. + // + // Scope (String): CSS selector describing the area to be searched. Default + // is document. + // + // Returns: + // Element (jQuery Object): jQuery object containing elements matching the + // selector within the scope. + S : S, + + // Description: + // Executes a function a max of once every n milliseconds + // + // Arguments: + // Func (Function): Function to be throttled. + // + // Delay (Integer): Function execution threshold in milliseconds. + // + // Returns: + // Lazy_function (Function): Function with throttling applied. + throttle : function (func, delay) { + var timer = null; + + return function () { + var context = this, args = arguments; + + if (timer == null) { + timer = setTimeout(function () { + func.apply(context, args); + timer = null; + }, delay); + } + }; + }, + + // Description: + // Executes a function when it stops being invoked for n seconds + // Modified version of _.debounce() http://underscorejs.org + // + // Arguments: + // Func (Function): Function to be debounced. + // + // Delay (Integer): Function execution threshold in milliseconds. + // + // Immediate (Bool): Whether the function should be called at the beginning + // of the delay instead of the end. Default is false. + // + // Returns: + // Lazy_function (Function): Function with debouncing applied. + debounce : function (func, delay, immediate) { + var timeout, result; + return function () { + var context = this, args = arguments; + var later = function () { + timeout = null; + if (!immediate) { + result = func.apply(context, args); + } + }; + var callNow = immediate && !timeout; + clearTimeout(timeout); + timeout = setTimeout(later, delay); + if (callNow) { + result = func.apply(context, args); + } + return result; + }; + }, + + // Description: + // Parses data-options attribute + // + // Arguments: + // El (jQuery Object): Element to be parsed. + // + // Returns: + // Options (Javascript Object): Contents of the element's data-options + // attribute. + data_options : function (el, data_attr_name) { + data_attr_name = data_attr_name || 'options'; + var opts = {}, ii, p, opts_arr, + data_options = function (el) { + var namespace = Foundation.global.namespace; + + if (namespace.length > 0) { + return el.data(namespace + '-' + data_attr_name); + } + + return el.data(data_attr_name); + }; + + var cached_options = data_options(el); + + if (typeof cached_options === 'object') { + return cached_options; + } + + opts_arr = (cached_options || ':').split(';'); + ii = opts_arr.length; + + function isNumber (o) { + return !isNaN (o - 0) && o !== null && o !== '' && o !== false && o !== true; + } + + function trim (str) { + if (typeof str === 'string') { + return $.trim(str); + } + return str; + } + + while (ii--) { + p = opts_arr[ii].split(':'); + p = [p[0], p.slice(1).join(':')]; + + if (/true/i.test(p[1])) { + p[1] = true; + } + if (/false/i.test(p[1])) { + p[1] = false; + } + if (isNumber(p[1])) { + if (p[1].indexOf('.') === -1) { + p[1] = parseInt(p[1], 10); + } else { + p[1] = parseFloat(p[1]); + } + } + + if (p.length === 2 && p[0].length > 0) { + opts[trim(p[0])] = trim(p[1]); + } + } + + return opts; + }, + + // Description: + // Adds JS-recognizable media queries + // + // Arguments: + // Media (String): Key string for the media query to be stored as in + // Foundation.media_queries + // + // Class (String): Class name for the generated tag + register_media : function (media, media_class) { + if (Foundation.media_queries[media] === undefined) { + $('head').append(''); + Foundation.media_queries[media] = removeQuotes($('.' + media_class).css('font-family')); + } + }, + + // Description: + // Add custom CSS within a JS-defined media query + // + // Arguments: + // Rule (String): CSS rule to be appended to the document. + // + // Media (String): Optional media query string for the CSS rule to be + // nested under. + add_custom_rule : function (rule, media) { + if (media === undefined && Foundation.stylesheet) { + Foundation.stylesheet.insertRule(rule, Foundation.stylesheet.cssRules.length); + } else { + var query = Foundation.media_queries[media]; + + if (query !== undefined) { + Foundation.stylesheet.insertRule('@media ' + + Foundation.media_queries[media] + '{ ' + rule + ' }', Foundation.stylesheet.cssRules.length); + } + } + }, + + // Description: + // Performs a callback function when an image is fully loaded + // + // Arguments: + // Image (jQuery Object): Image(s) to check if loaded. + // + // Callback (Function): Function to execute when image is fully loaded. + image_loaded : function (images, callback) { + var self = this, + unloaded = images.length; + + function pictures_has_height(images) { + var pictures_number = images.length; + + for (var i = pictures_number - 1; i >= 0; i--) { + if(images.attr('height') === undefined) { + return false; + }; + }; + + return true; + } + + if (unloaded === 0 || pictures_has_height(images)) { + callback(images); + } + + images.each(function () { + single_image_loaded(self.S(this), function () { + unloaded -= 1; + if (unloaded === 0) { + callback(images); + } + }); + }); + }, + + // Description: + // Returns a random, alphanumeric string + // + // Arguments: + // Length (Integer): Length of string to be generated. Defaults to random + // integer. + // + // Returns: + // Rand (String): Pseudo-random, alphanumeric string. + random_str : function () { + if (!this.fidx) { + this.fidx = 0; + } + this.prefix = this.prefix || [(this.name || 'F'), (+new Date).toString(36)].join('-'); + + return this.prefix + (this.fidx++).toString(36); + }, + + // Description: + // Helper for window.matchMedia + // + // Arguments: + // mq (String): Media query + // + // Returns: + // (Boolean): Whether the media query passes or not + match : function (mq) { + return window.matchMedia(mq).matches; + }, + + // Description: + // Helpers for checking Foundation default media queries with JS + // + // Returns: + // (Boolean): Whether the media query passes or not + + is_small_up : function () { + return this.match(Foundation.media_queries.small); + }, + + is_medium_up : function () { + return this.match(Foundation.media_queries.medium); + }, + + is_large_up : function () { + return this.match(Foundation.media_queries.large); + }, + + is_xlarge_up : function () { + return this.match(Foundation.media_queries.xlarge); + }, + + is_xxlarge_up : function () { + return this.match(Foundation.media_queries.xxlarge); + }, + + is_small_only : function () { + return !this.is_medium_up() && !this.is_large_up() && !this.is_xlarge_up() && !this.is_xxlarge_up(); + }, + + is_medium_only : function () { + return this.is_medium_up() && !this.is_large_up() && !this.is_xlarge_up() && !this.is_xxlarge_up(); + }, + + is_large_only : function () { + return this.is_medium_up() && this.is_large_up() && !this.is_xlarge_up() && !this.is_xxlarge_up(); + }, + + is_xlarge_only : function () { + return this.is_medium_up() && this.is_large_up() && this.is_xlarge_up() && !this.is_xxlarge_up(); + }, + + is_xxlarge_only : function () { + return this.is_medium_up() && this.is_large_up() && this.is_xlarge_up() && this.is_xxlarge_up(); + } + } + }; + + $.fn.foundation = function () { + var args = Array.prototype.slice.call(arguments, 0); + + return this.each(function () { + Foundation.init.apply(Foundation, [this].concat(args)); + return this; + }); + }; + +}(jQuery, window, window.document)); diff --git a/docs.helm.sh/rootfs/public/src/js/custom/foundation.offcanvas.js b/themes/helm/assets/js/foundation.offcanvas.js similarity index 100% rename from docs.helm.sh/rootfs/public/src/js/custom/foundation.offcanvas.js rename to themes/helm/assets/js/foundation.offcanvas.js diff --git a/docs.helm.sh/rootfs/public/src/js/custom/foundation.slider.js b/themes/helm/assets/js/foundation.slider.js similarity index 100% rename from docs.helm.sh/rootfs/public/src/js/custom/foundation.slider.js rename to themes/helm/assets/js/foundation.slider.js diff --git a/docs.helm.sh/rootfs/public/src/js/custom/foundation.tooltip.js b/themes/helm/assets/js/foundation.tooltip.js similarity index 100% rename from docs.helm.sh/rootfs/public/src/js/custom/foundation.tooltip.js rename to themes/helm/assets/js/foundation.tooltip.js diff --git a/docs.helm.sh/rootfs/public/src/js/custom/foundation.topbar.js b/themes/helm/assets/js/foundation.topbar.js similarity index 100% rename from docs.helm.sh/rootfs/public/src/js/custom/foundation.topbar.js rename to themes/helm/assets/js/foundation.topbar.js diff --git a/docs.helm.sh/rootfs/public/src/js/custom/jquery.js b/themes/helm/assets/js/jquery.js similarity index 100% rename from docs.helm.sh/rootfs/public/src/js/custom/jquery.js rename to themes/helm/assets/js/jquery.js diff --git a/themes/helm/assets/js/modernizr.js b/themes/helm/assets/js/modernizr.js new file mode 100644 index 0000000000..33653390e4 --- /dev/null +++ b/themes/helm/assets/js/modernizr.js @@ -0,0 +1,1406 @@ +/*! + * Modernizr v2.8.3 + * www.modernizr.com + * + * Copyright (c) Faruk Ates, Paul Irish, Alex Sexton + * Available under the BSD and MIT licenses: www.modernizr.com/license/ + */ + +/* + * Modernizr tests which native CSS3 and HTML5 features are available in + * the current UA and makes the results available to you in two ways: + * as properties on a global Modernizr object, and as classes on the + * element. This information allows you to progressively enhance + * your pages with a granular level of control over the experience. + * + * Modernizr has an optional (not included) conditional resource loader + * called Modernizr.load(), based on Yepnope.js (yepnopejs.com). + * To get a build that includes Modernizr.load(), as well as choosing + * which tests to include, go to www.modernizr.com/download/ + * + * Authors Faruk Ates, Paul Irish, Alex Sexton + * Contributors Ryan Seddon, Ben Alman + */ + +window.Modernizr = (function( window, document, undefined ) { + + var version = '2.8.3', + + Modernizr = {}, + + /*>>cssclasses*/ + // option for enabling the HTML classes to be added + enableClasses = true, + /*>>cssclasses*/ + + docElement = document.documentElement, + + /** + * Create our "modernizr" element that we do most feature tests on. + */ + mod = 'modernizr', + modElem = document.createElement(mod), + mStyle = modElem.style, + + /** + * Create the input element for various Web Forms feature tests. + */ + inputElem /*>>inputelem*/ = document.createElement('input') /*>>inputelem*/ , + + /*>>smile*/ + smile = ':)', + /*>>smile*/ + + toString = {}.toString, + + // TODO :: make the prefixes more granular + /*>>prefixes*/ + // List of property values to set for css tests. See ticket #21 + prefixes = ' -webkit- -moz- -o- -ms- '.split(' '), + /*>>prefixes*/ + + /*>>domprefixes*/ + // Following spec is to expose vendor-specific style properties as: + // elem.style.WebkitBorderRadius + // and the following would be incorrect: + // elem.style.webkitBorderRadius + + // Webkit ghosts their properties in lowercase but Opera & Moz do not. + // Microsoft uses a lowercase `ms` instead of the correct `Ms` in IE8+ + // erik.eae.net/archives/2008/03/10/21.48.10/ + + // More here: github.com/Modernizr/Modernizr/issues/issue/21 + omPrefixes = 'Webkit Moz O ms', + + cssomPrefixes = omPrefixes.split(' '), + + domPrefixes = omPrefixes.toLowerCase().split(' '), + /*>>domprefixes*/ + + /*>>ns*/ + ns = {'svg': 'http://www.w3.org/2000/svg'}, + /*>>ns*/ + + tests = {}, + inputs = {}, + attrs = {}, + + classes = [], + + slice = classes.slice, + + featureName, // used in testing loop + + + /*>>teststyles*/ + // Inject element with style element and some CSS rules + injectElementWithStyles = function( rule, callback, nodes, testnames ) { + + var style, ret, node, docOverflow, + div = document.createElement('div'), + // After page load injecting a fake body doesn't work so check if body exists + body = document.body, + // IE6 and 7 won't return offsetWidth or offsetHeight unless it's in the body element, so we fake it. + fakeBody = body || document.createElement('body'); + + if ( parseInt(nodes, 10) ) { + // In order not to give false positives we create a node for each test + // This also allows the method to scale for unspecified uses + while ( nodes-- ) { + node = document.createElement('div'); + node.id = testnames ? testnames[nodes] : mod + (nodes + 1); + div.appendChild(node); + } + } + + // '].join(''); + div.id = mod; + // IE6 will false positive on some tests due to the style element inside the test div somehow interfering offsetHeight, so insert it into body or fakebody. + // Opera will act all quirky when injecting elements in documentElement when page is served as xml, needs fakebody too. #270 + (body ? div : fakeBody).innerHTML += style; + fakeBody.appendChild(div); + if ( !body ) { + //avoid crashing IE8, if background image is used + fakeBody.style.background = ''; + //Safari 5.13/5.1.4 OSX stops loading if ::-webkit-scrollbar is used and scrollbars are visible + fakeBody.style.overflow = 'hidden'; + docOverflow = docElement.style.overflow; + docElement.style.overflow = 'hidden'; + docElement.appendChild(fakeBody); + } + + ret = callback(div, rule); + // If this is done after page load we don't want to remove the body so check if body exists + if ( !body ) { + fakeBody.parentNode.removeChild(fakeBody); + docElement.style.overflow = docOverflow; + } else { + div.parentNode.removeChild(div); + } + + return !!ret; + + }, + /*>>teststyles*/ + + /*>>mq*/ + // adapted from matchMedia polyfill + // by Scott Jehl and Paul Irish + // gist.github.com/786768 + testMediaQuery = function( mq ) { + + var matchMedia = window.matchMedia || window.msMatchMedia; + if ( matchMedia ) { + return matchMedia(mq) && matchMedia(mq).matches || false; + } + + var bool; + + injectElementWithStyles('@media ' + mq + ' { #' + mod + ' { position: absolute; } }', function( node ) { + bool = (window.getComputedStyle ? + getComputedStyle(node, null) : + node.currentStyle)['position'] == 'absolute'; + }); + + return bool; + + }, + /*>>mq*/ + + + /*>>hasevent*/ + // + // isEventSupported determines if a given element supports the given event + // kangax.github.com/iseventsupported/ + // + // The following results are known incorrects: + // Modernizr.hasEvent("webkitTransitionEnd", elem) // false negative + // Modernizr.hasEvent("textInput") // in Webkit. github.com/Modernizr/Modernizr/issues/333 + // ... + isEventSupported = (function() { + + var TAGNAMES = { + 'select': 'input', 'change': 'input', + 'submit': 'form', 'reset': 'form', + 'error': 'img', 'load': 'img', 'abort': 'img' + }; + + function isEventSupported( eventName, element ) { + + element = element || document.createElement(TAGNAMES[eventName] || 'div'); + eventName = 'on' + eventName; + + // When using `setAttribute`, IE skips "unload", WebKit skips "unload" and "resize", whereas `in` "catches" those + var isSupported = eventName in element; + + if ( !isSupported ) { + // If it has no `setAttribute` (i.e. doesn't implement Node interface), try generic element + if ( !element.setAttribute ) { + element = document.createElement('div'); + } + if ( element.setAttribute && element.removeAttribute ) { + element.setAttribute(eventName, ''); + isSupported = is(element[eventName], 'function'); + + // If property was created, "remove it" (by setting value to `undefined`) + if ( !is(element[eventName], 'undefined') ) { + element[eventName] = undefined; + } + element.removeAttribute(eventName); + } + } + + element = null; + return isSupported; + } + return isEventSupported; + })(), + /*>>hasevent*/ + + // TODO :: Add flag for hasownprop ? didn't last time + + // hasOwnProperty shim by kangax needed for Safari 2.0 support + _hasOwnProperty = ({}).hasOwnProperty, hasOwnProp; + + if ( !is(_hasOwnProperty, 'undefined') && !is(_hasOwnProperty.call, 'undefined') ) { + hasOwnProp = function (object, property) { + return _hasOwnProperty.call(object, property); + }; + } + else { + hasOwnProp = function (object, property) { /* yes, this can give false positives/negatives, but most of the time we don't care about those */ + return ((property in object) && is(object.constructor.prototype[property], 'undefined')); + }; + } + + // Adapted from ES5-shim https://github.com/kriskowal/es5-shim/blob/master/es5-shim.js + // es5.github.com/#x15.3.4.5 + + if (!Function.prototype.bind) { + Function.prototype.bind = function bind(that) { + + var target = this; + + if (typeof target != "function") { + throw new TypeError(); + } + + var args = slice.call(arguments, 1), + bound = function () { + + if (this instanceof bound) { + + var F = function(){}; + F.prototype = target.prototype; + var self = new F(); + + var result = target.apply( + self, + args.concat(slice.call(arguments)) + ); + if (Object(result) === result) { + return result; + } + return self; + + } else { + + return target.apply( + that, + args.concat(slice.call(arguments)) + ); + + } + + }; + + return bound; + }; + } + + /** + * setCss applies given styles to the Modernizr DOM node. + */ + function setCss( str ) { + mStyle.cssText = str; + } + + /** + * setCssAll extrapolates all vendor-specific css strings. + */ + function setCssAll( str1, str2 ) { + return setCss(prefixes.join(str1 + ';') + ( str2 || '' )); + } + + /** + * is returns a boolean for if typeof obj is exactly type. + */ + function is( obj, type ) { + return typeof obj === type; + } + + /** + * contains returns a boolean for if substr is found within str. + */ + function contains( str, substr ) { + return !!~('' + str).indexOf(substr); + } + + /*>>testprop*/ + + // testProps is a generic CSS / DOM property test. + + // In testing support for a given CSS property, it's legit to test: + // `elem.style[styleName] !== undefined` + // If the property is supported it will return an empty string, + // if unsupported it will return undefined. + + // We'll take advantage of this quick test and skip setting a style + // on our modernizr element, but instead just testing undefined vs + // empty string. + + // Because the testing of the CSS property names (with "-", as + // opposed to the camelCase DOM properties) is non-portable and + // non-standard but works in WebKit and IE (but not Gecko or Opera), + // we explicitly reject properties with dashes so that authors + // developing in WebKit or IE first don't end up with + // browser-specific content by accident. + + function testProps( props, prefixed ) { + for ( var i in props ) { + var prop = props[i]; + if ( !contains(prop, "-") && mStyle[prop] !== undefined ) { + return prefixed == 'pfx' ? prop : true; + } + } + return false; + } + /*>>testprop*/ + + // TODO :: add testDOMProps + /** + * testDOMProps is a generic DOM property test; if a browser supports + * a certain property, it won't return undefined for it. + */ + function testDOMProps( props, obj, elem ) { + for ( var i in props ) { + var item = obj[props[i]]; + if ( item !== undefined) { + + // return the property name as a string + if (elem === false) return props[i]; + + // let's bind a function + if (is(item, 'function')){ + // default to autobind unless override + return item.bind(elem || obj); + } + + // return the unbound function or obj or value + return item; + } + } + return false; + } + + /*>>testallprops*/ + /** + * testPropsAll tests a list of DOM properties we want to check against. + * We specify literally ALL possible (known and/or likely) properties on + * the element including the non-vendor prefixed one, for forward- + * compatibility. + */ + function testPropsAll( prop, prefixed, elem ) { + + var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1), + props = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' '); + + // did they call .prefixed('boxSizing') or are we just testing a prop? + if(is(prefixed, "string") || is(prefixed, "undefined")) { + return testProps(props, prefixed); + + // otherwise, they called .prefixed('requestAnimationFrame', window[, elem]) + } else { + props = (prop + ' ' + (domPrefixes).join(ucProp + ' ') + ucProp).split(' '); + return testDOMProps(props, prefixed, elem); + } + } + /*>>testallprops*/ + + + /** + * Tests + * ----- + */ + + // The *new* flexbox + // dev.w3.org/csswg/css3-flexbox + + tests['flexbox'] = function() { + return testPropsAll('flexWrap'); + }; + + // The *old* flexbox + // www.w3.org/TR/2009/WD-css3-flexbox-20090723/ + + tests['flexboxlegacy'] = function() { + return testPropsAll('boxDirection'); + }; + + // On the S60 and BB Storm, getContext exists, but always returns undefined + // so we actually have to call getContext() to verify + // github.com/Modernizr/Modernizr/issues/issue/97/ + + tests['canvas'] = function() { + var elem = document.createElement('canvas'); + return !!(elem.getContext && elem.getContext('2d')); + }; + + tests['canvastext'] = function() { + return !!(Modernizr['canvas'] && is(document.createElement('canvas').getContext('2d').fillText, 'function')); + }; + + // webk.it/70117 is tracking a legit WebGL feature detect proposal + + // We do a soft detect which may false positive in order to avoid + // an expensive context creation: bugzil.la/732441 + + tests['webgl'] = function() { + return !!window.WebGLRenderingContext; + }; + + /* + * The Modernizr.touch test only indicates if the browser supports + * touch events, which does not necessarily reflect a touchscreen + * device, as evidenced by tablets running Windows 7 or, alas, + * the Palm Pre / WebOS (touch) phones. + * + * Additionally, Chrome (desktop) used to lie about its support on this, + * but that has since been rectified: crbug.com/36415 + * + * We also test for Firefox 4 Multitouch Support. + * + * For more info, see: modernizr.github.com/Modernizr/touch.html + */ + + tests['touch'] = function() { + var bool; + + if(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) { + bool = true; + } else { + injectElementWithStyles(['@media (',prefixes.join('touch-enabled),('),mod,')','{#modernizr{top:9px;position:absolute}}'].join(''), function( node ) { + bool = node.offsetTop === 9; + }); + } + + return bool; + }; + + + // geolocation is often considered a trivial feature detect... + // Turns out, it's quite tricky to get right: + // + // Using !!navigator.geolocation does two things we don't want. It: + // 1. Leaks memory in IE9: github.com/Modernizr/Modernizr/issues/513 + // 2. Disables page caching in WebKit: webk.it/43956 + // + // Meanwhile, in Firefox < 8, an about:config setting could expose + // a false positive that would throw an exception: bugzil.la/688158 + + tests['geolocation'] = function() { + return 'geolocation' in navigator; + }; + + + tests['postmessage'] = function() { + return !!window.postMessage; + }; + + + // Chrome incognito mode used to throw an exception when using openDatabase + // It doesn't anymore. + tests['websqldatabase'] = function() { + return !!window.openDatabase; + }; + + // Vendors had inconsistent prefixing with the experimental Indexed DB: + // - Webkit's implementation is accessible through webkitIndexedDB + // - Firefox shipped moz_indexedDB before FF4b9, but since then has been mozIndexedDB + // For speed, we don't test the legacy (and beta-only) indexedDB + tests['indexedDB'] = function() { + return !!testPropsAll("indexedDB", window); + }; + + // documentMode logic from YUI to filter out IE8 Compat Mode + // which false positives. + tests['hashchange'] = function() { + return isEventSupported('hashchange', window) && (document.documentMode === undefined || document.documentMode > 7); + }; + + // Per 1.6: + // This used to be Modernizr.historymanagement but the longer + // name has been deprecated in favor of a shorter and property-matching one. + // The old API is still available in 1.6, but as of 2.0 will throw a warning, + // and in the first release thereafter disappear entirely. + tests['history'] = function() { + return !!(window.history && history.pushState); + }; + + tests['draganddrop'] = function() { + var div = document.createElement('div'); + return ('draggable' in div) || ('ondragstart' in div && 'ondrop' in div); + }; + + // FF3.6 was EOL'ed on 4/24/12, but the ESR version of FF10 + // will be supported until FF19 (2/12/13), at which time, ESR becomes FF17. + // FF10 still uses prefixes, so check for it until then. + // for more ESR info, see: mozilla.org/en-US/firefox/organizations/faq/ + tests['websockets'] = function() { + return 'WebSocket' in window || 'MozWebSocket' in window; + }; + + + // css-tricks.com/rgba-browser-support/ + tests['rgba'] = function() { + // Set an rgba() color and check the returned value + + setCss('background-color:rgba(150,255,150,.5)'); + + return contains(mStyle.backgroundColor, 'rgba'); + }; + + tests['hsla'] = function() { + // Same as rgba(), in fact, browsers re-map hsla() to rgba() internally, + // except IE9 who retains it as hsla + + setCss('background-color:hsla(120,40%,100%,.5)'); + + return contains(mStyle.backgroundColor, 'rgba') || contains(mStyle.backgroundColor, 'hsla'); + }; + + tests['multiplebgs'] = function() { + // Setting multiple images AND a color on the background shorthand property + // and then querying the style.background property value for the number of + // occurrences of "url(" is a reliable method for detecting ACTUAL support for this! + + setCss('background:url(https://),url(https://),red url(https://)'); + + // If the UA supports multiple backgrounds, there should be three occurrences + // of the string "url(" in the return value for elemStyle.background + + return (/(url\s*\(.*?){3}/).test(mStyle.background); + }; + + + + // this will false positive in Opera Mini + // github.com/Modernizr/Modernizr/issues/396 + + tests['backgroundsize'] = function() { + return testPropsAll('backgroundSize'); + }; + + tests['borderimage'] = function() { + return testPropsAll('borderImage'); + }; + + + // Super comprehensive table about all the unique implementations of + // border-radius: muddledramblings.com/table-of-css3-border-radius-compliance + + tests['borderradius'] = function() { + return testPropsAll('borderRadius'); + }; + + // WebOS unfortunately false positives on this test. + tests['boxshadow'] = function() { + return testPropsAll('boxShadow'); + }; + + // FF3.0 will false positive on this test + tests['textshadow'] = function() { + return document.createElement('div').style.textShadow === ''; + }; + + + tests['opacity'] = function() { + // Browsers that actually have CSS Opacity implemented have done so + // according to spec, which means their return values are within the + // range of [0.0,1.0] - including the leading zero. + + setCssAll('opacity:.55'); + + // The non-literal . in this regex is intentional: + // German Chrome returns this value as 0,55 + // github.com/Modernizr/Modernizr/issues/#issue/59/comment/516632 + return (/^0.55$/).test(mStyle.opacity); + }; + + + // Note, Android < 4 will pass this test, but can only animate + // a single property at a time + // goo.gl/v3V4Gp + tests['cssanimations'] = function() { + return testPropsAll('animationName'); + }; + + + tests['csscolumns'] = function() { + return testPropsAll('columnCount'); + }; + + + tests['cssgradients'] = function() { + /** + * For CSS Gradients syntax, please see: + * webkit.org/blog/175/introducing-css-gradients/ + * developer.mozilla.org/en/CSS/-moz-linear-gradient + * developer.mozilla.org/en/CSS/-moz-radial-gradient + * dev.w3.org/csswg/css3-images/#gradients- + */ + + var str1 = 'background-image:', + str2 = 'gradient(linear,left top,right bottom,from(#9f9),to(white));', + str3 = 'linear-gradient(left top,#9f9, white);'; + + setCss( + // legacy webkit syntax (FIXME: remove when syntax not in use anymore) + (str1 + '-webkit- '.split(' ').join(str2 + str1) + + // standard syntax // trailing 'background-image:' + prefixes.join(str3 + str1)).slice(0, -str1.length) + ); + + return contains(mStyle.backgroundImage, 'gradient'); + }; + + + tests['cssreflections'] = function() { + return testPropsAll('boxReflect'); + }; + + + tests['csstransforms'] = function() { + return !!testPropsAll('transform'); + }; + + + tests['csstransforms3d'] = function() { + + var ret = !!testPropsAll('perspective'); + + // Webkit's 3D transforms are passed off to the browser's own graphics renderer. + // It works fine in Safari on Leopard and Snow Leopard, but not in Chrome in + // some conditions. As a result, Webkit typically recognizes the syntax but + // will sometimes throw a false positive, thus we must do a more thorough check: + if ( ret && 'webkitPerspective' in docElement.style ) { + + // Webkit allows this media query to succeed only if the feature is enabled. + // `@media (transform-3d),(-webkit-transform-3d){ ... }` + injectElementWithStyles('@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}', function( node, rule ) { + ret = node.offsetLeft === 9 && node.offsetHeight === 3; + }); + } + return ret; + }; + + + tests['csstransitions'] = function() { + return testPropsAll('transition'); + }; + + + /*>>fontface*/ + // @font-face detection routine by Diego Perini + // javascript.nwbox.com/CSSSupport/ + + // false positives: + // WebOS github.com/Modernizr/Modernizr/issues/342 + // WP7 github.com/Modernizr/Modernizr/issues/538 + tests['fontface'] = function() { + var bool; + + injectElementWithStyles('@font-face {font-family:"font";src:url("https://")}', function( node, rule ) { + var style = document.getElementById('smodernizr'), + sheet = style.sheet || style.styleSheet, + cssText = sheet ? (sheet.cssRules && sheet.cssRules[0] ? sheet.cssRules[0].cssText : sheet.cssText || '') : ''; + + bool = /src/i.test(cssText) && cssText.indexOf(rule.split(' ')[0]) === 0; + }); + + return bool; + }; + /*>>fontface*/ + + // CSS generated content detection + tests['generatedcontent'] = function() { + var bool; + + injectElementWithStyles(['#',mod,'{font:0/0 a}#',mod,':after{content:"',smile,'";visibility:hidden;font:3px/1 a}'].join(''), function( node ) { + bool = node.offsetHeight >= 3; + }); + + return bool; + }; + + + + // These tests evaluate support of the video/audio elements, as well as + // testing what types of content they support. + // + // We're using the Boolean constructor here, so that we can extend the value + // e.g. Modernizr.video // true + // Modernizr.video.ogg // 'probably' + // + // Codec values from : github.com/NielsLeenheer/html5test/blob/9106a8/index.html#L845 + // thx to NielsLeenheer and zcorpan + + // Note: in some older browsers, "no" was a return value instead of empty string. + // It was live in FF3.5.0 and 3.5.1, but fixed in 3.5.2 + // It was also live in Safari 4.0.0 - 4.0.4, but fixed in 4.0.5 + + tests['video'] = function() { + var elem = document.createElement('video'), + bool = false; + + // IE9 Running on Windows Server SKU can cause an exception to be thrown, bug #224 + try { + if ( bool = !!elem.canPlayType ) { + bool = new Boolean(bool); + bool.ogg = elem.canPlayType('video/ogg; codecs="theora"') .replace(/^no$/,''); + + // Without QuickTime, this value will be `undefined`. github.com/Modernizr/Modernizr/issues/546 + bool.h264 = elem.canPlayType('video/mp4; codecs="avc1.42E01E"') .replace(/^no$/,''); + + bool.webm = elem.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,''); + } + + } catch(e) { } + + return bool; + }; + + tests['audio'] = function() { + var elem = document.createElement('audio'), + bool = false; + + try { + if ( bool = !!elem.canPlayType ) { + bool = new Boolean(bool); + bool.ogg = elem.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,''); + bool.mp3 = elem.canPlayType('audio/mpeg;') .replace(/^no$/,''); + + // Mimetypes accepted: + // developer.mozilla.org/En/Media_formats_supported_by_the_audio_and_video_elements + // bit.ly/iphoneoscodecs + bool.wav = elem.canPlayType('audio/wav; codecs="1"') .replace(/^no$/,''); + bool.m4a = ( elem.canPlayType('audio/x-m4a;') || + elem.canPlayType('audio/aac;')) .replace(/^no$/,''); + } + } catch(e) { } + + return bool; + }; + + + // In FF4, if disabled, window.localStorage should === null. + + // Normally, we could not test that directly and need to do a + // `('localStorage' in window) && ` test first because otherwise Firefox will + // throw bugzil.la/365772 if cookies are disabled + + // Also in iOS5 Private Browsing mode, attempting to use localStorage.setItem + // will throw the exception: + // QUOTA_EXCEEDED_ERRROR DOM Exception 22. + // Peculiarly, getItem and removeItem calls do not throw. + + // Because we are forced to try/catch this, we'll go aggressive. + + // Just FWIW: IE8 Compat mode supports these features completely: + // www.quirksmode.org/dom/html5.html + // But IE8 doesn't support either with local files + + tests['localstorage'] = function() { + try { + localStorage.setItem(mod, mod); + localStorage.removeItem(mod); + return true; + } catch(e) { + return false; + } + }; + + tests['sessionstorage'] = function() { + try { + sessionStorage.setItem(mod, mod); + sessionStorage.removeItem(mod); + return true; + } catch(e) { + return false; + } + }; + + + tests['webworkers'] = function() { + return !!window.Worker; + }; + + + tests['applicationcache'] = function() { + return !!window.applicationCache; + }; + + + // Thanks to Erik Dahlstrom + tests['svg'] = function() { + return !!document.createElementNS && !!document.createElementNS(ns.svg, 'svg').createSVGRect; + }; + + // specifically for SVG inline in HTML, not within XHTML + // test page: paulirish.com/demo/inline-svg + tests['inlinesvg'] = function() { + var div = document.createElement('div'); + div.innerHTML = ''; + return (div.firstChild && div.firstChild.namespaceURI) == ns.svg; + }; + + // SVG SMIL animation + tests['smil'] = function() { + return !!document.createElementNS && /SVGAnimate/.test(toString.call(document.createElementNS(ns.svg, 'animate'))); + }; + + // This test is only for clip paths in SVG proper, not clip paths on HTML content + // demo: srufaculty.sru.edu/david.dailey/svg/newstuff/clipPath4.svg + + // However read the comments to dig into applying SVG clippaths to HTML content here: + // github.com/Modernizr/Modernizr/issues/213#issuecomment-1149491 + tests['svgclippaths'] = function() { + return !!document.createElementNS && /SVGClipPath/.test(toString.call(document.createElementNS(ns.svg, 'clipPath'))); + }; + + /*>>webforms*/ + // input features and input types go directly onto the ret object, bypassing the tests loop. + // Hold this guy to execute in a moment. + function webforms() { + /*>>input*/ + // Run through HTML5's new input attributes to see if the UA understands any. + // We're using f which is the element created early on + // Mike Taylr has created a comprehensive resource for testing these attributes + // when applied to all input types: + // miketaylr.com/code/input-type-attr.html + // spec: www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary + + // Only input placeholder is tested while textarea's placeholder is not. + // Currently Safari 4 and Opera 11 have support only for the input placeholder + // Both tests are available in feature-detects/forms-placeholder.js + Modernizr['input'] = (function( props ) { + for ( var i = 0, len = props.length; i < len; i++ ) { + attrs[ props[i] ] = !!(props[i] in inputElem); + } + if (attrs.list){ + // safari false positive's on datalist: webk.it/74252 + // see also github.com/Modernizr/Modernizr/issues/146 + attrs.list = !!(document.createElement('datalist') && window.HTMLDataListElement); + } + return attrs; + })('autocomplete autofocus list placeholder max min multiple pattern required step'.split(' ')); + /*>>input*/ + + /*>>inputtypes*/ + // Run through HTML5's new input types to see if the UA understands any. + // This is put behind the tests runloop because it doesn't return a + // true/false like all the other tests; instead, it returns an object + // containing each input type with its corresponding true/false value + + // Big thanks to @miketaylr for the html5 forms expertise. miketaylr.com/ + Modernizr['inputtypes'] = (function(props) { + + for ( var i = 0, bool, inputElemType, defaultView, len = props.length; i < len; i++ ) { + + inputElem.setAttribute('type', inputElemType = props[i]); + bool = inputElem.type !== 'text'; + + // We first check to see if the type we give it sticks.. + // If the type does, we feed it a textual value, which shouldn't be valid. + // If the value doesn't stick, we know there's input sanitization which infers a custom UI + if ( bool ) { + + inputElem.value = smile; + inputElem.style.cssText = 'position:absolute;visibility:hidden;'; + + if ( /^range$/.test(inputElemType) && inputElem.style.WebkitAppearance !== undefined ) { + + docElement.appendChild(inputElem); + defaultView = document.defaultView; + + // Safari 2-4 allows the smiley as a value, despite making a slider + bool = defaultView.getComputedStyle && + defaultView.getComputedStyle(inputElem, null).WebkitAppearance !== 'textfield' && + // Mobile android web browser has false positive, so must + // check the height to see if the widget is actually there. + (inputElem.offsetHeight !== 0); + + docElement.removeChild(inputElem); + + } else if ( /^(search|tel)$/.test(inputElemType) ){ + // Spec doesn't define any special parsing or detectable UI + // behaviors so we pass these through as true + + // Interestingly, opera fails the earlier test, so it doesn't + // even make it here. + + } else if ( /^(url|email)$/.test(inputElemType) ) { + // Real url and email support comes with prebaked validation. + bool = inputElem.checkValidity && inputElem.checkValidity() === false; + + } else { + // If the upgraded input compontent rejects the :) text, we got a winner + bool = inputElem.value != smile; + } + } + + inputs[ props[i] ] = !!bool; + } + return inputs; + })('search tel url email datetime date month week time datetime-local number range color'.split(' ')); + /*>>inputtypes*/ + } + /*>>webforms*/ + + + // End of test definitions + // ----------------------- + + + + // Run through all tests and detect their support in the current UA. + // todo: hypothetically we could be doing an array of tests and use a basic loop here. + for ( var feature in tests ) { + if ( hasOwnProp(tests, feature) ) { + // run the test, throw the return value into the Modernizr, + // then based on that boolean, define an appropriate className + // and push it into an array of classes we'll join later. + featureName = feature.toLowerCase(); + Modernizr[featureName] = tests[feature](); + + classes.push((Modernizr[featureName] ? '' : 'no-') + featureName); + } + } + + /*>>webforms*/ + // input tests need to run. + Modernizr.input || webforms(); + /*>>webforms*/ + + + /** + * addTest allows the user to define their own feature tests + * the result will be added onto the Modernizr object, + * as well as an appropriate className set on the html element + * + * @param feature - String naming the feature + * @param test - Function returning true if feature is supported, false if not + */ + Modernizr.addTest = function ( feature, test ) { + if ( typeof feature == 'object' ) { + for ( var key in feature ) { + if ( hasOwnProp( feature, key ) ) { + Modernizr.addTest( key, feature[ key ] ); + } + } + } else { + + feature = feature.toLowerCase(); + + if ( Modernizr[feature] !== undefined ) { + // we're going to quit if you're trying to overwrite an existing test + // if we were to allow it, we'd do this: + // var re = new RegExp("\\b(no-)?" + feature + "\\b"); + // docElement.className = docElement.className.replace( re, '' ); + // but, no rly, stuff 'em. + return Modernizr; + } + + test = typeof test == 'function' ? test() : test; + + if (typeof enableClasses !== "undefined" && enableClasses) { + docElement.className += ' ' + (test ? '' : 'no-') + feature; + } + Modernizr[feature] = test; + + } + + return Modernizr; // allow chaining. + }; + + + // Reset modElem.cssText to nothing to reduce memory footprint. + setCss(''); + modElem = inputElem = null; + + /*>>shiv*/ + /** + * @preserve HTML5 Shiv prev3.7.1 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed + */ + ;(function(window, document) { + /*jshint evil:true */ + /** version */ + var version = '3.7.0'; + + /** Preset options */ + var options = window.html5 || {}; + + /** Used to skip problem elements */ + var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i; + + /** Not all elements can be cloned in IE **/ + var saveClones = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i; + + /** Detect whether the browser supports default html5 styles */ + var supportsHtml5Styles; + + /** Name of the expando, to work with multiple documents or to re-shiv one document */ + var expando = '_html5shiv'; + + /** The id for the the documents expando */ + var expanID = 0; + + /** Cached data for each document */ + var expandoData = {}; + + /** Detect whether the browser supports unknown elements */ + var supportsUnknownElements; + + (function() { + try { + var a = document.createElement('a'); + a.innerHTML = ''; + //if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles + supportsHtml5Styles = ('hidden' in a); + + supportsUnknownElements = a.childNodes.length == 1 || (function() { + // assign a false positive if unable to shiv + (document.createElement)('a'); + var frag = document.createDocumentFragment(); + return ( + typeof frag.cloneNode == 'undefined' || + typeof frag.createDocumentFragment == 'undefined' || + typeof frag.createElement == 'undefined' + ); + }()); + } catch(e) { + // assign a false positive if detection fails => unable to shiv + supportsHtml5Styles = true; + supportsUnknownElements = true; + } + + }()); + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a style sheet with the given CSS text and adds it to the document. + * @private + * @param {Document} ownerDocument The document. + * @param {String} cssText The CSS text. + * @returns {StyleSheet} The style element. + */ + function addStyleSheet(ownerDocument, cssText) { + var p = ownerDocument.createElement('p'), + parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement; + + p.innerHTML = 'x'; + return parent.insertBefore(p.lastChild, parent.firstChild); + } + + /** + * Returns the value of `html5.elements` as an array. + * @private + * @returns {Array} An array of shived element node names. + */ + function getElements() { + var elements = html5.elements; + return typeof elements == 'string' ? elements.split(' ') : elements; + } + + /** + * Returns the data associated to the given document + * @private + * @param {Document} ownerDocument The document. + * @returns {Object} An object of data. + */ + function getExpandoData(ownerDocument) { + var data = expandoData[ownerDocument[expando]]; + if (!data) { + data = {}; + expanID++; + ownerDocument[expando] = expanID; + expandoData[expanID] = data; + } + return data; + } + + /** + * returns a shived element for the given nodeName and document + * @memberOf html5 + * @param {String} nodeName name of the element + * @param {Document} ownerDocument The context document. + * @returns {Object} The shived element. + */ + function createElement(nodeName, ownerDocument, data){ + if (!ownerDocument) { + ownerDocument = document; + } + if(supportsUnknownElements){ + return ownerDocument.createElement(nodeName); + } + if (!data) { + data = getExpandoData(ownerDocument); + } + var node; + + if (data.cache[nodeName]) { + node = data.cache[nodeName].cloneNode(); + } else if (saveClones.test(nodeName)) { + node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode(); + } else { + node = data.createElem(nodeName); + } + + // Avoid adding some elements to fragments in IE < 9 because + // * Attributes like `name` or `type` cannot be set/changed once an element + // is inserted into a document/fragment + // * Link elements with `src` attributes that are inaccessible, as with + // a 403 response, will cause the tab/window to crash + // * Script elements appended to fragments will execute when their `src` + // or `text` property is set + return node.canHaveChildren && !reSkip.test(nodeName) && !node.tagUrn ? data.frag.appendChild(node) : node; + } + + /** + * returns a shived DocumentFragment for the given document + * @memberOf html5 + * @param {Document} ownerDocument The context document. + * @returns {Object} The shived DocumentFragment. + */ + function createDocumentFragment(ownerDocument, data){ + if (!ownerDocument) { + ownerDocument = document; + } + if(supportsUnknownElements){ + return ownerDocument.createDocumentFragment(); + } + data = data || getExpandoData(ownerDocument); + var clone = data.frag.cloneNode(), + i = 0, + elems = getElements(), + l = elems.length; + for(;i>shiv*/ + + // Assign private properties to the return object with prefix + Modernizr._version = version; + + // expose these for the plugin API. Look in the source for how to join() them against your input + /*>>prefixes*/ + Modernizr._prefixes = prefixes; + /*>>prefixes*/ + /*>>domprefixes*/ + Modernizr._domPrefixes = domPrefixes; + Modernizr._cssomPrefixes = cssomPrefixes; + /*>>domprefixes*/ + + /*>>mq*/ + // Modernizr.mq tests a given media query, live against the current state of the window + // A few important notes: + // * If a browser does not support media queries at all (eg. oldIE) the mq() will always return false + // * A max-width or orientation query will be evaluated against the current state, which may change later. + // * You must specify values. Eg. If you are testing support for the min-width media query use: + // Modernizr.mq('(min-width:0)') + // usage: + // Modernizr.mq('only screen and (max-width:768)') + Modernizr.mq = testMediaQuery; + /*>>mq*/ + + /*>>hasevent*/ + // Modernizr.hasEvent() detects support for a given event, with an optional element to test on + // Modernizr.hasEvent('gesturestart', elem) + Modernizr.hasEvent = isEventSupported; + /*>>hasevent*/ + + /*>>testprop*/ + // Modernizr.testProp() investigates whether a given style property is recognized + // Note that the property names must be provided in the camelCase variant. + // Modernizr.testProp('pointerEvents') + Modernizr.testProp = function(prop){ + return testProps([prop]); + }; + /*>>testprop*/ + + /*>>testallprops*/ + // Modernizr.testAllProps() investigates whether a given style property, + // or any of its vendor-prefixed variants, is recognized + // Note that the property names must be provided in the camelCase variant. + // Modernizr.testAllProps('boxSizing') + Modernizr.testAllProps = testPropsAll; + /*>>testallprops*/ + + + /*>>teststyles*/ + // Modernizr.testStyles() allows you to add custom styles to the document and test an element afterwards + // Modernizr.testStyles('#modernizr { position:absolute }', function(elem, rule){ ... }) + Modernizr.testStyles = injectElementWithStyles; + /*>>teststyles*/ + + + /*>>prefixed*/ + // Modernizr.prefixed() returns the prefixed or nonprefixed property name variant of your input + // Modernizr.prefixed('boxSizing') // 'MozBoxSizing' + + // Properties must be passed as dom-style camelcase, rather than `box-sizing` hypentated style. + // Return values will also be the camelCase variant, if you need to translate that to hypenated style use: + // + // str.replace(/([A-Z])/g, function(str,m1){ return '-' + m1.toLowerCase(); }).replace(/^ms-/,'-ms-'); + + // If you're trying to ascertain which transition end event to bind to, you might do something like... + // + // var transEndEventNames = { + // 'WebkitTransition' : 'webkitTransitionEnd', + // 'MozTransition' : 'transitionend', + // 'OTransition' : 'oTransitionEnd', + // 'msTransition' : 'MSTransitionEnd', + // 'transition' : 'transitionend' + // }, + // transEndEventName = transEndEventNames[ Modernizr.prefixed('transition') ]; + + Modernizr.prefixed = function(prop, obj, elem){ + if(!obj) { + return testPropsAll(prop, 'pfx'); + } else { + // Testing DOM property e.g. Modernizr.prefixed('requestAnimationFrame', window) // 'mozRequestAnimationFrame' + return testPropsAll(prop, obj, elem); + } + }; + /*>>prefixed*/ + + + /*>>cssclasses*/ + // Remove "no-js" class from element, if it exists: + docElement.className = docElement.className.replace(/(^|\s)no-js(\s|$)/, '$1$2') + + + // Add the new classes to the element. + (enableClasses ? ' js ' + classes.join(' ') : ''); + /*>>cssclasses*/ + + return Modernizr; + +})(this, this.document); diff --git a/themes/helm/assets/sass/bulma/bulma.sass b/themes/helm/assets/sass/bulma/bulma.sass new file mode 100644 index 0000000000..d1c1a1d272 --- /dev/null +++ b/themes/helm/assets/sass/bulma/bulma.sass @@ -0,0 +1,9 @@ +@charset "utf-8" +/*! bulma.io v0.8.0 | MIT License | github.com/jgthms/bulma */ +@import "sass/utilities/_all" +@import "sass/base/_all" +@import "sass/elements/_all" +@import "sass/form/_all" +@import "sass/components/_all" +@import "sass/grid/_all" +@import "sass/layout/_all" diff --git a/themes/helm/assets/sass/bulma/sass/base/_all.sass b/themes/helm/assets/sass/bulma/sass/base/_all.sass new file mode 100644 index 0000000000..e913d6ba39 --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/base/_all.sass @@ -0,0 +1,5 @@ +@charset "utf-8" + +@import "minireset.sass" +@import "generic.sass" +@import "helpers.sass" diff --git a/themes/helm/assets/sass/bulma/sass/base/generic.sass b/themes/helm/assets/sass/bulma/sass/base/generic.sass new file mode 100644 index 0000000000..31eedfe9b5 --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/base/generic.sass @@ -0,0 +1,142 @@ +$body-background-color: $scheme-main !default +$body-size: 16px !default +$body-min-width: 300px !default +$body-rendering: optimizeLegibility !default +$body-family: $family-primary !default +$body-overflow-x: hidden !default +$body-overflow-y: scroll !default + +$body-color: $text !default +$body-font-size: 1em !default +$body-weight: $weight-normal !default +$body-line-height: 1.5 !default + +$code-family: $family-code !default +$code-padding: 0.25em 0.5em 0.25em !default +$code-weight: normal !default +$code-size: 0.875em !default + +$small-font-size: 0.875em !default + +$hr-background-color: $background !default +$hr-height: 2px !default +$hr-margin: 1.5rem 0 !default + +$strong-color: $text-strong !default +$strong-weight: $weight-bold !default + +$pre-font-size: 0.875em !default +$pre-padding: 1.25rem 1.5rem !default +$pre-code-font-size: 1em !default + +html + background-color: $body-background-color + font-size: $body-size + -moz-osx-font-smoothing: grayscale + -webkit-font-smoothing: antialiased + min-width: $body-min-width + overflow-x: $body-overflow-x + overflow-y: $body-overflow-y + text-rendering: $body-rendering + text-size-adjust: 100% + +article, +aside, +figure, +footer, +header, +hgroup, +section + display: block + +body, +button, +input, +select, +textarea + font-family: $body-family + +code, +pre + -moz-osx-font-smoothing: auto + -webkit-font-smoothing: auto + font-family: $code-family + +body + color: $body-color + font-size: $body-font-size + font-weight: $body-weight + line-height: $body-line-height + +// Inline + +a + color: $link + cursor: pointer + text-decoration: none + strong + color: currentColor + &:hover + color: $link-hover + +code + background-color: $code-background + color: $code + font-size: $code-size + font-weight: $code-weight + padding: $code-padding + +hr + background-color: $hr-background-color + border: none + display: block + height: $hr-height + margin: $hr-margin + +img + height: auto + max-width: 100% + +input[type="checkbox"], +input[type="radio"] + vertical-align: baseline + +small + font-size: $small-font-size + +span + font-style: inherit + font-weight: inherit + +strong + color: $strong-color + font-weight: $strong-weight + +// Block + +fieldset + border: none + +pre + +overflow-touch + background-color: $pre-background + color: $pre + font-size: $pre-font-size + overflow-x: auto + padding: $pre-padding + white-space: pre + word-wrap: normal + code + background-color: transparent + color: currentColor + font-size: $pre-code-font-size + padding: 0 + +table + td, + th + vertical-align: top + &:not([align]) + text-align: left + th + color: $text-strong diff --git a/themes/helm/assets/sass/bulma/sass/base/helpers.sass b/themes/helm/assets/sass/bulma/sass/base/helpers.sass new file mode 100644 index 0000000000..bbb489dddc --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/base/helpers.sass @@ -0,0 +1,281 @@ +// Float + +.is-clearfix + +clearfix + +.is-pulled-left + float: left !important + +.is-pulled-right + float: right !important + +// Overflow + +.is-clipped + overflow: hidden !important + +// Overlay + +.is-overlay + @extend %overlay + +// Typography + +=typography-size($target:'') + @each $size in $sizes + $i: index($sizes, $size) + .is-size-#{$i}#{if($target == '', '', '-' + $target)} + font-size: $size !important + ++typography-size() + ++mobile + +typography-size('mobile') + ++tablet + +typography-size('tablet') + ++touch + +typography-size('touch') + ++desktop + +typography-size('desktop') + ++widescreen + +typography-size('widescreen') + ++fullhd + +typography-size('fullhd') + +$alignments: ('centered': 'center', 'justified': 'justify', 'left': 'left', 'right': 'right') + +@each $alignment, $text-align in $alignments + .has-text-#{$alignment} + text-align: #{$text-align} !important + +@each $alignment, $text-align in $alignments + +mobile + .has-text-#{$alignment}-mobile + text-align: #{$text-align} !important + +tablet + .has-text-#{$alignment}-tablet + text-align: #{$text-align} !important + +tablet-only + .has-text-#{$alignment}-tablet-only + text-align: #{$text-align} !important + +touch + .has-text-#{$alignment}-touch + text-align: #{$text-align} !important + +desktop + .has-text-#{$alignment}-desktop + text-align: #{$text-align} !important + +desktop-only + .has-text-#{$alignment}-desktop-only + text-align: #{$text-align} !important + +widescreen + .has-text-#{$alignment}-widescreen + text-align: #{$text-align} !important + +widescreen-only + .has-text-#{$alignment}-widescreen-only + text-align: #{$text-align} !important + +fullhd + .has-text-#{$alignment}-fullhd + text-align: #{$text-align} !important + +.is-capitalized + text-transform: capitalize !important + +.is-lowercase + text-transform: lowercase !important + +.is-uppercase + text-transform: uppercase !important + +.is-italic + font-style: italic !important + +@each $name, $pair in $colors + $color: nth($pair, 1) + .has-text-#{$name} + color: $color !important + a.has-text-#{$name} + &:hover, + &:focus + color: darken($color, 10%) !important + .has-background-#{$name} + background-color: $color !important + +@each $name, $shade in $shades + .has-text-#{$name} + color: $shade !important + .has-background-#{$name} + background-color: $shade !important + +.has-text-weight-light + font-weight: $weight-light !important +.has-text-weight-normal + font-weight: $weight-normal !important +.has-text-weight-medium + font-weight: $weight-medium !important +.has-text-weight-semibold + font-weight: $weight-semibold !important +.has-text-weight-bold + font-weight: $weight-bold !important + +.is-family-primary + font-family: $family-primary !important + +.is-family-secondary + font-family: $family-secondary !important + +.is-family-sans-serif + font-family: $family-sans-serif !important + +.is-family-monospace + font-family: $family-monospace !important + +.is-family-code + font-family: $family-code !important + +// Visibility + +$displays: 'block' 'flex' 'inline' 'inline-block' 'inline-flex' + +@each $display in $displays + .is-#{$display} + display: #{$display} !important + +mobile + .is-#{$display}-mobile + display: #{$display} !important + +tablet + .is-#{$display}-tablet + display: #{$display} !important + +tablet-only + .is-#{$display}-tablet-only + display: #{$display} !important + +touch + .is-#{$display}-touch + display: #{$display} !important + +desktop + .is-#{$display}-desktop + display: #{$display} !important + +desktop-only + .is-#{$display}-desktop-only + display: #{$display} !important + +widescreen + .is-#{$display}-widescreen + display: #{$display} !important + +widescreen-only + .is-#{$display}-widescreen-only + display: #{$display} !important + +fullhd + .is-#{$display}-fullhd + display: #{$display} !important + +.is-hidden + display: none !important + +.is-sr-only + border: none !important + clip: rect(0, 0, 0, 0) !important + height: 0.01em !important + overflow: hidden !important + padding: 0 !important + position: absolute !important + white-space: nowrap !important + width: 0.01em !important + ++mobile + .is-hidden-mobile + display: none !important + ++tablet + .is-hidden-tablet + display: none !important + ++tablet-only + .is-hidden-tablet-only + display: none !important + ++touch + .is-hidden-touch + display: none !important + ++desktop + .is-hidden-desktop + display: none !important + ++desktop-only + .is-hidden-desktop-only + display: none !important + ++widescreen + .is-hidden-widescreen + display: none !important + ++widescreen-only + .is-hidden-widescreen-only + display: none !important + ++fullhd + .is-hidden-fullhd + display: none !important + +.is-invisible + visibility: hidden !important + ++mobile + .is-invisible-mobile + visibility: hidden !important + ++tablet + .is-invisible-tablet + visibility: hidden !important + ++tablet-only + .is-invisible-tablet-only + visibility: hidden !important + ++touch + .is-invisible-touch + visibility: hidden !important + ++desktop + .is-invisible-desktop + visibility: hidden !important + ++desktop-only + .is-invisible-desktop-only + visibility: hidden !important + ++widescreen + .is-invisible-widescreen + visibility: hidden !important + ++widescreen-only + .is-invisible-widescreen-only + visibility: hidden !important + ++fullhd + .is-invisible-fullhd + visibility: hidden !important + +// Other + +.is-marginless + margin: 0 !important + +.is-paddingless + padding: 0 !important + +.is-radiusless + border-radius: 0 !important + +.is-shadowless + box-shadow: none !important + +.is-unselectable + @extend %unselectable + +.is-relative + position: relative !important diff --git a/themes/helm/assets/sass/bulma/sass/base/minireset.sass b/themes/helm/assets/sass/bulma/sass/base/minireset.sass new file mode 100644 index 0000000000..c5657ebdd4 --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/base/minireset.sass @@ -0,0 +1,79 @@ +/*! minireset.css v0.0.6 | MIT License | github.com/jgthms/minireset.css */ +// Blocks +html, +body, +p, +ol, +ul, +li, +dl, +dt, +dd, +blockquote, +figure, +fieldset, +legend, +textarea, +pre, +iframe, +hr, +h1, +h2, +h3, +h4, +h5, +h6 + margin: 0 + padding: 0 + +// Headings +h1, +h2, +h3, +h4, +h5, +h6 + font-size: 100% + font-weight: normal + +// List +ul + list-style: none + +// Form +button, +input, +select, +textarea + margin: 0 + +// Box sizing +html + box-sizing: border-box + +* + &, + &::before, + &::after + box-sizing: inherit + +// Media +img, +video + height: auto + max-width: 100% + +// Iframe +iframe + border: 0 + +// Table +table + border-collapse: collapse + border-spacing: 0 + +td, +th + padding: 0 + &:not([align]) + text-align: left diff --git a/themes/helm/assets/sass/bulma/sass/components/_all.sass b/themes/helm/assets/sass/bulma/sass/components/_all.sass new file mode 100644 index 0000000000..88fd45c5a6 --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/components/_all.sass @@ -0,0 +1,15 @@ +@charset "utf-8" + +@import "breadcrumb.sass" +@import "card.sass" +@import "dropdown.sass" +@import "level.sass" +@import "list.sass" +@import "media.sass" +@import "menu.sass" +@import "message.sass" +@import "modal.sass" +@import "navbar.sass" +@import "pagination.sass" +@import "panel.sass" +@import "tabs.sass" diff --git a/themes/helm/assets/sass/bulma/sass/components/breadcrumb.sass b/themes/helm/assets/sass/bulma/sass/components/breadcrumb.sass new file mode 100644 index 0000000000..3d7f4eb3c5 --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/components/breadcrumb.sass @@ -0,0 +1,75 @@ +$breadcrumb-item-color: $link !default +$breadcrumb-item-hover-color: $link-hover !default +$breadcrumb-item-active-color: $text-strong !default + +$breadcrumb-item-padding-vertical: 0 !default +$breadcrumb-item-padding-horizontal: 0.75em !default + +$breadcrumb-item-separator-color: $border-hover !default + +.breadcrumb + @extend %block + @extend %unselectable + font-size: $size-normal + white-space: nowrap + a + align-items: center + color: $breadcrumb-item-color + display: flex + justify-content: center + padding: $breadcrumb-item-padding-vertical $breadcrumb-item-padding-horizontal + &:hover + color: $breadcrumb-item-hover-color + li + align-items: center + display: flex + &:first-child a + padding-left: 0 + &.is-active + a + color: $breadcrumb-item-active-color + cursor: default + pointer-events: none + & + li::before + color: $breadcrumb-item-separator-color + content: "\0002f" + ul, + ol + align-items: flex-start + display: flex + flex-wrap: wrap + justify-content: flex-start + .icon + &:first-child + margin-right: 0.5em + &:last-child + margin-left: 0.5em + // Alignment + &.is-centered + ol, + ul + justify-content: center + &.is-right + ol, + ul + justify-content: flex-end + // Sizes + &.is-small + font-size: $size-small + &.is-medium + font-size: $size-medium + &.is-large + font-size: $size-large + // Styles + &.has-arrow-separator + li + li::before + content: "\02192" + &.has-bullet-separator + li + li::before + content: "\02022" + &.has-dot-separator + li + li::before + content: "\000b7" + &.has-succeeds-separator + li + li::before + content: "\0227B" diff --git a/themes/helm/assets/sass/bulma/sass/components/card.sass b/themes/helm/assets/sass/bulma/sass/components/card.sass new file mode 100644 index 0000000000..3cdf0008f1 --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/components/card.sass @@ -0,0 +1,79 @@ +$card-color: $text !default +$card-background-color: $scheme-main !default +$card-shadow: 0 0.5em 1em -0.125em rgba($scheme-invert, 0.1), 0 0px 0 1px rgba($scheme-invert, 0.02) !default + +$card-header-background-color: transparent !default +$card-header-color: $text-strong !default +$card-header-padding: 0.75rem 1rem !default +$card-header-shadow: 0 0.125em 0.25em rgba($scheme-invert, 0.1) !default +$card-header-weight: $weight-bold !default + +$card-content-background-color: transparent !default +$card-content-padding: 1.5rem !default + +$card-footer-background-color: transparent !default +$card-footer-border-top: 1px solid $border-light !default +$card-footer-padding: 0.75rem !default + +$card-media-margin: $block-spacing !default + +.card + background-color: $card-background-color + box-shadow: $card-shadow + color: $card-color + max-width: 100% + position: relative + +.card-header + background-color: $card-header-background-color + align-items: stretch + box-shadow: $card-header-shadow + display: flex + +.card-header-title + align-items: center + color: $card-header-color + display: flex + flex-grow: 1 + font-weight: $card-header-weight + padding: $card-header-padding + &.is-centered + justify-content: center + +.card-header-icon + align-items: center + cursor: pointer + display: flex + justify-content: center + padding: $card-header-padding + +.card-image + display: block + position: relative + +.card-content + background-color: $card-content-background-color + padding: $card-content-padding + +.card-footer + background-color: $card-footer-background-color + border-top: $card-footer-border-top + align-items: stretch + display: flex + +.card-footer-item + align-items: center + display: flex + flex-basis: 0 + flex-grow: 1 + flex-shrink: 0 + justify-content: center + padding: $card-footer-padding + &:not(:last-child) + border-right: $card-footer-border-top + +// Combinations + +.card + .media:not(:last-child) + margin-bottom: $card-media-margin diff --git a/themes/helm/assets/sass/bulma/sass/components/dropdown.sass b/themes/helm/assets/sass/bulma/sass/components/dropdown.sass new file mode 100644 index 0000000000..d62a6d88ef --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/components/dropdown.sass @@ -0,0 +1,81 @@ +$dropdown-menu-min-width: 12rem !default + +$dropdown-content-background-color: $scheme-main !default +$dropdown-content-arrow: $link !default +$dropdown-content-offset: 4px !default +$dropdown-content-padding-bottom: 0.5rem !default +$dropdown-content-padding-top: 0.5rem !default +$dropdown-content-radius: $radius !default +$dropdown-content-shadow: 0 0.5em 1em -0.125em rgba($scheme-invert, 0.1), 0 0px 0 1px rgba($scheme-invert, 0.02) !default +$dropdown-content-z: 20 !default + +$dropdown-item-color: $text !default +$dropdown-item-hover-color: $scheme-invert !default +$dropdown-item-hover-background-color: $background !default +$dropdown-item-active-color: $link-invert !default +$dropdown-item-active-background-color: $link !default + +$dropdown-divider-background-color: $border-light !default + +.dropdown + display: inline-flex + position: relative + vertical-align: top + &.is-active, + &.is-hoverable:hover + .dropdown-menu + display: block + &.is-right + .dropdown-menu + left: auto + right: 0 + &.is-up + .dropdown-menu + bottom: 100% + padding-bottom: $dropdown-content-offset + padding-top: initial + top: auto + +.dropdown-menu + display: none + left: 0 + min-width: $dropdown-menu-min-width + padding-top: $dropdown-content-offset + position: absolute + top: 100% + z-index: $dropdown-content-z + +.dropdown-content + background-color: $dropdown-content-background-color + border-radius: $dropdown-content-radius + box-shadow: $dropdown-content-shadow + padding-bottom: $dropdown-content-padding-bottom + padding-top: $dropdown-content-padding-top + +.dropdown-item + color: $dropdown-item-color + display: block + font-size: 0.875rem + line-height: 1.5 + padding: 0.375rem 1rem + position: relative + +a.dropdown-item, +button.dropdown-item + padding-right: 3rem + text-align: left + white-space: nowrap + width: 100% + &:hover + background-color: $dropdown-item-hover-background-color + color: $dropdown-item-hover-color + &.is-active + background-color: $dropdown-item-active-background-color + color: $dropdown-item-active-color + +.dropdown-divider + background-color: $dropdown-divider-background-color + border: none + display: block + height: 1px + margin: 0.5rem 0 diff --git a/themes/helm/assets/sass/bulma/sass/components/level.sass b/themes/helm/assets/sass/bulma/sass/components/level.sass new file mode 100644 index 0000000000..608f291e75 --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/components/level.sass @@ -0,0 +1,77 @@ +$level-item-spacing: ($block-spacing / 2) !default + +.level + @extend %block + align-items: center + justify-content: space-between + code + border-radius: $radius + img + display: inline-block + vertical-align: top + // Modifiers + &.is-mobile + display: flex + .level-left, + .level-right + display: flex + .level-left + .level-right + margin-top: 0 + .level-item + &:not(:last-child) + margin-bottom: 0 + margin-right: $level-item-spacing + &:not(.is-narrow) + flex-grow: 1 + // Responsiveness + +tablet + display: flex + & > .level-item + &:not(.is-narrow) + flex-grow: 1 + +.level-item + align-items: center + display: flex + flex-basis: auto + flex-grow: 0 + flex-shrink: 0 + justify-content: center + .title, + .subtitle + margin-bottom: 0 + // Responsiveness + +mobile + &:not(:last-child) + margin-bottom: $level-item-spacing + +.level-left, +.level-right + flex-basis: auto + flex-grow: 0 + flex-shrink: 0 + .level-item + // Modifiers + &.is-flexible + flex-grow: 1 + // Responsiveness + +tablet + &:not(:last-child) + margin-right: $level-item-spacing + +.level-left + align-items: center + justify-content: flex-start + // Responsiveness + +mobile + & + .level-right + margin-top: 1.5rem + +tablet + display: flex + +.level-right + align-items: center + justify-content: flex-end + // Responsiveness + +tablet + display: flex diff --git a/themes/helm/assets/sass/bulma/sass/components/list.sass b/themes/helm/assets/sass/bulma/sass/components/list.sass new file mode 100644 index 0000000000..bc99428a9a --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/components/list.sass @@ -0,0 +1,39 @@ +$list-background-color: $scheme-main !default +$list-shadow: 0 2px 3px rgba($scheme-invert, 0.1), 0 0 0 1px rgba($scheme-invert, 0.1) !default +$list-radius: $radius !default + +$list-item-border: 1px solid $border !default +$list-item-color: $text !default +$list-item-active-background-color: $link !default +$list-item-active-color: $link-invert !default +$list-item-hover-background-color: $background !default + +.list + @extend %block + background-color: $list-background-color + border-radius: $list-radius + box-shadow: $list-shadow + // &.is-hoverable > .list-item:hover:not(.is-active) + // background-color: $list-item-hover-background-color + // cursor: pointer + +.list-item + display: block + padding: 0.5em 1em + &:not(a) + color: $list-item-color + &:first-child + border-top-left-radius: $list-radius + border-top-right-radius: $list-radius + &:last-child + border-bottom-left-radius: $list-radius + border-bottom-right-radius: $list-radius + &:not(:last-child) + border-bottom: $list-item-border + &.is-active + background-color: $list-item-active-background-color + color: $list-item-active-color + +a.list-item + background-color: $list-item-hover-background-color + cursor: pointer diff --git a/themes/helm/assets/sass/bulma/sass/components/media.sass b/themes/helm/assets/sass/bulma/sass/components/media.sass new file mode 100644 index 0000000000..65939fca13 --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/components/media.sass @@ -0,0 +1,50 @@ +$media-border-color: rgba($border, 0.5) !default + +.media + align-items: flex-start + display: flex + text-align: left + .content:not(:last-child) + margin-bottom: 0.75rem + .media + border-top: 1px solid $media-border-color + display: flex + padding-top: 0.75rem + .content:not(:last-child), + .control:not(:last-child) + margin-bottom: 0.5rem + .media + padding-top: 0.5rem + & + .media + margin-top: 0.5rem + & + .media + border-top: 1px solid $media-border-color + margin-top: 1rem + padding-top: 1rem + // Sizes + &.is-large + & + .media + margin-top: 1.5rem + padding-top: 1.5rem + +.media-left, +.media-right + flex-basis: auto + flex-grow: 0 + flex-shrink: 0 + +.media-left + margin-right: 1rem + +.media-right + margin-left: 1rem + +.media-content + flex-basis: auto + flex-grow: 1 + flex-shrink: 1 + text-align: left + ++mobile + .media-content + overflow-x: auto diff --git a/themes/helm/assets/sass/bulma/sass/components/menu.sass b/themes/helm/assets/sass/bulma/sass/components/menu.sass new file mode 100644 index 0000000000..3de7e18db0 --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/components/menu.sass @@ -0,0 +1,57 @@ +$menu-item-color: $text !default +$menu-item-radius: $radius-small !default +$menu-item-hover-color: $text-strong !default +$menu-item-hover-background-color: $background !default +$menu-item-active-color: $link-invert !default +$menu-item-active-background-color: $link !default + +$menu-list-border-left: 1px solid $border !default +$menu-list-line-height: 1.25 !default +$menu-list-link-padding: 0.5em 0.75em !default +$menu-nested-list-margin: 0.75em !default +$menu-nested-list-padding-left: 0.75em !default + +$menu-label-color: $text-light !default +$menu-label-font-size: 0.75em !default +$menu-label-letter-spacing: 0.1em !default +$menu-label-spacing: 1em !default + +.menu + font-size: $size-normal + // Sizes + &.is-small + font-size: $size-small + &.is-medium + font-size: $size-medium + &.is-large + font-size: $size-large + +.menu-list + line-height: $menu-list-line-height + a + border-radius: $menu-item-radius + color: $menu-item-color + display: block + padding: $menu-list-link-padding + &:hover + background-color: $menu-item-hover-background-color + color: $menu-item-hover-color + // Modifiers + &.is-active + background-color: $menu-item-active-background-color + color: $menu-item-active-color + li + ul + border-left: $menu-list-border-left + margin: $menu-nested-list-margin + padding-left: $menu-nested-list-padding-left + +.menu-label + color: $menu-label-color + font-size: $menu-label-font-size + letter-spacing: $menu-label-letter-spacing + text-transform: uppercase + &:not(:first-child) + margin-top: $menu-label-spacing + &:not(:last-child) + margin-bottom: $menu-label-spacing diff --git a/themes/helm/assets/sass/bulma/sass/components/message.sass b/themes/helm/assets/sass/bulma/sass/components/message.sass new file mode 100644 index 0000000000..89e4cc9a84 --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/components/message.sass @@ -0,0 +1,99 @@ +$message-background-color: $background !default +$message-radius: $radius !default + +$message-header-background-color: $text !default +$message-header-color: $text-invert !default +$message-header-weight: $weight-bold !default +$message-header-padding: 0.75em 1em !default +$message-header-radius: $radius !default + +$message-body-border-color: $border !default +$message-body-border-width: 0 0 0 4px !default +$message-body-color: $text !default +$message-body-padding: 1.25em 1.5em !default +$message-body-radius: $radius !default + +$message-body-pre-background-color: $scheme-main !default +$message-body-pre-code-background-color: transparent !default + +$message-header-body-border-width: 0 !default +$message-colors: $colors !default + +.message + @extend %block + background-color: $message-background-color + border-radius: $message-radius + font-size: $size-normal + strong + color: currentColor + a:not(.button):not(.tag):not(.dropdown-item) + color: currentColor + text-decoration: underline + // Sizes + &.is-small + font-size: $size-small + &.is-medium + font-size: $size-medium + &.is-large + font-size: $size-large + // Colors + @each $name, $components in $message-colors + $color: nth($components, 1) + $color-invert: nth($components, 2) + $color-light: null + $color-dark: null + + @if length($components) >= 3 + $color-light: nth($components, 3) + @if length($components) >= 4 + $color-dark: nth($components, 4) + @else + $color-luminance: colorLuminance($color) + $darken-percentage: $color-luminance * 70% + $desaturate-percentage: $color-luminance * 30% + $color-dark: desaturate(darken($color, $darken-percentage), $desaturate-percentage) + @else + $color-lightning: max((100% - lightness($color)) - 2%, 0%) + $color-light: lighten($color, $color-lightning) + + &.is-#{$name} + background-color: $color-light + .message-header + background-color: $color + color: $color-invert + .message-body + border-color: $color + color: $color-dark + +.message-header + align-items: center + background-color: $message-header-background-color + border-radius: $message-header-radius $message-header-radius 0 0 + color: $message-header-color + display: flex + font-weight: $message-header-weight + justify-content: space-between + line-height: 1.25 + padding: $message-header-padding + position: relative + .delete + flex-grow: 0 + flex-shrink: 0 + margin-left: 0.75em + & + .message-body + border-width: $message-header-body-border-width + border-top-left-radius: 0 + border-top-right-radius: 0 + +.message-body + border-color: $message-body-border-color + border-radius: $message-body-radius + border-style: solid + border-width: $message-body-border-width + color: $message-body-color + padding: $message-body-padding + code, + pre + background-color: $message-body-pre-background-color + pre code + background-color: $message-body-pre-code-background-color diff --git a/themes/helm/assets/sass/bulma/sass/components/modal.sass b/themes/helm/assets/sass/bulma/sass/components/modal.sass new file mode 100644 index 0000000000..c3a5a0c6c1 --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/components/modal.sass @@ -0,0 +1,113 @@ +$modal-z: 40 !default + +$modal-background-background-color: rgba($scheme-invert, 0.86) !default + +$modal-content-width: 640px !default +$modal-content-margin-mobile: 20px !default +$modal-content-spacing-mobile: 160px !default +$modal-content-spacing-tablet: 40px !default + +$modal-close-dimensions: 40px !default +$modal-close-right: 20px !default +$modal-close-top: 20px !default + +$modal-card-spacing: 40px !default + +$modal-card-head-background-color: $background !default +$modal-card-head-border-bottom: 1px solid $border !default +$modal-card-head-padding: 20px !default +$modal-card-head-radius: $radius-large !default + +$modal-card-title-color: $text-strong !default +$modal-card-title-line-height: 1 !default +$modal-card-title-size: $size-4 !default + +$modal-card-foot-radius: $radius-large !default +$modal-card-foot-border-top: 1px solid $border !default + +$modal-card-body-background-color: $scheme-main !default +$modal-card-body-padding: 20px !default + +.modal + @extend %overlay + align-items: center + display: none + flex-direction: column + justify-content: center + overflow: hidden + position: fixed + z-index: $modal-z + // Modifiers + &.is-active + display: flex + +.modal-background + @extend %overlay + background-color: $modal-background-background-color + +.modal-content, +.modal-card + margin: 0 $modal-content-margin-mobile + max-height: calc(100vh - #{$modal-content-spacing-mobile}) + overflow: auto + position: relative + width: 100% + // Responsiveness + +tablet + margin: 0 auto + max-height: calc(100vh - #{$modal-content-spacing-tablet}) + width: $modal-content-width + +.modal-close + @extend %delete + background: none + height: $modal-close-dimensions + position: fixed + right: $modal-close-right + top: $modal-close-top + width: $modal-close-dimensions + +.modal-card + display: flex + flex-direction: column + max-height: calc(100vh - #{$modal-card-spacing}) + overflow: hidden + -ms-overflow-y: visible + +.modal-card-head, +.modal-card-foot + align-items: center + background-color: $modal-card-head-background-color + display: flex + flex-shrink: 0 + justify-content: flex-start + padding: $modal-card-head-padding + position: relative + +.modal-card-head + border-bottom: $modal-card-head-border-bottom + border-top-left-radius: $modal-card-head-radius + border-top-right-radius: $modal-card-head-radius + +.modal-card-title + color: $modal-card-title-color + flex-grow: 1 + flex-shrink: 0 + font-size: $modal-card-title-size + line-height: $modal-card-title-line-height + +.modal-card-foot + border-bottom-left-radius: $modal-card-foot-radius + border-bottom-right-radius: $modal-card-foot-radius + border-top: $modal-card-foot-border-top + .button + &:not(:last-child) + margin-right: 0.5em + +.modal-card-body + +overflow-touch + background-color: $modal-card-body-background-color + flex-grow: 1 + flex-shrink: 1 + overflow: auto + padding: $modal-card-body-padding diff --git a/themes/helm/assets/sass/bulma/sass/components/navbar.sass b/themes/helm/assets/sass/bulma/sass/components/navbar.sass new file mode 100644 index 0000000000..664558f726 --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/components/navbar.sass @@ -0,0 +1,443 @@ +$navbar-background-color: $scheme-main !default +$navbar-box-shadow-size: 0 2px 0 0 !default +$navbar-box-shadow-color: $background !default +$navbar-height: 3.25rem !default +$navbar-padding-vertical: 1rem !default +$navbar-padding-horizontal: 2rem !default +$navbar-z: 30 !default +$navbar-fixed-z: 30 !default + +$navbar-item-color: $text !default +$navbar-item-hover-color: $link !default +$navbar-item-hover-background-color: $scheme-main-bis !default +$navbar-item-active-color: $scheme-invert !default +$navbar-item-active-background-color: transparent !default +$navbar-item-img-max-height: 1.75rem !default + +$navbar-burger-color: $navbar-item-color !default + +$navbar-tab-hover-background-color: transparent !default +$navbar-tab-hover-border-bottom-color: $link !default +$navbar-tab-active-color: $link !default +$navbar-tab-active-background-color: transparent !default +$navbar-tab-active-border-bottom-color: $link !default +$navbar-tab-active-border-bottom-style: solid !default +$navbar-tab-active-border-bottom-width: 3px !default + +$navbar-dropdown-background-color: $scheme-main !default +$navbar-dropdown-border-top: 2px solid $border !default +$navbar-dropdown-offset: -4px !default +$navbar-dropdown-arrow: $link !default +$navbar-dropdown-radius: $radius-large !default +$navbar-dropdown-z: 20 !default + +$navbar-dropdown-boxed-radius: $radius-large !default +$navbar-dropdown-boxed-shadow: 0 8px 8px rgba($scheme-invert, 0.1), 0 0 0 1px rgba($scheme-invert, 0.1) !default + +$navbar-dropdown-item-hover-color: $scheme-invert !default +$navbar-dropdown-item-hover-background-color: $background !default +$navbar-dropdown-item-active-color: $link !default +$navbar-dropdown-item-active-background-color: $background !default + +$navbar-divider-background-color: $background !default +$navbar-divider-height: 2px !default + +$navbar-bottom-box-shadow-size: 0 -2px 0 0 !default + +$navbar-breakpoint: $desktop !default + +=navbar-fixed + left: 0 + position: fixed + right: 0 + z-index: $navbar-fixed-z + +.navbar + background-color: $navbar-background-color + min-height: $navbar-height + position: relative + z-index: $navbar-z + @each $name, $pair in $colors + $color: nth($pair, 1) + $color-invert: nth($pair, 2) + &.is-#{$name} + background-color: $color + color: $color-invert + .navbar-brand + & > .navbar-item, + .navbar-link + color: $color-invert + & > a.navbar-item, + .navbar-link + &:focus, + &:hover, + &.is-active + background-color: darken($color, 5%) + color: $color-invert + .navbar-link + &::after + border-color: $color-invert + .navbar-burger + color: $color-invert + +from($navbar-breakpoint) + .navbar-start, + .navbar-end + & > .navbar-item, + .navbar-link + color: $color-invert + & > a.navbar-item, + .navbar-link + &:focus, + &:hover, + &.is-active + background-color: darken($color, 5%) + color: $color-invert + .navbar-link + &::after + border-color: $color-invert + .navbar-item.has-dropdown:focus .navbar-link, + .navbar-item.has-dropdown:hover .navbar-link, + .navbar-item.has-dropdown.is-active .navbar-link + background-color: darken($color, 5%) + color: $color-invert + .navbar-dropdown + a.navbar-item + &.is-active + background-color: $color + color: $color-invert + & > .container + align-items: stretch + display: flex + min-height: $navbar-height + width: 100% + &.has-shadow + box-shadow: $navbar-box-shadow-size $navbar-box-shadow-color + &.is-fixed-bottom, + &.is-fixed-top + +navbar-fixed + &.is-fixed-bottom + bottom: 0 + &.has-shadow + box-shadow: $navbar-bottom-box-shadow-size $navbar-box-shadow-color + &.is-fixed-top + top: 0 + +html, +body + &.has-navbar-fixed-top + padding-top: $navbar-height + &.has-navbar-fixed-bottom + padding-bottom: $navbar-height + +.navbar-brand, +.navbar-tabs + align-items: stretch + display: flex + flex-shrink: 0 + min-height: $navbar-height + +.navbar-brand + a.navbar-item + &:focus, + &:hover + background-color: transparent + +.navbar-tabs + +overflow-touch + max-width: 100vw + overflow-x: auto + overflow-y: hidden + +.navbar-burger + color: $navbar-burger-color + +hamburger($navbar-height) + margin-left: auto + +.navbar-menu + display: none + +.navbar-item, +.navbar-link + color: $navbar-item-color + display: block + line-height: 1.5 + padding: 0.5rem 0.75rem + position: relative + .icon + &:only-child + margin-left: -0.25rem + margin-right: -0.25rem + +a.navbar-item, +.navbar-link + cursor: pointer + &:focus, + &:focus-within, + &:hover, + &.is-active + background-color: $navbar-item-hover-background-color + color: $navbar-item-hover-color + +.navbar-item + display: block + flex-grow: 0 + flex-shrink: 0 + img + max-height: $navbar-item-img-max-height + &.has-dropdown + padding: 0 + &.is-expanded + flex-grow: 1 + flex-shrink: 1 + &.is-tab + border-bottom: 1px solid transparent + min-height: $navbar-height + padding-bottom: calc(0.5rem - 1px) + &:focus, + &:hover + background-color: $navbar-tab-hover-background-color + border-bottom-color: $navbar-tab-hover-border-bottom-color + &.is-active + background-color: $navbar-tab-active-background-color + border-bottom-color: $navbar-tab-active-border-bottom-color + border-bottom-style: $navbar-tab-active-border-bottom-style + border-bottom-width: $navbar-tab-active-border-bottom-width + color: $navbar-tab-active-color + padding-bottom: calc(0.5rem - #{$navbar-tab-active-border-bottom-width}) + +.navbar-content + flex-grow: 1 + flex-shrink: 1 + +.navbar-link:not(.is-arrowless) + padding-right: 2.5em + &::after + @extend %arrow + border-color: $navbar-dropdown-arrow + margin-top: -0.375em + right: 1.125em + +.navbar-dropdown + font-size: 0.875rem + padding-bottom: 0.5rem + padding-top: 0.5rem + .navbar-item + padding-left: 1.5rem + padding-right: 1.5rem + +.navbar-divider + background-color: $navbar-divider-background-color + border: none + display: none + height: $navbar-divider-height + margin: 0.5rem 0 + ++until($navbar-breakpoint) + .navbar > .container + display: block + .navbar-brand, + .navbar-tabs + .navbar-item + align-items: center + display: flex + .navbar-link + &::after + display: none + .navbar-menu + background-color: $navbar-background-color + box-shadow: 0 8px 16px rgba($scheme-invert, 0.1) + padding: 0.5rem 0 + &.is-active + display: block + // Fixed navbar + .navbar + &.is-fixed-bottom-touch, + &.is-fixed-top-touch + +navbar-fixed + &.is-fixed-bottom-touch + bottom: 0 + &.has-shadow + box-shadow: 0 -2px 3px rgba($scheme-invert, 0.1) + &.is-fixed-top-touch + top: 0 + &.is-fixed-top, + &.is-fixed-top-touch + .navbar-menu + +overflow-touch + max-height: calc(100vh - #{$navbar-height}) + overflow: auto + html, + body + &.has-navbar-fixed-top-touch + padding-top: $navbar-height + &.has-navbar-fixed-bottom-touch + padding-bottom: $navbar-height + ++from($navbar-breakpoint) + .navbar, + .navbar-menu, + .navbar-start, + .navbar-end + align-items: stretch + display: flex + .navbar + min-height: $navbar-height + &.is-spaced + padding: $navbar-padding-vertical $navbar-padding-horizontal + .navbar-start, + .navbar-end + align-items: center + a.navbar-item, + .navbar-link + border-radius: $radius + &.is-transparent + a.navbar-item, + .navbar-link + &:focus, + &:hover, + &.is-active + background-color: transparent !important + .navbar-item.has-dropdown + &.is-active, + &.is-hoverable:focus, + &.is-hoverable:focus-within, + &.is-hoverable:hover + .navbar-link + background-color: transparent !important + .navbar-dropdown + a.navbar-item + &:focus, + &:hover + background-color: $navbar-dropdown-item-hover-background-color + color: $navbar-dropdown-item-hover-color + &.is-active + background-color: $navbar-dropdown-item-active-background-color + color: $navbar-dropdown-item-active-color + .navbar-burger + display: none + .navbar-item, + .navbar-link + align-items: center + display: flex + .navbar-item + display: flex + &.has-dropdown + align-items: stretch + &.has-dropdown-up + .navbar-link::after + transform: rotate(135deg) translate(0.25em, -0.25em) + .navbar-dropdown + border-bottom: $navbar-dropdown-border-top + border-radius: $navbar-dropdown-radius $navbar-dropdown-radius 0 0 + border-top: none + bottom: 100% + box-shadow: 0 -8px 8px rgba($scheme-invert, 0.1) + top: auto + &.is-active, + &.is-hoverable:focus, + &.is-hoverable:focus-within, + &.is-hoverable:hover + .navbar-dropdown + display: block + .navbar.is-spaced &, + &.is-boxed + opacity: 1 + pointer-events: auto + transform: translateY(0) + .navbar-menu + flex-grow: 1 + flex-shrink: 0 + .navbar-start + justify-content: flex-start + margin-right: auto + .navbar-end + justify-content: flex-end + margin-left: auto + .navbar-dropdown + background-color: $navbar-dropdown-background-color + border-bottom-left-radius: $navbar-dropdown-radius + border-bottom-right-radius: $navbar-dropdown-radius + border-top: $navbar-dropdown-border-top + box-shadow: 0 8px 8px rgba($scheme-invert, 0.1) + display: none + font-size: 0.875rem + left: 0 + min-width: 100% + position: absolute + top: 100% + z-index: $navbar-dropdown-z + .navbar-item + padding: 0.375rem 1rem + white-space: nowrap + a.navbar-item + padding-right: 3rem + &:focus, + &:hover + background-color: $navbar-dropdown-item-hover-background-color + color: $navbar-dropdown-item-hover-color + &.is-active + background-color: $navbar-dropdown-item-active-background-color + color: $navbar-dropdown-item-active-color + .navbar.is-spaced &, + &.is-boxed + border-radius: $navbar-dropdown-boxed-radius + border-top: none + box-shadow: $navbar-dropdown-boxed-shadow + display: block + opacity: 0 + pointer-events: none + top: calc(100% + (#{$navbar-dropdown-offset})) + transform: translateY(-5px) + transition-duration: $speed + transition-property: opacity, transform + &.is-right + left: auto + right: 0 + .navbar-divider + display: block + .navbar > .container, + .container > .navbar + .navbar-brand + margin-left: -.75rem + .navbar-menu + margin-right: -.75rem + // Fixed navbar + .navbar + &.is-fixed-bottom-desktop, + &.is-fixed-top-desktop + +navbar-fixed + &.is-fixed-bottom-desktop + bottom: 0 + &.has-shadow + box-shadow: 0 -2px 3px rgba($scheme-invert, 0.1) + &.is-fixed-top-desktop + top: 0 + html, + body + &.has-navbar-fixed-top-desktop + padding-top: $navbar-height + &.has-navbar-fixed-bottom-desktop + padding-bottom: $navbar-height + &.has-spaced-navbar-fixed-top + padding-top: $navbar-height + ($navbar-padding-vertical * 2) + &.has-spaced-navbar-fixed-bottom + padding-bottom: $navbar-height + ($navbar-padding-vertical * 2) + // Hover/Active states + a.navbar-item, + .navbar-link + &.is-active + color: $navbar-item-active-color + &.is-active:not(:focus):not(:hover) + background-color: $navbar-item-active-background-color + .navbar-item.has-dropdown + &:focus, + &:hover, + &.is-active + .navbar-link + background-color: $navbar-item-hover-background-color + +// Combination + +.hero + &.is-fullheight-with-navbar + min-height: calc(100vh - #{$navbar-height}) diff --git a/themes/helm/assets/sass/bulma/sass/components/pagination.sass b/themes/helm/assets/sass/bulma/sass/components/pagination.sass new file mode 100644 index 0000000000..822c2e816b --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/components/pagination.sass @@ -0,0 +1,150 @@ +$pagination-color: $text-strong !default +$pagination-border-color: $border !default +$pagination-margin: -0.25rem !default +$pagination-min-width: $control-height !default + +$pagination-item-font-size: 1em !default +$pagination-item-margin: 0.25rem !default +$pagination-item-padding-left: 0.5em !default +$pagination-item-padding-right: 0.5em !default + +$pagination-hover-color: $link-hover !default +$pagination-hover-border-color: $link-hover-border !default + +$pagination-focus-color: $link-focus !default +$pagination-focus-border-color: $link-focus-border !default + +$pagination-active-color: $link-active !default +$pagination-active-border-color: $link-active-border !default + +$pagination-disabled-color: $text-light !default +$pagination-disabled-background-color: $border !default +$pagination-disabled-border-color: $border !default + +$pagination-current-color: $link-invert !default +$pagination-current-background-color: $link !default +$pagination-current-border-color: $link !default + +$pagination-ellipsis-color: $grey-light !default + +$pagination-shadow-inset: inset 0 1px 2px rgba($scheme-invert, 0.2) + +.pagination + @extend %block + font-size: $size-normal + margin: $pagination-margin + // Sizes + &.is-small + font-size: $size-small + &.is-medium + font-size: $size-medium + &.is-large + font-size: $size-large + &.is-rounded + .pagination-previous, + .pagination-next + padding-left: 1em + padding-right: 1em + border-radius: $radius-rounded + .pagination-link + border-radius: $radius-rounded + +.pagination, +.pagination-list + align-items: center + display: flex + justify-content: center + text-align: center + +.pagination-previous, +.pagination-next, +.pagination-link, +.pagination-ellipsis + @extend %control + @extend %unselectable + font-size: $pagination-item-font-size + justify-content: center + margin: $pagination-item-margin + padding-left: $pagination-item-padding-left + padding-right: $pagination-item-padding-right + text-align: center + +.pagination-previous, +.pagination-next, +.pagination-link + border-color: $pagination-border-color + color: $pagination-color + min-width: $pagination-min-width + &:hover + border-color: $pagination-hover-border-color + color: $pagination-hover-color + &:focus + border-color: $pagination-focus-border-color + &:active + box-shadow: $pagination-shadow-inset + &[disabled] + background-color: $pagination-disabled-background-color + border-color: $pagination-disabled-border-color + box-shadow: none + color: $pagination-disabled-color + opacity: 0.5 + +.pagination-previous, +.pagination-next + padding-left: 0.75em + padding-right: 0.75em + white-space: nowrap + +.pagination-link + &.is-current + background-color: $pagination-current-background-color + border-color: $pagination-current-border-color + color: $pagination-current-color + +.pagination-ellipsis + color: $pagination-ellipsis-color + pointer-events: none + +.pagination-list + flex-wrap: wrap + ++mobile + .pagination + flex-wrap: wrap + .pagination-previous, + .pagination-next + flex-grow: 1 + flex-shrink: 1 + .pagination-list + li + flex-grow: 1 + flex-shrink: 1 + ++tablet + .pagination-list + flex-grow: 1 + flex-shrink: 1 + justify-content: flex-start + order: 1 + .pagination-previous + order: 2 + .pagination-next + order: 3 + .pagination + justify-content: space-between + &.is-centered + .pagination-previous + order: 1 + .pagination-list + justify-content: center + order: 2 + .pagination-next + order: 3 + &.is-right + .pagination-previous + order: 1 + .pagination-next + order: 2 + .pagination-list + justify-content: flex-end + order: 3 diff --git a/themes/helm/assets/sass/bulma/sass/components/panel.sass b/themes/helm/assets/sass/bulma/sass/components/panel.sass new file mode 100644 index 0000000000..3c32be600d --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/components/panel.sass @@ -0,0 +1,118 @@ +$panel-margin: $block-spacing !default +$panel-item-border: 1px solid $border-light !default +$panel-radius: $radius-large !default +$panel-shadow: 0 0.5em 1em -0.125em rgba($scheme-invert, 0.1), 0 0px 0 1px rgba($scheme-invert, 0.02) !default + +$panel-heading-background-color: $border-light !default +$panel-heading-color: $text-strong !default +$panel-heading-line-height: 1.25 !default +$panel-heading-padding: 0.75em 1em !default +$panel-heading-radius: $radius !default +$panel-heading-size: 1.25em !default +$panel-heading-weight: $weight-bold !default + +$panel-tabs-font-size: 0.875em !default +$panel-tab-border-bottom: 1px solid $border !default +$panel-tab-active-border-bottom-color: $link-active-border !default +$panel-tab-active-color: $link-active !default + +$panel-list-item-color: $text !default +$panel-list-item-hover-color: $link !default + +$panel-block-color: $text-strong !default +$panel-block-hover-background-color: $background !default +$panel-block-active-border-left-color: $link !default +$panel-block-active-color: $link-active !default +$panel-block-active-icon-color: $link !default + +$panel-icon-color: $text-light !default + +.panel + border-radius: $panel-radius + box-shadow: $panel-shadow + font-size: $size-normal + &:not(:last-child) + margin-bottom: $panel-margin + // Colors + @each $name, $components in $message-colors + $color: nth($components, 1) + $color-invert: nth($components, 2) + &.is-#{$name} + .panel-heading + background-color: $color + color: $color-invert + .panel-tabs a.is-active + border-bottom-color: $color + .panel-block.is-active .panel-icon + color: $color + +.panel-tabs, +.panel-block + &:not(:last-child) + border-bottom: $panel-item-border + +.panel-heading + background-color: $panel-heading-background-color + border-radius: $panel-radius $panel-radius 0 0 + color: $panel-heading-color + font-size: $panel-heading-size + font-weight: $panel-heading-weight + line-height: $panel-heading-line-height + padding: $panel-heading-padding + +.panel-tabs + align-items: flex-end + display: flex + font-size: $panel-tabs-font-size + justify-content: center + a + border-bottom: $panel-tab-border-bottom + margin-bottom: -1px + padding: 0.5em + // Modifiers + &.is-active + border-bottom-color: $panel-tab-active-border-bottom-color + color: $panel-tab-active-color + +.panel-list + a + color: $panel-list-item-color + &:hover + color: $panel-list-item-hover-color + +.panel-block + align-items: center + color: $panel-block-color + display: flex + justify-content: flex-start + padding: 0.5em 0.75em + input[type="checkbox"] + margin-right: 0.75em + & > .control + flex-grow: 1 + flex-shrink: 1 + width: 100% + &.is-wrapped + flex-wrap: wrap + &.is-active + border-left-color: $panel-block-active-border-left-color + color: $panel-block-active-color + .panel-icon + color: $panel-block-active-icon-color + &:last-child + border-bottom-left-radius: $panel-radius + border-bottom-right-radius: $panel-radius + +a.panel-block, +label.panel-block + cursor: pointer + &:hover + background-color: $panel-block-hover-background-color + +.panel-icon + +fa(14px, 1em) + color: $panel-icon-color + margin-right: 0.75em + .fa + font-size: inherit + line-height: inherit diff --git a/themes/helm/assets/sass/bulma/sass/components/tabs.sass b/themes/helm/assets/sass/bulma/sass/components/tabs.sass new file mode 100644 index 0000000000..8c28c257a5 --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/components/tabs.sass @@ -0,0 +1,151 @@ +$tabs-border-bottom-color: $border !default +$tabs-border-bottom-style: solid !default +$tabs-border-bottom-width: 1px !default +$tabs-link-color: $text !default +$tabs-link-hover-border-bottom-color: $text-strong !default +$tabs-link-hover-color: $text-strong !default +$tabs-link-active-border-bottom-color: $link !default +$tabs-link-active-color: $link !default +$tabs-link-padding: 0.5em 1em !default + +$tabs-boxed-link-radius: $radius !default +$tabs-boxed-link-hover-background-color: $background !default +$tabs-boxed-link-hover-border-bottom-color: $border !default + +$tabs-boxed-link-active-background-color: $scheme-main !default +$tabs-boxed-link-active-border-color: $border !default +$tabs-boxed-link-active-border-bottom-color: transparent !default + +$tabs-toggle-link-border-color: $border !default +$tabs-toggle-link-border-style: solid !default +$tabs-toggle-link-border-width: 1px !default +$tabs-toggle-link-hover-background-color: $background !default +$tabs-toggle-link-hover-border-color: $border-hover !default +$tabs-toggle-link-radius: $radius !default +$tabs-toggle-link-active-background-color: $link !default +$tabs-toggle-link-active-border-color: $link !default +$tabs-toggle-link-active-color: $link-invert !default + +.tabs + @extend %block + +overflow-touch + @extend %unselectable + align-items: stretch + display: flex + font-size: $size-normal + justify-content: space-between + overflow: hidden + overflow-x: auto + white-space: nowrap + a + align-items: center + border-bottom-color: $tabs-border-bottom-color + border-bottom-style: $tabs-border-bottom-style + border-bottom-width: $tabs-border-bottom-width + color: $tabs-link-color + display: flex + justify-content: center + margin-bottom: -#{$tabs-border-bottom-width} + padding: $tabs-link-padding + vertical-align: top + &:hover + border-bottom-color: $tabs-link-hover-border-bottom-color + color: $tabs-link-hover-color + li + display: block + &.is-active + a + border-bottom-color: $tabs-link-active-border-bottom-color + color: $tabs-link-active-color + ul + align-items: center + border-bottom-color: $tabs-border-bottom-color + border-bottom-style: $tabs-border-bottom-style + border-bottom-width: $tabs-border-bottom-width + display: flex + flex-grow: 1 + flex-shrink: 0 + justify-content: flex-start + &.is-left + padding-right: 0.75em + &.is-center + flex: none + justify-content: center + padding-left: 0.75em + padding-right: 0.75em + &.is-right + justify-content: flex-end + padding-left: 0.75em + .icon + &:first-child + margin-right: 0.5em + &:last-child + margin-left: 0.5em + // Alignment + &.is-centered + ul + justify-content: center + &.is-right + ul + justify-content: flex-end + // Styles + &.is-boxed + a + border: 1px solid transparent + border-radius: $tabs-boxed-link-radius $tabs-boxed-link-radius 0 0 + &:hover + background-color: $tabs-boxed-link-hover-background-color + border-bottom-color: $tabs-boxed-link-hover-border-bottom-color + li + &.is-active + a + background-color: $tabs-boxed-link-active-background-color + border-color: $tabs-boxed-link-active-border-color + border-bottom-color: $tabs-boxed-link-active-border-bottom-color !important + &.is-fullwidth + li + flex-grow: 1 + flex-shrink: 0 + &.is-toggle + a + border-color: $tabs-toggle-link-border-color + border-style: $tabs-toggle-link-border-style + border-width: $tabs-toggle-link-border-width + margin-bottom: 0 + position: relative + &:hover + background-color: $tabs-toggle-link-hover-background-color + border-color: $tabs-toggle-link-hover-border-color + z-index: 2 + li + & + li + margin-left: -#{$tabs-toggle-link-border-width} + &:first-child a + border-radius: $tabs-toggle-link-radius 0 0 $tabs-toggle-link-radius + &:last-child a + border-radius: 0 $tabs-toggle-link-radius $tabs-toggle-link-radius 0 + &.is-active + a + background-color: $tabs-toggle-link-active-background-color + border-color: $tabs-toggle-link-active-border-color + color: $tabs-toggle-link-active-color + z-index: 1 + ul + border-bottom: none + &.is-toggle-rounded + li + &:first-child a + border-bottom-left-radius: $radius-rounded + border-top-left-radius: $radius-rounded + padding-left: 1.25em + &:last-child a + border-bottom-right-radius: $radius-rounded + border-top-right-radius: $radius-rounded + padding-right: 1.25em + // Sizes + &.is-small + font-size: $size-small + &.is-medium + font-size: $size-medium + &.is-large + font-size: $size-large diff --git a/themes/helm/assets/sass/bulma/sass/elements/_all.sass b/themes/helm/assets/sass/bulma/sass/elements/_all.sass new file mode 100644 index 0000000000..7490c00d86 --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/elements/_all.sass @@ -0,0 +1,15 @@ +@charset "utf-8" + +@import "box.sass" +@import "button.sass" +@import "container.sass" +@import "content.sass" +@import "icon.sass" +@import "image.sass" +@import "notification.sass" +@import "progress.sass" +@import "table.sass" +@import "tag.sass" +@import "title.sass" + +@import "other.sass" diff --git a/themes/helm/assets/sass/bulma/sass/elements/box.sass b/themes/helm/assets/sass/bulma/sass/elements/box.sass new file mode 100644 index 0000000000..2fd18d4984 --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/elements/box.sass @@ -0,0 +1,24 @@ +$box-color: $text !default +$box-background-color: $scheme-main !default +$box-radius: $radius-large !default +$box-shadow: 0 0.5em 1em -0.125em rgba($scheme-invert, 0.1), 0 0px 0 1px rgba($scheme-invert, 0.02) !default +$box-padding: 1.25rem !default + +$box-link-hover-shadow: 0 0.5em 1em -0.125em rgba($scheme-invert, 0.1), 0 0 0 1px $link !default +$box-link-active-shadow: inset 0 1px 2px rgba($scheme-invert, 0.2), 0 0 0 1px $link !default + +.box + @extend %block + background-color: $box-background-color + border-radius: $box-radius + box-shadow: $box-shadow + color: $box-color + display: block + padding: $box-padding + +a.box + &:hover, + &:focus + box-shadow: $box-link-hover-shadow + &:active + box-shadow: $box-link-active-shadow diff --git a/themes/helm/assets/sass/bulma/sass/elements/button.sass b/themes/helm/assets/sass/bulma/sass/elements/button.sass new file mode 100644 index 0000000000..22078aef60 --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/elements/button.sass @@ -0,0 +1,322 @@ +$button-color: $text-strong !default +$button-background-color: $scheme-main !default +$button-family: false !default + +$button-border-color: $border !default +$button-border-width: $control-border-width !default + +$button-padding-vertical: calc(0.5em - #{$button-border-width}) !default +$button-padding-horizontal: 1em !default + +$button-hover-color: $link-hover !default +$button-hover-border-color: $link-hover-border !default + +$button-focus-color: $link-focus !default +$button-focus-border-color: $link-focus-border !default +$button-focus-box-shadow-size: 0 0 0 0.125em !default +$button-focus-box-shadow-color: rgba($link, 0.25) !default + +$button-active-color: $link-active !default +$button-active-border-color: $link-active-border !default + +$button-text-color: $text !default +$button-text-hover-background-color: $background !default +$button-text-hover-color: $text-strong !default + +$button-disabled-background-color: $scheme-main !default +$button-disabled-border-color: $border !default +$button-disabled-shadow: none !default +$button-disabled-opacity: 0.5 !default + +$button-static-color: $text-light !default +$button-static-background-color: $scheme-main-ter !default +$button-static-border-color: $border !default + +// The button sizes use mixins so they can be used at different breakpoints +=button-small + border-radius: $radius-small + font-size: $size-small +=button-normal + font-size: $size-normal +=button-medium + font-size: $size-medium +=button-large + font-size: $size-large + +.button + @extend %control + @extend %unselectable + background-color: $button-background-color + border-color: $button-border-color + border-width: $button-border-width + color: $button-color + cursor: pointer + @if $button-family + font-family: $button-family + justify-content: center + padding-bottom: $button-padding-vertical + padding-left: $button-padding-horizontal + padding-right: $button-padding-horizontal + padding-top: $button-padding-vertical + text-align: center + white-space: nowrap + strong + color: inherit + .icon + &, + &.is-small, + &.is-medium, + &.is-large + height: 1.5em + width: 1.5em + &:first-child:not(:last-child) + margin-left: calc(#{-1 / 2 * $button-padding-horizontal} - #{$button-border-width}) + margin-right: $button-padding-horizontal / 4 + &:last-child:not(:first-child) + margin-left: $button-padding-horizontal / 4 + margin-right: calc(#{-1 / 2 * $button-padding-horizontal} - #{$button-border-width}) + &:first-child:last-child + margin-left: calc(#{-1 / 2 * $button-padding-horizontal} - #{$button-border-width}) + margin-right: calc(#{-1 / 2 * $button-padding-horizontal} - #{$button-border-width}) + // States + &:hover, + &.is-hovered + border-color: $button-hover-border-color + color: $button-hover-color + &:focus, + &.is-focused + border-color: $button-focus-border-color + color: $button-focus-color + &:not(:active) + box-shadow: $button-focus-box-shadow-size $button-focus-box-shadow-color + &:active, + &.is-active + border-color: $button-active-border-color + color: $button-active-color + // Colors + &.is-text + background-color: transparent + border-color: transparent + color: $button-text-color + text-decoration: underline + &:hover, + &.is-hovered, + &:focus, + &.is-focused + background-color: $button-text-hover-background-color + color: $button-text-hover-color + &:active, + &.is-active + background-color: darken($button-text-hover-background-color, 5%) + color: $button-text-hover-color + &[disabled], + fieldset[disabled] & + background-color: transparent + border-color: transparent + box-shadow: none + @each $name, $pair in $colors + $color: nth($pair, 1) + $color-invert: nth($pair, 2) + &.is-#{$name} + background-color: $color + border-color: transparent + color: $color-invert + &:hover, + &.is-hovered + background-color: darken($color, 2.5%) + border-color: transparent + color: $color-invert + &:focus, + &.is-focused + border-color: transparent + color: $color-invert + &:not(:active) + box-shadow: $button-focus-box-shadow-size rgba($color, 0.25) + &:active, + &.is-active + background-color: darken($color, 5%) + border-color: transparent + color: $color-invert + &[disabled], + fieldset[disabled] & + background-color: $color + border-color: transparent + box-shadow: none + &.is-inverted + background-color: $color-invert + color: $color + &:hover, + &.is-hovered + background-color: darken($color-invert, 5%) + &[disabled], + fieldset[disabled] & + background-color: $color-invert + border-color: transparent + box-shadow: none + color: $color + &.is-loading + &::after + border-color: transparent transparent $color-invert $color-invert !important + &.is-outlined + background-color: transparent + border-color: $color + color: $color + &:hover, + &.is-hovered, + &:focus, + &.is-focused + background-color: $color + border-color: $color + color: $color-invert + &.is-loading + &::after + border-color: transparent transparent $color $color !important + &:hover, + &.is-hovered, + &:focus, + &.is-focused + &::after + border-color: transparent transparent $color-invert $color-invert !important + &[disabled], + fieldset[disabled] & + background-color: transparent + border-color: $color + box-shadow: none + color: $color + &.is-inverted.is-outlined + background-color: transparent + border-color: $color-invert + color: $color-invert + &:hover, + &.is-hovered, + &:focus, + &.is-focused + background-color: $color-invert + color: $color + &.is-loading + &:hover, + &.is-hovered, + &:focus, + &.is-focused + &::after + border-color: transparent transparent $color $color !important + &[disabled], + fieldset[disabled] & + background-color: transparent + border-color: $color-invert + box-shadow: none + color: $color-invert + // If light and dark colors are provided + @if length($pair) >= 4 + $color-light: nth($pair, 3) + $color-dark: nth($pair, 4) + &.is-light + background-color: $color-light + color: $color-dark + &:hover, + &.is-hovered + background-color: darken($color-light, 2.5%) + border-color: transparent + color: $color-dark + &:active, + &.is-active + background-color: darken($color-light, 5%) + border-color: transparent + color: $color-dark + // Sizes + &.is-small + +button-small + &.is-normal + +button-normal + &.is-medium + +button-medium + &.is-large + +button-large + // Modifiers + &[disabled], + fieldset[disabled] & + background-color: $button-disabled-background-color + border-color: $button-disabled-border-color + box-shadow: $button-disabled-shadow + opacity: $button-disabled-opacity + &.is-fullwidth + display: flex + width: 100% + &.is-loading + color: transparent !important + pointer-events: none + &::after + @extend %loader + +center(1em) + position: absolute !important + &.is-static + background-color: $button-static-background-color + border-color: $button-static-border-color + color: $button-static-color + box-shadow: none + pointer-events: none + &.is-rounded + border-radius: $radius-rounded + padding-left: calc(#{$button-padding-horizontal} + 0.25em) + padding-right: calc(#{$button-padding-horizontal} + 0.25em) + +.buttons + align-items: center + display: flex + flex-wrap: wrap + justify-content: flex-start + .button + margin-bottom: 0.5rem + &:not(:last-child):not(.is-fullwidth) + margin-right: 0.5rem + &:last-child + margin-bottom: -0.5rem + &:not(:last-child) + margin-bottom: 1rem + // Sizes + &.are-small + .button:not(.is-normal):not(.is-medium):not(.is-large) + +button-small + &.are-medium + .button:not(.is-small):not(.is-normal):not(.is-large) + +button-medium + &.are-large + .button:not(.is-small):not(.is-normal):not(.is-medium) + +button-large + &.has-addons + .button + &:not(:first-child) + border-bottom-left-radius: 0 + border-top-left-radius: 0 + &:not(:last-child) + border-bottom-right-radius: 0 + border-top-right-radius: 0 + margin-right: -1px + &:last-child + margin-right: 0 + &:hover, + &.is-hovered + z-index: 2 + &:focus, + &.is-focused, + &:active, + &.is-active, + &.is-selected + z-index: 3 + &:hover + z-index: 4 + &.is-expanded + flex-grow: 1 + flex-shrink: 1 + &.is-centered + justify-content: center + &:not(.has-addons) + .button:not(.is-fullwidth) + margin-left: 0.25rem + margin-right: 0.25rem + &.is-right + justify-content: flex-end + &:not(.has-addons) + .button:not(.is-fullwidth) + margin-left: 0.25rem + margin-right: 0.25rem diff --git a/themes/helm/assets/sass/bulma/sass/elements/container.sass b/themes/helm/assets/sass/bulma/sass/elements/container.sass new file mode 100644 index 0000000000..d88eb94acc --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/elements/container.sass @@ -0,0 +1,24 @@ +$container-offset: (2 * $gap) !default + +.container + flex-grow: 1 + margin: 0 auto + position: relative + width: auto + &.is-fluid + max-width: none + padding-left: $gap + padding-right: $gap + width: 100% + +desktop + max-width: $desktop - $container-offset + +until-widescreen + &.is-widescreen + max-width: $widescreen - $container-offset + +until-fullhd + &.is-fullhd + max-width: $fullhd - $container-offset + +widescreen + max-width: $widescreen - $container-offset + +fullhd + max-width: $fullhd - $container-offset diff --git a/themes/helm/assets/sass/bulma/sass/elements/content.sass b/themes/helm/assets/sass/bulma/sass/elements/content.sass new file mode 100644 index 0000000000..001419abd8 --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/elements/content.sass @@ -0,0 +1,155 @@ +$content-heading-color: $text-strong !default +$content-heading-weight: $weight-semibold !default +$content-heading-line-height: 1.125 !default + +$content-blockquote-background-color: $background !default +$content-blockquote-border-left: 5px solid $border !default +$content-blockquote-padding: 1.25em 1.5em !default + +$content-pre-padding: 1.25em 1.5em !default + +$content-table-cell-border: 1px solid $border !default +$content-table-cell-border-width: 0 0 1px !default +$content-table-cell-padding: 0.5em 0.75em !default +$content-table-cell-heading-color: $text-strong !default +$content-table-head-cell-border-width: 0 0 2px !default +$content-table-head-cell-color: $text-strong !default +$content-table-foot-cell-border-width: 2px 0 0 !default +$content-table-foot-cell-color: $text-strong !default + +.content + @extend %block + // Inline + li + li + margin-top: 0.25em + // Block + p, + dl, + ol, + ul, + blockquote, + pre, + table + &:not(:last-child) + margin-bottom: 1em + h1, + h2, + h3, + h4, + h5, + h6 + color: $content-heading-color + font-weight: $content-heading-weight + line-height: $content-heading-line-height + h1 + font-size: 2em + margin-bottom: 0.5em + &:not(:first-child) + margin-top: 1em + h2 + font-size: 1.75em + margin-bottom: 0.5714em + &:not(:first-child) + margin-top: 1.1428em + h3 + font-size: 1.5em + margin-bottom: 0.6666em + &:not(:first-child) + margin-top: 1.3333em + h4 + font-size: 1.25em + margin-bottom: 0.8em + h5 + font-size: 1.125em + margin-bottom: 0.8888em + h6 + font-size: 1em + margin-bottom: 1em + blockquote + background-color: $content-blockquote-background-color + border-left: $content-blockquote-border-left + padding: $content-blockquote-padding + ol + list-style-position: outside + margin-left: 2em + margin-top: 1em + &:not([type]) + list-style-type: decimal + &.is-lower-alpha + list-style-type: lower-alpha + &.is-lower-roman + list-style-type: lower-roman + &.is-upper-alpha + list-style-type: upper-alpha + &.is-upper-roman + list-style-type: upper-roman + ul + list-style: disc outside + margin-left: 2em + margin-top: 1em + ul + list-style-type: circle + margin-top: 0.5em + ul + list-style-type: square + dd + margin-left: 2em + figure + margin-left: 2em + margin-right: 2em + text-align: center + &:not(:first-child) + margin-top: 2em + &:not(:last-child) + margin-bottom: 2em + img + display: inline-block + figcaption + font-style: italic + pre + +overflow-touch + overflow-x: auto + padding: $content-pre-padding + white-space: pre + word-wrap: normal + sup, + sub + font-size: 75% + table + width: 100% + td, + th + border: $content-table-cell-border + border-width: $content-table-cell-border-width + padding: $content-table-cell-padding + vertical-align: top + th + color: $content-table-cell-heading-color + &:not([align]) + text-align: left + thead + td, + th + border-width: $content-table-head-cell-border-width + color: $content-table-head-cell-color + tfoot + td, + th + border-width: $content-table-foot-cell-border-width + color: $content-table-foot-cell-color + tbody + tr + &:last-child + td, + th + border-bottom-width: 0 + .tabs + li + li + margin-top: 0 + // Sizes + &.is-small + font-size: $size-small + &.is-medium + font-size: $size-medium + &.is-large + font-size: $size-large diff --git a/themes/helm/assets/sass/bulma/sass/elements/form.sass b/themes/helm/assets/sass/bulma/sass/elements/form.sass new file mode 100644 index 0000000000..3122dc4c5e --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/elements/form.sass @@ -0,0 +1 @@ +@warn "The form.sass file is DEPRECATED. It has moved into its own /form folder. Please import sass/form/_all instead." diff --git a/themes/helm/assets/sass/bulma/sass/elements/icon.sass b/themes/helm/assets/sass/bulma/sass/elements/icon.sass new file mode 100644 index 0000000000..988546c7fc --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/elements/icon.sass @@ -0,0 +1,21 @@ +$icon-dimensions: 1.5rem !default +$icon-dimensions-small: 1rem !default +$icon-dimensions-medium: 2rem !default +$icon-dimensions-large: 3rem !default + +.icon + align-items: center + display: inline-flex + justify-content: center + height: $icon-dimensions + width: $icon-dimensions + // Sizes + &.is-small + height: $icon-dimensions-small + width: $icon-dimensions-small + &.is-medium + height: $icon-dimensions-medium + width: $icon-dimensions-medium + &.is-large + height: $icon-dimensions-large + width: $icon-dimensions-large diff --git a/themes/helm/assets/sass/bulma/sass/elements/image.sass b/themes/helm/assets/sass/bulma/sass/elements/image.sass new file mode 100644 index 0000000000..7547abcfd6 --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/elements/image.sass @@ -0,0 +1,71 @@ +$dimensions: 16 24 32 48 64 96 128 !default + +.image + display: block + position: relative + img + display: block + height: auto + width: 100% + &.is-rounded + border-radius: $radius-rounded + &.is-fullwidth + width: 100% + // Ratio + &.is-square, + &.is-1by1, + &.is-5by4, + &.is-4by3, + &.is-3by2, + &.is-5by3, + &.is-16by9, + &.is-2by1, + &.is-3by1, + &.is-4by5, + &.is-3by4, + &.is-2by3, + &.is-3by5, + &.is-9by16, + &.is-1by2, + &.is-1by3 + img, + .has-ratio + @extend %overlay + height: 100% + width: 100% + &.is-square, + &.is-1by1 + padding-top: 100% + &.is-5by4 + padding-top: 80% + &.is-4by3 + padding-top: 75% + &.is-3by2 + padding-top: 66.6666% + &.is-5by3 + padding-top: 60% + &.is-16by9 + padding-top: 56.25% + &.is-2by1 + padding-top: 50% + &.is-3by1 + padding-top: 33.3333% + &.is-4by5 + padding-top: 125% + &.is-3by4 + padding-top: 133.3333% + &.is-2by3 + padding-top: 150% + &.is-3by5 + padding-top: 166.6666% + &.is-9by16 + padding-top: 177.7777% + &.is-1by2 + padding-top: 200% + &.is-1by3 + padding-top: 300% + // Sizes + @each $dimension in $dimensions + &.is-#{$dimension}x#{$dimension} + height: $dimension * 1px + width: $dimension * 1px diff --git a/themes/helm/assets/sass/bulma/sass/elements/notification.sass b/themes/helm/assets/sass/bulma/sass/elements/notification.sass new file mode 100644 index 0000000000..24122e78d3 --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/elements/notification.sass @@ -0,0 +1,36 @@ +$notification-background-color: $background !default +$notification-code-background-color: $scheme-main !default +$notification-radius: $radius !default +$notification-padding: 1.25rem 2.5rem 1.25rem 1.5rem !default + +.notification + @extend %block + background-color: $notification-background-color + border-radius: $notification-radius + padding: $notification-padding + position: relative + a:not(.button):not(.dropdown-item) + color: currentColor + text-decoration: underline + strong + color: currentColor + code, + pre + background: $notification-code-background-color + pre code + background: transparent + & > .delete + position: absolute + right: 0.5rem + top: 0.5rem + .title, + .subtitle, + .content + color: currentColor + // Colors + @each $name, $pair in $colors + $color: nth($pair, 1) + $color-invert: nth($pair, 2) + &.is-#{$name} + background-color: $color + color: $color-invert diff --git a/themes/helm/assets/sass/bulma/sass/elements/other.sass b/themes/helm/assets/sass/bulma/sass/elements/other.sass new file mode 100644 index 0000000000..5725617c26 --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/elements/other.sass @@ -0,0 +1,39 @@ +.block + @extend %block + +.delete + @extend %delete + +.heading + display: block + font-size: 11px + letter-spacing: 1px + margin-bottom: 5px + text-transform: uppercase + +.highlight + @extend %block + font-weight: $weight-normal + max-width: 100% + overflow: hidden + padding: 0 + pre + overflow: auto + max-width: 100% + +.loader + @extend %loader + +.number + align-items: center + background-color: $background + border-radius: $radius-rounded + display: inline-flex + font-size: $size-medium + height: 2em + justify-content: center + margin-right: 1.5rem + min-width: 2.5em + padding: 0.25rem 0.5rem + text-align: center + vertical-align: top diff --git a/themes/helm/assets/sass/bulma/sass/elements/progress.sass b/themes/helm/assets/sass/bulma/sass/elements/progress.sass new file mode 100644 index 0000000000..bb43bb6017 --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/elements/progress.sass @@ -0,0 +1,67 @@ +$progress-bar-background-color: $border-light !default +$progress-value-background-color: $text !default +$progress-border-radius: $radius-rounded !default + +$progress-indeterminate-duration: 1.5s !default + +.progress + @extend %block + -moz-appearance: none + -webkit-appearance: none + border: none + border-radius: $progress-border-radius + display: block + height: $size-normal + overflow: hidden + padding: 0 + width: 100% + &::-webkit-progress-bar + background-color: $progress-bar-background-color + &::-webkit-progress-value + background-color: $progress-value-background-color + &::-moz-progress-bar + background-color: $progress-value-background-color + &::-ms-fill + background-color: $progress-value-background-color + border: none + // Colors + @each $name, $pair in $colors + $color: nth($pair, 1) + &.is-#{$name} + &::-webkit-progress-value + background-color: $color + &::-moz-progress-bar + background-color: $color + &::-ms-fill + background-color: $color + &:indeterminate + background-image: linear-gradient(to right, $color 30%, $progress-bar-background-color 30%) + + &:indeterminate + animation-duration: $progress-indeterminate-duration + animation-iteration-count: infinite + animation-name: moveIndeterminate + animation-timing-function: linear + background-color: $progress-bar-background-color + background-image: linear-gradient(to right, $text 30%, $progress-bar-background-color 30%) + background-position: top left + background-repeat: no-repeat + background-size: 150% 150% + &::-webkit-progress-bar + background-color: transparent + &::-moz-progress-bar + background-color: transparent + + // Sizes + &.is-small + height: $size-small + &.is-medium + height: $size-medium + &.is-large + height: $size-large + +@keyframes moveIndeterminate + from + background-position: 200% 0 + to + background-position: -200% 0 diff --git a/themes/helm/assets/sass/bulma/sass/elements/table.sass b/themes/helm/assets/sass/bulma/sass/elements/table.sass new file mode 100644 index 0000000000..2e6036ad38 --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/elements/table.sass @@ -0,0 +1,127 @@ +$table-color: $text-strong !default +$table-background-color: $scheme-main !default + +$table-cell-border: 1px solid $border !default +$table-cell-border-width: 0 0 1px !default +$table-cell-padding: 0.5em 0.75em !default +$table-cell-heading-color: $text-strong !default + +$table-head-cell-border-width: 0 0 2px !default +$table-head-cell-color: $text-strong !default +$table-foot-cell-border-width: 2px 0 0 !default +$table-foot-cell-color: $text-strong !default + +$table-head-background-color: transparent !default +$table-body-background-color: transparent !default +$table-foot-background-color: transparent !default + +$table-row-hover-background-color: $scheme-main-bis !default + +$table-row-active-background-color: $primary !default +$table-row-active-color: $primary-invert !default + +$table-striped-row-even-background-color: $scheme-main-bis !default +$table-striped-row-even-hover-background-color: $scheme-main-ter !default + +.table + @extend %block + background-color: $table-background-color + color: $table-color + td, + th + border: $table-cell-border + border-width: $table-cell-border-width + padding: $table-cell-padding + vertical-align: top + // Colors + @each $name, $pair in $colors + $color: nth($pair, 1) + $color-invert: nth($pair, 2) + &.is-#{$name} + background-color: $color + border-color: $color + color: $color-invert + // Modifiers + &.is-narrow + white-space: nowrap + width: 1% + &.is-selected + background-color: $table-row-active-background-color + color: $table-row-active-color + a, + strong + color: currentColor + th + color: $table-cell-heading-color + &:not([align]) + text-align: left + tr + &.is-selected + background-color: $table-row-active-background-color + color: $table-row-active-color + a, + strong + color: currentColor + td, + th + border-color: $table-row-active-color + color: currentColor + thead + background-color: $table-head-background-color + td, + th + border-width: $table-head-cell-border-width + color: $table-head-cell-color + tfoot + background-color: $table-foot-background-color + td, + th + border-width: $table-foot-cell-border-width + color: $table-foot-cell-color + tbody + background-color: $table-body-background-color + tr + &:last-child + td, + th + border-bottom-width: 0 + // Modifiers + &.is-bordered + td, + th + border-width: 1px + tr + &:last-child + td, + th + border-bottom-width: 1px + &.is-fullwidth + width: 100% + &.is-hoverable + tbody + tr:not(.is-selected) + &:hover + background-color: $table-row-hover-background-color + &.is-striped + tbody + tr:not(.is-selected) + &:hover + background-color: $table-row-hover-background-color + &:nth-child(even) + background-color: $table-striped-row-even-hover-background-color + &.is-narrow + td, + th + padding: 0.25em 0.5em + &.is-striped + tbody + tr:not(.is-selected) + &:nth-child(even) + background-color: $table-striped-row-even-background-color + +.table-container + @extend %block + +overflow-touch + overflow: auto + overflow-y: hidden + max-width: 100% diff --git a/themes/helm/assets/sass/bulma/sass/elements/tag.sass b/themes/helm/assets/sass/bulma/sass/elements/tag.sass new file mode 100644 index 0000000000..e0fb89efe6 --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/elements/tag.sass @@ -0,0 +1,128 @@ +$tag-background-color: $background !default +$tag-color: $text !default +$tag-radius: $radius !default +$tag-delete-margin: 1px !default + +.tags + align-items: center + display: flex + flex-wrap: wrap + justify-content: flex-start + .tag + margin-bottom: 0.5rem + &:not(:last-child) + margin-right: 0.5rem + &:last-child + margin-bottom: -0.5rem + &:not(:last-child) + margin-bottom: 1rem + // Sizes + &.are-medium + .tag:not(.is-normal):not(.is-large) + font-size: $size-normal + &.are-large + .tag:not(.is-normal):not(.is-medium) + font-size: $size-medium + &.is-centered + justify-content: center + .tag + margin-right: 0.25rem + margin-left: 0.25rem + &.is-right + justify-content: flex-end + .tag + &:not(:first-child) + margin-left: 0.5rem + &:not(:last-child) + margin-right: 0 + &.has-addons + .tag + margin-right: 0 + &:not(:first-child) + margin-left: 0 + border-bottom-left-radius: 0 + border-top-left-radius: 0 + &:not(:last-child) + border-bottom-right-radius: 0 + border-top-right-radius: 0 + +.tag:not(body) + align-items: center + background-color: $tag-background-color + border-radius: $tag-radius + color: $tag-color + display: inline-flex + font-size: $size-small + height: 2em + justify-content: center + line-height: 1.5 + padding-left: 0.75em + padding-right: 0.75em + white-space: nowrap + .delete + margin-left: 0.25rem + margin-right: -0.375rem + // Colors + @each $name, $pair in $colors + $color: nth($pair, 1) + $color-invert: nth($pair, 2) + &.is-#{$name} + background-color: $color + color: $color-invert + // If a light and dark colors are provided + @if length($pair) > 3 + $color-light: nth($pair, 3) + $color-dark: nth($pair, 4) + &.is-light + background-color: $color-light + color: $color-dark + // Sizes + &.is-normal + font-size: $size-small + &.is-medium + font-size: $size-normal + &.is-large + font-size: $size-medium + .icon + &:first-child:not(:last-child) + margin-left: -0.375em + margin-right: 0.1875em + &:last-child:not(:first-child) + margin-left: 0.1875em + margin-right: -0.375em + &:first-child:last-child + margin-left: -0.375em + margin-right: -0.375em + // Modifiers + &.is-delete + margin-left: $tag-delete-margin + padding: 0 + position: relative + width: 2em + &::before, + &::after + background-color: currentColor + content: "" + display: block + left: 50% + position: absolute + top: 50% + transform: translateX(-50%) translateY(-50%) rotate(45deg) + transform-origin: center center + &::before + height: 1px + width: 50% + &::after + height: 50% + width: 1px + &:hover, + &:focus + background-color: darken($tag-background-color, 5%) + &:active + background-color: darken($tag-background-color, 10%) + &.is-rounded + border-radius: $radius-rounded + +a.tag + &:hover + text-decoration: underline diff --git a/themes/helm/assets/sass/bulma/sass/elements/title.sass b/themes/helm/assets/sass/bulma/sass/elements/title.sass new file mode 100644 index 0000000000..fa9947dd85 --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/elements/title.sass @@ -0,0 +1,70 @@ +$title-color: $text-strong !default +$title-family: false !default +$title-size: $size-3 !default +$title-weight: $weight-semibold !default +$title-line-height: 1.125 !default +$title-strong-color: inherit !default +$title-strong-weight: inherit !default +$title-sub-size: 0.75em !default +$title-sup-size: 0.75em !default + +$subtitle-color: $text !default +$subtitle-family: false !default +$subtitle-size: $size-5 !default +$subtitle-weight: $weight-normal !default +$subtitle-line-height: 1.25 !default +$subtitle-strong-color: $text-strong !default +$subtitle-strong-weight: $weight-semibold !default +$subtitle-negative-margin: -1.25rem !default + +.title, +.subtitle + @extend %block + word-break: break-word + em, + span + font-weight: inherit + sub + font-size: $title-sub-size + sup + font-size: $title-sup-size + .tag + vertical-align: middle + +.title + color: $title-color + @if $title-family + font-family: $title-family + font-size: $title-size + font-weight: $title-weight + line-height: $title-line-height + strong + color: $title-strong-color + font-weight: $title-strong-weight + & + .highlight + margin-top: -0.75rem + &:not(.is-spaced) + .subtitle + margin-top: $subtitle-negative-margin + // Sizes + @each $size in $sizes + $i: index($sizes, $size) + &.is-#{$i} + font-size: $size + +.subtitle + color: $subtitle-color + @if $subtitle-family + font-family: $subtitle-family + font-size: $subtitle-size + font-weight: $subtitle-weight + line-height: $subtitle-line-height + strong + color: $subtitle-strong-color + font-weight: $subtitle-strong-weight + &:not(.is-spaced) + .title + margin-top: $subtitle-negative-margin + // Sizes + @each $size in $sizes + $i: index($sizes, $size) + &.is-#{$i} + font-size: $size diff --git a/themes/helm/assets/sass/bulma/sass/form/_all.sass b/themes/helm/assets/sass/bulma/sass/form/_all.sass new file mode 100644 index 0000000000..d9a2b95525 --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/form/_all.sass @@ -0,0 +1,8 @@ +@charset "utf-8" + +@import "shared.sass" +@import "input-textarea.sass" +@import "checkbox-radio.sass" +@import "select.sass" +@import "file.sass" +@import "tools.sass" diff --git a/themes/helm/assets/sass/bulma/sass/form/checkbox-radio.sass b/themes/helm/assets/sass/bulma/sass/form/checkbox-radio.sass new file mode 100644 index 0000000000..d9f3ff0c5d --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/form/checkbox-radio.sass @@ -0,0 +1,21 @@ +%checkbox-radio + cursor: pointer + display: inline-block + line-height: 1.25 + position: relative + input + cursor: pointer + &:hover + color: $input-hover-color + &[disabled], + fieldset[disabled] & + color: $input-disabled-color + cursor: not-allowed + +.checkbox + @extend %checkbox-radio + +.radio + @extend %checkbox-radio + & + .radio + margin-left: 0.5em diff --git a/themes/helm/assets/sass/bulma/sass/form/file.sass b/themes/helm/assets/sass/bulma/sass/form/file.sass new file mode 100644 index 0000000000..41cc02154a --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/form/file.sass @@ -0,0 +1,180 @@ +$file-border-color: $border !default +$file-radius: $radius !default + +$file-cta-background-color: $scheme-main-ter !default +$file-cta-color: $text !default +$file-cta-hover-color: $text-strong !default +$file-cta-active-color: $text-strong !default + +$file-name-border-color: $border !default +$file-name-border-style: solid !default +$file-name-border-width: 1px 1px 1px 0 !default +$file-name-max-width: 16em !default + +.file + @extend %unselectable + align-items: stretch + display: flex + justify-content: flex-start + position: relative + // Colors + @each $name, $pair in $colors + $color: nth($pair, 1) + $color-invert: nth($pair, 2) + &.is-#{$name} + .file-cta + background-color: $color + border-color: transparent + color: $color-invert + &:hover, + &.is-hovered + .file-cta + background-color: darken($color, 2.5%) + border-color: transparent + color: $color-invert + &:focus, + &.is-focused + .file-cta + border-color: transparent + box-shadow: 0 0 0.5em rgba($color, 0.25) + color: $color-invert + &:active, + &.is-active + .file-cta + background-color: darken($color, 5%) + border-color: transparent + color: $color-invert + // Sizes + &.is-small + font-size: $size-small + &.is-medium + font-size: $size-medium + .file-icon + .fa + font-size: 21px + &.is-large + font-size: $size-large + .file-icon + .fa + font-size: 28px + // Modifiers + &.has-name + .file-cta + border-bottom-right-radius: 0 + border-top-right-radius: 0 + .file-name + border-bottom-left-radius: 0 + border-top-left-radius: 0 + &.is-empty + .file-cta + border-radius: $file-radius + .file-name + display: none + &.is-boxed + .file-label + flex-direction: column + .file-cta + flex-direction: column + height: auto + padding: 1em 3em + .file-name + border-width: 0 1px 1px + .file-icon + height: 1.5em + width: 1.5em + .fa + font-size: 21px + &.is-small + .file-icon .fa + font-size: 14px + &.is-medium + .file-icon .fa + font-size: 28px + &.is-large + .file-icon .fa + font-size: 35px + &.has-name + .file-cta + border-radius: $file-radius $file-radius 0 0 + .file-name + border-radius: 0 0 $file-radius $file-radius + border-width: 0 1px 1px + &.is-centered + justify-content: center + &.is-fullwidth + .file-label + width: 100% + .file-name + flex-grow: 1 + max-width: none + &.is-right + justify-content: flex-end + .file-cta + border-radius: 0 $file-radius $file-radius 0 + .file-name + border-radius: $file-radius 0 0 $file-radius + border-width: 1px 0 1px 1px + order: -1 + +.file-label + align-items: stretch + display: flex + cursor: pointer + justify-content: flex-start + overflow: hidden + position: relative + &:hover + .file-cta + background-color: darken($file-cta-background-color, 2.5%) + color: $file-cta-hover-color + .file-name + border-color: darken($file-name-border-color, 2.5%) + &:active + .file-cta + background-color: darken($file-cta-background-color, 5%) + color: $file-cta-active-color + .file-name + border-color: darken($file-name-border-color, 5%) + +.file-input + height: 100% + left: 0 + opacity: 0 + outline: none + position: absolute + top: 0 + width: 100% + +.file-cta, +.file-name + @extend %control + border-color: $file-border-color + border-radius: $file-radius + font-size: 1em + padding-left: 1em + padding-right: 1em + white-space: nowrap + +.file-cta + background-color: $file-cta-background-color + color: $file-cta-color + +.file-name + border-color: $file-name-border-color + border-style: $file-name-border-style + border-width: $file-name-border-width + display: block + max-width: $file-name-max-width + overflow: hidden + text-align: left + text-overflow: ellipsis + +.file-icon + align-items: center + display: flex + height: 1em + justify-content: center + margin-right: 0.5em + width: 1em + .fa + font-size: 14px diff --git a/themes/helm/assets/sass/bulma/sass/form/input-textarea.sass b/themes/helm/assets/sass/bulma/sass/form/input-textarea.sass new file mode 100644 index 0000000000..7636cdaed8 --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/form/input-textarea.sass @@ -0,0 +1,64 @@ +$textarea-padding: $control-padding-horizontal !default +$textarea-max-height: 40em !default +$textarea-min-height: 8em !default + +%input-textarea + @extend %input + box-shadow: $input-shadow + max-width: 100% + width: 100% + &[readonly] + box-shadow: none + // Colors + @each $name, $pair in $colors + $color: nth($pair, 1) + &.is-#{$name} + border-color: $color + &:focus, + &.is-focused, + &:active, + &.is-active + box-shadow: $input-focus-box-shadow-size rgba($color, 0.25) + // Sizes + &.is-small + +control-small + &.is-medium + +control-medium + &.is-large + +control-large + // Modifiers + &.is-fullwidth + display: block + width: 100% + &.is-inline + display: inline + width: auto + +.input + @extend %input-textarea + &.is-rounded + border-radius: $radius-rounded + padding-left: calc(#{$control-padding-horizontal} + 0.375em) + padding-right: calc(#{$control-padding-horizontal} + 0.375em) + &.is-static + background-color: transparent + border-color: transparent + box-shadow: none + padding-left: 0 + padding-right: 0 + +.textarea + @extend %input-textarea + display: block + max-width: 100% + min-width: 100% + padding: $textarea-padding + resize: vertical + &:not([rows]) + max-height: $textarea-max-height + min-height: $textarea-min-height + &[rows] + height: initial + // Modifiers + &.has-fixed-size + resize: none diff --git a/themes/helm/assets/sass/bulma/sass/form/select.sass b/themes/helm/assets/sass/bulma/sass/form/select.sass new file mode 100644 index 0000000000..909b9d5249 --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/form/select.sass @@ -0,0 +1,85 @@ +.select + display: inline-block + max-width: 100% + position: relative + vertical-align: top + &:not(.is-multiple) + height: $input-height + &:not(.is-multiple):not(.is-loading) + &::after + @extend %arrow + border-color: $input-arrow + right: 1.125em + z-index: 4 + &.is-rounded + select + border-radius: $radius-rounded + padding-left: 1em + select + @extend %input + cursor: pointer + display: block + font-size: 1em + max-width: 100% + outline: none + &::-ms-expand + display: none + &[disabled]:hover, + fieldset[disabled] &:hover + border-color: $input-disabled-border-color + &:not([multiple]) + padding-right: 2.5em + &[multiple] + height: auto + padding: 0 + option + padding: 0.5em 1em + // States + &:not(.is-multiple):not(.is-loading):hover + &::after + border-color: $input-hover-color + // Colors + @each $name, $pair in $colors + $color: nth($pair, 1) + &.is-#{$name} + &:not(:hover)::after + border-color: $color + select + border-color: $color + &:hover, + &.is-hovered + border-color: darken($color, 5%) + &:focus, + &.is-focused, + &:active, + &.is-active + box-shadow: $input-focus-box-shadow-size rgba($color, 0.25) + // Sizes + &.is-small + +control-small + &.is-medium + +control-medium + &.is-large + +control-large + // Modifiers + &.is-disabled + &::after + border-color: $input-disabled-color + &.is-fullwidth + width: 100% + select + width: 100% + &.is-loading + &::after + @extend %loader + margin-top: 0 + position: absolute + right: 0.625em + top: 0.625em + transform: none + &.is-small:after + font-size: $size-small + &.is-medium:after + font-size: $size-medium + &.is-large:after + font-size: $size-large diff --git a/themes/helm/assets/sass/bulma/sass/form/shared.sass b/themes/helm/assets/sass/bulma/sass/form/shared.sass new file mode 100644 index 0000000000..f9c6890f46 --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/form/shared.sass @@ -0,0 +1,55 @@ +$input-color: $text-strong !default +$input-background-color: $scheme-main !default +$input-border-color: $border !default +$input-height: $control-height !default +$input-shadow: inset 0 0.0625em 0.125em rgba($scheme-invert, 0.05) !default +$input-placeholder-color: rgba($input-color, 0.3) !default + +$input-hover-color: $text-strong !default +$input-hover-border-color: $border-hover !default + +$input-focus-color: $text-strong !default +$input-focus-border-color: $link !default +$input-focus-box-shadow-size: 0 0 0 0.125em !default +$input-focus-box-shadow-color: rgba($link, 0.25) !default + +$input-disabled-color: $text-light !default +$input-disabled-background-color: $background !default +$input-disabled-border-color: $background !default +$input-disabled-placeholder-color: rgba($input-disabled-color, 0.3) !default + +$input-arrow: $link !default + +$input-icon-color: $border !default +$input-icon-active-color: $text !default + +$input-radius: $radius !default + +=input + @extend %control + background-color: $input-background-color + border-color: $input-border-color + border-radius: $input-radius + color: $input-color + +placeholder + color: $input-placeholder-color + &:hover, + &.is-hovered + border-color: $input-hover-border-color + &:focus, + &.is-focused, + &:active, + &.is-active + border-color: $input-focus-border-color + box-shadow: $input-focus-box-shadow-size $input-focus-box-shadow-color + &[disabled], + fieldset[disabled] & + background-color: $input-disabled-background-color + border-color: $input-disabled-border-color + box-shadow: none + color: $input-disabled-color + +placeholder + color: $input-disabled-placeholder-color + +%input + +input diff --git a/themes/helm/assets/sass/bulma/sass/form/tools.sass b/themes/helm/assets/sass/bulma/sass/form/tools.sass new file mode 100644 index 0000000000..ff2f8e208a --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/form/tools.sass @@ -0,0 +1,205 @@ +$label-color: $text-strong !default +$label-weight: $weight-bold !default + +$help-size: $size-small !default + +.label + color: $label-color + display: block + font-size: $size-normal + font-weight: $label-weight + &:not(:last-child) + margin-bottom: 0.5em + // Sizes + &.is-small + font-size: $size-small + &.is-medium + font-size: $size-medium + &.is-large + font-size: $size-large + +.help + display: block + font-size: $help-size + margin-top: 0.25rem + @each $name, $pair in $colors + $color: nth($pair, 1) + &.is-#{$name} + color: $color + +// Containers + +.field + &:not(:last-child) + margin-bottom: 0.75rem + // Modifiers + &.has-addons + display: flex + justify-content: flex-start + .control + &:not(:last-child) + margin-right: -1px + &:not(:first-child):not(:last-child) + .button, + .input, + .select select + border-radius: 0 + &:first-child:not(:only-child) + .button, + .input, + .select select + border-bottom-right-radius: 0 + border-top-right-radius: 0 + &:last-child:not(:only-child) + .button, + .input, + .select select + border-bottom-left-radius: 0 + border-top-left-radius: 0 + .button, + .input, + .select select + &:not([disabled]) + &:hover, + &.is-hovered + z-index: 2 + &:focus, + &.is-focused, + &:active, + &.is-active + z-index: 3 + &:hover + z-index: 4 + &.is-expanded + flex-grow: 1 + flex-shrink: 1 + &.has-addons-centered + justify-content: center + &.has-addons-right + justify-content: flex-end + &.has-addons-fullwidth + .control + flex-grow: 1 + flex-shrink: 0 + &.is-grouped + display: flex + justify-content: flex-start + & > .control + flex-shrink: 0 + &:not(:last-child) + margin-bottom: 0 + margin-right: 0.75rem + &.is-expanded + flex-grow: 1 + flex-shrink: 1 + &.is-grouped-centered + justify-content: center + &.is-grouped-right + justify-content: flex-end + &.is-grouped-multiline + flex-wrap: wrap + & > .control + &:last-child, + &:not(:last-child) + margin-bottom: 0.75rem + &:last-child + margin-bottom: -0.75rem + &:not(:last-child) + margin-bottom: 0 + &.is-horizontal + +tablet + display: flex + +.field-label + .label + font-size: inherit + +mobile + margin-bottom: 0.5rem + +tablet + flex-basis: 0 + flex-grow: 1 + flex-shrink: 0 + margin-right: 1.5rem + text-align: right + &.is-small + font-size: $size-small + padding-top: 0.375em + &.is-normal + padding-top: 0.375em + &.is-medium + font-size: $size-medium + padding-top: 0.375em + &.is-large + font-size: $size-large + padding-top: 0.375em + +.field-body + .field .field + margin-bottom: 0 + +tablet + display: flex + flex-basis: 0 + flex-grow: 5 + flex-shrink: 1 + .field + margin-bottom: 0 + & > .field + flex-shrink: 1 + &:not(.is-narrow) + flex-grow: 1 + &:not(:last-child) + margin-right: 0.75rem + +.control + box-sizing: border-box + clear: both + font-size: $size-normal + position: relative + text-align: left + // Modifiers + &.has-icons-left, + &.has-icons-right + .input, + .select + &:focus + & ~ .icon + color: $input-icon-active-color + &.is-small ~ .icon + font-size: $size-small + &.is-medium ~ .icon + font-size: $size-medium + &.is-large ~ .icon + font-size: $size-large + .icon + color: $input-icon-color + height: $input-height + pointer-events: none + position: absolute + top: 0 + width: $input-height + z-index: 4 + &.has-icons-left + .input, + .select select + padding-left: $input-height + .icon.is-left + left: 0 + &.has-icons-right + .input, + .select select + padding-right: $input-height + .icon.is-right + right: 0 + &.is-loading + &::after + @extend %loader + position: absolute !important + right: 0.625em + top: 0.625em + z-index: 4 + &.is-small:after + font-size: $size-small + &.is-medium:after + font-size: $size-medium + &.is-large:after + font-size: $size-large diff --git a/themes/helm/assets/sass/bulma/sass/grid/_all.sass b/themes/helm/assets/sass/bulma/sass/grid/_all.sass new file mode 100644 index 0000000000..e53070f6c3 --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/grid/_all.sass @@ -0,0 +1,4 @@ +@charset "utf-8" + +@import "columns.sass" +@import "tiles.sass" diff --git a/themes/helm/assets/sass/bulma/sass/grid/columns.sass b/themes/helm/assets/sass/bulma/sass/grid/columns.sass new file mode 100644 index 0000000000..34a8353313 --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/grid/columns.sass @@ -0,0 +1,504 @@ +$column-gap: 0.75rem !default + +.column + display: block + flex-basis: 0 + flex-grow: 1 + flex-shrink: 1 + padding: $column-gap + .columns.is-mobile > &.is-narrow + flex: none + .columns.is-mobile > &.is-full + flex: none + width: 100% + .columns.is-mobile > &.is-three-quarters + flex: none + width: 75% + .columns.is-mobile > &.is-two-thirds + flex: none + width: 66.6666% + .columns.is-mobile > &.is-half + flex: none + width: 50% + .columns.is-mobile > &.is-one-third + flex: none + width: 33.3333% + .columns.is-mobile > &.is-one-quarter + flex: none + width: 25% + .columns.is-mobile > &.is-one-fifth + flex: none + width: 20% + .columns.is-mobile > &.is-two-fifths + flex: none + width: 40% + .columns.is-mobile > &.is-three-fifths + flex: none + width: 60% + .columns.is-mobile > &.is-four-fifths + flex: none + width: 80% + .columns.is-mobile > &.is-offset-three-quarters + margin-left: 75% + .columns.is-mobile > &.is-offset-two-thirds + margin-left: 66.6666% + .columns.is-mobile > &.is-offset-half + margin-left: 50% + .columns.is-mobile > &.is-offset-one-third + margin-left: 33.3333% + .columns.is-mobile > &.is-offset-one-quarter + margin-left: 25% + .columns.is-mobile > &.is-offset-one-fifth + margin-left: 20% + .columns.is-mobile > &.is-offset-two-fifths + margin-left: 40% + .columns.is-mobile > &.is-offset-three-fifths + margin-left: 60% + .columns.is-mobile > &.is-offset-four-fifths + margin-left: 80% + @for $i from 0 through 12 + .columns.is-mobile > &.is-#{$i} + flex: none + width: percentage($i / 12) + .columns.is-mobile > &.is-offset-#{$i} + margin-left: percentage($i / 12) + +mobile + &.is-narrow-mobile + flex: none + &.is-full-mobile + flex: none + width: 100% + &.is-three-quarters-mobile + flex: none + width: 75% + &.is-two-thirds-mobile + flex: none + width: 66.6666% + &.is-half-mobile + flex: none + width: 50% + &.is-one-third-mobile + flex: none + width: 33.3333% + &.is-one-quarter-mobile + flex: none + width: 25% + &.is-one-fifth-mobile + flex: none + width: 20% + &.is-two-fifths-mobile + flex: none + width: 40% + &.is-three-fifths-mobile + flex: none + width: 60% + &.is-four-fifths-mobile + flex: none + width: 80% + &.is-offset-three-quarters-mobile + margin-left: 75% + &.is-offset-two-thirds-mobile + margin-left: 66.6666% + &.is-offset-half-mobile + margin-left: 50% + &.is-offset-one-third-mobile + margin-left: 33.3333% + &.is-offset-one-quarter-mobile + margin-left: 25% + &.is-offset-one-fifth-mobile + margin-left: 20% + &.is-offset-two-fifths-mobile + margin-left: 40% + &.is-offset-three-fifths-mobile + margin-left: 60% + &.is-offset-four-fifths-mobile + margin-left: 80% + @for $i from 0 through 12 + &.is-#{$i}-mobile + flex: none + width: percentage($i / 12) + &.is-offset-#{$i}-mobile + margin-left: percentage($i / 12) + +tablet + &.is-narrow, + &.is-narrow-tablet + flex: none + &.is-full, + &.is-full-tablet + flex: none + width: 100% + &.is-three-quarters, + &.is-three-quarters-tablet + flex: none + width: 75% + &.is-two-thirds, + &.is-two-thirds-tablet + flex: none + width: 66.6666% + &.is-half, + &.is-half-tablet + flex: none + width: 50% + &.is-one-third, + &.is-one-third-tablet + flex: none + width: 33.3333% + &.is-one-quarter, + &.is-one-quarter-tablet + flex: none + width: 25% + &.is-one-fifth, + &.is-one-fifth-tablet + flex: none + width: 20% + &.is-two-fifths, + &.is-two-fifths-tablet + flex: none + width: 40% + &.is-three-fifths, + &.is-three-fifths-tablet + flex: none + width: 60% + &.is-four-fifths, + &.is-four-fifths-tablet + flex: none + width: 80% + &.is-offset-three-quarters, + &.is-offset-three-quarters-tablet + margin-left: 75% + &.is-offset-two-thirds, + &.is-offset-two-thirds-tablet + margin-left: 66.6666% + &.is-offset-half, + &.is-offset-half-tablet + margin-left: 50% + &.is-offset-one-third, + &.is-offset-one-third-tablet + margin-left: 33.3333% + &.is-offset-one-quarter, + &.is-offset-one-quarter-tablet + margin-left: 25% + &.is-offset-one-fifth, + &.is-offset-one-fifth-tablet + margin-left: 20% + &.is-offset-two-fifths, + &.is-offset-two-fifths-tablet + margin-left: 40% + &.is-offset-three-fifths, + &.is-offset-three-fifths-tablet + margin-left: 60% + &.is-offset-four-fifths, + &.is-offset-four-fifths-tablet + margin-left: 80% + @for $i from 0 through 12 + &.is-#{$i}, + &.is-#{$i}-tablet + flex: none + width: percentage($i / 12) + &.is-offset-#{$i}, + &.is-offset-#{$i}-tablet + margin-left: percentage($i / 12) + +touch + &.is-narrow-touch + flex: none + &.is-full-touch + flex: none + width: 100% + &.is-three-quarters-touch + flex: none + width: 75% + &.is-two-thirds-touch + flex: none + width: 66.6666% + &.is-half-touch + flex: none + width: 50% + &.is-one-third-touch + flex: none + width: 33.3333% + &.is-one-quarter-touch + flex: none + width: 25% + &.is-one-fifth-touch + flex: none + width: 20% + &.is-two-fifths-touch + flex: none + width: 40% + &.is-three-fifths-touch + flex: none + width: 60% + &.is-four-fifths-touch + flex: none + width: 80% + &.is-offset-three-quarters-touch + margin-left: 75% + &.is-offset-two-thirds-touch + margin-left: 66.6666% + &.is-offset-half-touch + margin-left: 50% + &.is-offset-one-third-touch + margin-left: 33.3333% + &.is-offset-one-quarter-touch + margin-left: 25% + &.is-offset-one-fifth-touch + margin-left: 20% + &.is-offset-two-fifths-touch + margin-left: 40% + &.is-offset-three-fifths-touch + margin-left: 60% + &.is-offset-four-fifths-touch + margin-left: 80% + @for $i from 0 through 12 + &.is-#{$i}-touch + flex: none + width: percentage($i / 12) + &.is-offset-#{$i}-touch + margin-left: percentage($i / 12) + +desktop + &.is-narrow-desktop + flex: none + &.is-full-desktop + flex: none + width: 100% + &.is-three-quarters-desktop + flex: none + width: 75% + &.is-two-thirds-desktop + flex: none + width: 66.6666% + &.is-half-desktop + flex: none + width: 50% + &.is-one-third-desktop + flex: none + width: 33.3333% + &.is-one-quarter-desktop + flex: none + width: 25% + &.is-one-fifth-desktop + flex: none + width: 20% + &.is-two-fifths-desktop + flex: none + width: 40% + &.is-three-fifths-desktop + flex: none + width: 60% + &.is-four-fifths-desktop + flex: none + width: 80% + &.is-offset-three-quarters-desktop + margin-left: 75% + &.is-offset-two-thirds-desktop + margin-left: 66.6666% + &.is-offset-half-desktop + margin-left: 50% + &.is-offset-one-third-desktop + margin-left: 33.3333% + &.is-offset-one-quarter-desktop + margin-left: 25% + &.is-offset-one-fifth-desktop + margin-left: 20% + &.is-offset-two-fifths-desktop + margin-left: 40% + &.is-offset-three-fifths-desktop + margin-left: 60% + &.is-offset-four-fifths-desktop + margin-left: 80% + @for $i from 0 through 12 + &.is-#{$i}-desktop + flex: none + width: percentage($i / 12) + &.is-offset-#{$i}-desktop + margin-left: percentage($i / 12) + +widescreen + &.is-narrow-widescreen + flex: none + &.is-full-widescreen + flex: none + width: 100% + &.is-three-quarters-widescreen + flex: none + width: 75% + &.is-two-thirds-widescreen + flex: none + width: 66.6666% + &.is-half-widescreen + flex: none + width: 50% + &.is-one-third-widescreen + flex: none + width: 33.3333% + &.is-one-quarter-widescreen + flex: none + width: 25% + &.is-one-fifth-widescreen + flex: none + width: 20% + &.is-two-fifths-widescreen + flex: none + width: 40% + &.is-three-fifths-widescreen + flex: none + width: 60% + &.is-four-fifths-widescreen + flex: none + width: 80% + &.is-offset-three-quarters-widescreen + margin-left: 75% + &.is-offset-two-thirds-widescreen + margin-left: 66.6666% + &.is-offset-half-widescreen + margin-left: 50% + &.is-offset-one-third-widescreen + margin-left: 33.3333% + &.is-offset-one-quarter-widescreen + margin-left: 25% + &.is-offset-one-fifth-widescreen + margin-left: 20% + &.is-offset-two-fifths-widescreen + margin-left: 40% + &.is-offset-three-fifths-widescreen + margin-left: 60% + &.is-offset-four-fifths-widescreen + margin-left: 80% + @for $i from 0 through 12 + &.is-#{$i}-widescreen + flex: none + width: percentage($i / 12) + &.is-offset-#{$i}-widescreen + margin-left: percentage($i / 12) + +fullhd + &.is-narrow-fullhd + flex: none + &.is-full-fullhd + flex: none + width: 100% + &.is-three-quarters-fullhd + flex: none + width: 75% + &.is-two-thirds-fullhd + flex: none + width: 66.6666% + &.is-half-fullhd + flex: none + width: 50% + &.is-one-third-fullhd + flex: none + width: 33.3333% + &.is-one-quarter-fullhd + flex: none + width: 25% + &.is-one-fifth-fullhd + flex: none + width: 20% + &.is-two-fifths-fullhd + flex: none + width: 40% + &.is-three-fifths-fullhd + flex: none + width: 60% + &.is-four-fifths-fullhd + flex: none + width: 80% + &.is-offset-three-quarters-fullhd + margin-left: 75% + &.is-offset-two-thirds-fullhd + margin-left: 66.6666% + &.is-offset-half-fullhd + margin-left: 50% + &.is-offset-one-third-fullhd + margin-left: 33.3333% + &.is-offset-one-quarter-fullhd + margin-left: 25% + &.is-offset-one-fifth-fullhd + margin-left: 20% + &.is-offset-two-fifths-fullhd + margin-left: 40% + &.is-offset-three-fifths-fullhd + margin-left: 60% + &.is-offset-four-fifths-fullhd + margin-left: 80% + @for $i from 0 through 12 + &.is-#{$i}-fullhd + flex: none + width: percentage($i / 12) + &.is-offset-#{$i}-fullhd + margin-left: percentage($i / 12) + +.columns + margin-left: (-$column-gap) + margin-right: (-$column-gap) + margin-top: (-$column-gap) + &:last-child + margin-bottom: (-$column-gap) + &:not(:last-child) + margin-bottom: calc(1.5rem - #{$column-gap}) + // Modifiers + &.is-centered + justify-content: center + &.is-gapless + margin-left: 0 + margin-right: 0 + margin-top: 0 + & > .column + margin: 0 + padding: 0 !important + &:not(:last-child) + margin-bottom: 1.5rem + &:last-child + margin-bottom: 0 + &.is-mobile + display: flex + &.is-multiline + flex-wrap: wrap + &.is-vcentered + align-items: center + // Responsiveness + +tablet + &:not(.is-desktop) + display: flex + +desktop + // Modifiers + &.is-desktop + display: flex + +@if $variable-columns + .columns.is-variable + --columnGap: 0.75rem + margin-left: calc(-1 * var(--columnGap)) + margin-right: calc(-1 * var(--columnGap)) + .column + padding-left: var(--columnGap) + padding-right: var(--columnGap) + @for $i from 0 through 8 + &.is-#{$i} + --columnGap: #{$i * 0.25rem} + +mobile + &.is-#{$i}-mobile + --columnGap: #{$i * 0.25rem} + +tablet + &.is-#{$i}-tablet + --columnGap: #{$i * 0.25rem} + +tablet-only + &.is-#{$i}-tablet-only + --columnGap: #{$i * 0.25rem} + +touch + &.is-#{$i}-touch + --columnGap: #{$i * 0.25rem} + +desktop + &.is-#{$i}-desktop + --columnGap: #{$i * 0.25rem} + +desktop-only + &.is-#{$i}-desktop-only + --columnGap: #{$i * 0.25rem} + +widescreen + &.is-#{$i}-widescreen + --columnGap: #{$i * 0.25rem} + +widescreen-only + &.is-#{$i}-widescreen-only + --columnGap: #{$i * 0.25rem} + +fullhd + &.is-#{$i}-fullhd + --columnGap: #{$i * 0.25rem} diff --git a/themes/helm/assets/sass/bulma/sass/grid/tiles.sass b/themes/helm/assets/sass/bulma/sass/grid/tiles.sass new file mode 100644 index 0000000000..15648c2981 --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/grid/tiles.sass @@ -0,0 +1,34 @@ +$tile-spacing: 0.75rem !default + +.tile + align-items: stretch + display: block + flex-basis: 0 + flex-grow: 1 + flex-shrink: 1 + min-height: min-content + // Modifiers + &.is-ancestor + margin-left: $tile-spacing * -1 + margin-right: $tile-spacing * -1 + margin-top: $tile-spacing * -1 + &:last-child + margin-bottom: $tile-spacing * -1 + &:not(:last-child) + margin-bottom: $tile-spacing + &.is-child + margin: 0 !important + &.is-parent + padding: $tile-spacing + &.is-vertical + flex-direction: column + & > .tile.is-child:not(:last-child) + margin-bottom: 1.5rem !important + // Responsiveness + +tablet + &:not(.is-child) + display: flex + @for $i from 1 through 12 + &.is-#{$i} + flex: none + width: ($i / 12) * 100% diff --git a/themes/helm/assets/sass/bulma/sass/layout/_all.sass b/themes/helm/assets/sass/bulma/sass/layout/_all.sass new file mode 100644 index 0000000000..143ada35be --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/layout/_all.sass @@ -0,0 +1,5 @@ +@charset "utf-8" + +@import "hero.sass" +@import "section.sass" +@import "footer.sass" diff --git a/themes/helm/assets/sass/bulma/sass/layout/footer.sass b/themes/helm/assets/sass/bulma/sass/layout/footer.sass new file mode 100644 index 0000000000..8faa11ed09 --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/layout/footer.sass @@ -0,0 +1,9 @@ +$footer-background-color: $scheme-main-bis !default +$footer-color: false !default +$footer-padding: 3rem 1.5rem 6rem !default + +.footer + background-color: $footer-background-color + padding: $footer-padding + @if $footer-color + color: $footer-color diff --git a/themes/helm/assets/sass/bulma/sass/layout/hero.sass b/themes/helm/assets/sass/bulma/sass/layout/hero.sass new file mode 100644 index 0000000000..9b18e4f938 --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/layout/hero.sass @@ -0,0 +1,143 @@ +// Main container + +.hero + align-items: stretch + display: flex + flex-direction: column + justify-content: space-between + .navbar + background: none + .tabs + ul + border-bottom: none + // Colors + @each $name, $pair in $colors + $color: nth($pair, 1) + $color-invert: nth($pair, 2) + &.is-#{$name} + background-color: $color + color: $color-invert + a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current), + strong + color: inherit + .title + color: $color-invert + .subtitle + color: rgba($color-invert, 0.9) + a:not(.button), + strong + color: $color-invert + .navbar-menu + +touch + background-color: $color + .navbar-item, + .navbar-link + color: rgba($color-invert, 0.7) + a.navbar-item, + .navbar-link + &:hover, + &.is-active + background-color: darken($color, 5%) + color: $color-invert + .tabs + a + color: $color-invert + opacity: 0.9 + &:hover + opacity: 1 + li + &.is-active a + opacity: 1 + &.is-boxed, + &.is-toggle + a + color: $color-invert + &:hover + background-color: rgba($scheme-invert, 0.1) + li.is-active a + &, + &:hover + background-color: $color-invert + border-color: $color-invert + color: $color + // Modifiers + &.is-bold + $gradient-top-left: darken(saturate(adjust-hue($color, -10deg), 10%), 10%) + $gradient-bottom-right: lighten(saturate(adjust-hue($color, 10deg), 5%), 5%) + background-image: linear-gradient(141deg, $gradient-top-left 0%, $color 71%, $gradient-bottom-right 100%) + +mobile + .navbar-menu + background-image: linear-gradient(141deg, $gradient-top-left 0%, $color 71%, $gradient-bottom-right 100%) + // Sizes + &.is-small + .hero-body + padding-bottom: 1.5rem + padding-top: 1.5rem + &.is-medium + +tablet + .hero-body + padding-bottom: 9rem + padding-top: 9rem + &.is-large + +tablet + .hero-body + padding-bottom: 18rem + padding-top: 18rem + &.is-halfheight, + &.is-fullheight, + &.is-fullheight-with-navbar + .hero-body + align-items: center + display: flex + & > .container + flex-grow: 1 + flex-shrink: 1 + &.is-halfheight + min-height: 50vh + &.is-fullheight + min-height: 100vh + +// Components + +.hero-video + @extend %overlay + overflow: hidden + video + left: 50% + min-height: 100% + min-width: 100% + position: absolute + top: 50% + transform: translate3d(-50%, -50%, 0) + // Modifiers + &.is-transparent + opacity: 0.3 + // Responsiveness + +mobile + display: none + +.hero-buttons + margin-top: 1.5rem + // Responsiveness + +mobile + .button + display: flex + &:not(:last-child) + margin-bottom: 0.75rem + +tablet + display: flex + justify-content: center + .button:not(:last-child) + margin-right: 1.5rem + +// Containers + +.hero-head, +.hero-foot + flex-grow: 0 + flex-shrink: 0 + +.hero-body + flex-grow: 1 + flex-shrink: 0 + padding: 3rem 1.5rem diff --git a/themes/helm/assets/sass/bulma/sass/layout/section.sass b/themes/helm/assets/sass/bulma/sass/layout/section.sass new file mode 100644 index 0000000000..6f2d35231f --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/layout/section.sass @@ -0,0 +1,13 @@ +$section-padding: 3rem 1.5rem !default +$section-padding-medium: 9rem 1.5rem !default +$section-padding-large: 18rem 1.5rem !default + +.section + padding: $section-padding + // Responsiveness + +desktop + // Sizes + &.is-medium + padding: $section-padding-medium + &.is-large + padding: $section-padding-large diff --git a/themes/helm/assets/sass/bulma/sass/utilities/_all.sass b/themes/helm/assets/sass/bulma/sass/utilities/_all.sass new file mode 100644 index 0000000000..bf4ecfe358 --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/utilities/_all.sass @@ -0,0 +1,8 @@ +@charset "utf-8" + +@import "initial-variables.sass" +@import "functions.sass" +@import "derived-variables.sass" +@import "animations.sass" +@import "mixins.sass" +@import "controls.sass" diff --git a/themes/helm/assets/sass/bulma/sass/utilities/animations.sass b/themes/helm/assets/sass/bulma/sass/utilities/animations.sass new file mode 100644 index 0000000000..a14525d75e --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/utilities/animations.sass @@ -0,0 +1,5 @@ +@keyframes spinAround + from + transform: rotate(0deg) + to + transform: rotate(359deg) diff --git a/themes/helm/assets/sass/bulma/sass/utilities/controls.sass b/themes/helm/assets/sass/bulma/sass/utilities/controls.sass new file mode 100644 index 0000000000..cc7672a198 --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/utilities/controls.sass @@ -0,0 +1,50 @@ +$control-radius: $radius !default +$control-radius-small: $radius-small !default + +$control-border-width: 1px !default + +$control-height: 2.5em !default +$control-line-height: 1.5 !default + +$control-padding-vertical: calc(0.5em - #{$control-border-width}) !default +$control-padding-horizontal: calc(0.75em - #{$control-border-width}) !default + +=control + -moz-appearance: none + -webkit-appearance: none + align-items: center + border: $control-border-width solid transparent + border-radius: $control-radius + box-shadow: none + display: inline-flex + font-size: $size-normal + height: $control-height + justify-content: flex-start + line-height: $control-line-height + padding-bottom: $control-padding-vertical + padding-left: $control-padding-horizontal + padding-right: $control-padding-horizontal + padding-top: $control-padding-vertical + position: relative + vertical-align: top + // States + &:focus, + &.is-focused, + &:active, + &.is-active + outline: none + &[disabled], + fieldset[disabled] & + cursor: not-allowed + +%control + +control + +// The controls sizes use mixins so they can be used at different breakpoints +=control-small + border-radius: $control-radius-small + font-size: $size-small +=control-medium + font-size: $size-medium +=control-large + font-size: $size-large diff --git a/themes/helm/assets/sass/bulma/sass/utilities/derived-variables.sass b/themes/helm/assets/sass/bulma/sass/utilities/derived-variables.sass new file mode 100644 index 0000000000..18a7f46125 --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/utilities/derived-variables.sass @@ -0,0 +1,106 @@ +$primary: $turquoise !default + +$info: $cyan !default +$success: $green !default +$warning: $yellow !default +$danger: $red !default + +$light: $white-ter !default +$dark: $grey-darker !default + +// Invert colors + +$orange-invert: findColorInvert($orange) !default +$yellow-invert: findColorInvert($yellow) !default +$green-invert: findColorInvert($green) !default +$turquoise-invert: findColorInvert($turquoise) !default +$cyan-invert: findColorInvert($cyan) !default +$blue-invert: findColorInvert($blue) !default +$purple-invert: findColorInvert($purple) !default +$red-invert: findColorInvert($red) !default + +$primary-invert: findColorInvert($primary) !default +$primary-light: findLightColor($primary) !default +$primary-dark: findDarkColor($primary) !default +$info-invert: findColorInvert($info) !default +$info-light: findLightColor($info) !default +$info-dark: findDarkColor($info) !default +$success-invert: findColorInvert($success) !default +$success-light: findLightColor($success) !default +$success-dark: findDarkColor($success) !default +$warning-invert: findColorInvert($warning) !default +$warning-light: findLightColor($warning) !default +$warning-dark: findDarkColor($warning) !default +$danger-invert: findColorInvert($danger) !default +$danger-light: findLightColor($danger) !default +$danger-dark: findDarkColor($danger) !default +$light-invert: findColorInvert($light) !default +$dark-invert: findColorInvert($dark) !default + +// General colors + +$scheme-main: $white !default +$scheme-main-bis: $white-bis !default +$scheme-main-ter: $white-ter !default +$scheme-invert: $black !default +$scheme-invert-bis: $black-bis !default +$scheme-invert-ter: $black-ter !default + +$background: $white-ter !default + +$border: $grey-lighter !default +$border-hover: $grey-light !default +$border-light: $grey-lightest !default +$border-light-hover: $grey-light !default + +// Text colors + +$text: $grey-dark !default +$text-invert: findColorInvert($text) !default +$text-light: $grey !default +$text-strong: $grey-darker !default + +// Code colors + +$code: $red !default +$code-background: $background !default + +$pre: $text !default +$pre-background: $background !default + +// Link colors + +$link: $blue !default +$link-invert: findColorInvert($link) !default +$link-light: findLightColor($link) !default +$link-dark: findDarkColor($link) !default +$link-visited: $purple !default + +$link-hover: $grey-darker !default +$link-hover-border: $grey-light !default + +$link-focus: $grey-darker !default +$link-focus-border: $blue !default + +$link-active: $grey-darker !default +$link-active-border: $grey-dark !default + +// Typography + +$family-primary: $family-sans-serif !default +$family-secondary: $family-sans-serif !default +$family-code: $family-monospace !default + +$size-small: $size-7 !default +$size-normal: $size-6 !default +$size-medium: $size-5 !default +$size-large: $size-4 !default + +// Lists and maps +$custom-colors: null !default +$custom-shades: null !default + +$colors: mergeColorMaps(("white": ($white, $black), "black": ($black, $white), "light": ($light, $light-invert), "dark": ($dark, $dark-invert), "primary": ($primary, $primary-invert, $primary-light, $primary-dark), "link": ($link, $link-invert, $link-light, $link-dark), "info": ($info, $info-invert, $info-light, $info-dark), "success": ($success, $success-invert, $success-light, $success-dark), "warning": ($warning, $warning-invert, $warning-light, $warning-dark), "danger": ($danger, $danger-invert, $danger-light, $danger-dark)), $custom-colors) !default +$shades: mergeColorMaps(("black-bis": $black-bis, "black-ter": $black-ter, "grey-darker": $grey-darker, "grey-dark": $grey-dark, "grey": $grey, "grey-light": $grey-light, "grey-lighter": $grey-lighter, "white-ter": $white-ter, "white-bis": $white-bis), $custom-shades) !default + +$sizes: $size-1 $size-2 $size-3 $size-4 $size-5 $size-6 $size-7 !default diff --git a/themes/helm/assets/sass/bulma/sass/utilities/functions.sass b/themes/helm/assets/sass/bulma/sass/utilities/functions.sass new file mode 100644 index 0000000000..481ab953b2 --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/utilities/functions.sass @@ -0,0 +1,98 @@ +@function mergeColorMaps($bulma-colors, $custom-colors) + // We return at least Bulma's hard-coded colors + $merged-colors: $bulma-colors + + // We want a map as input + @if type-of($custom-colors) == 'map' + @each $name, $components in $custom-colors + // The color name should be a string + // and the components either a single color + // or a colors list with at least one element + @if type-of($name) == 'string' and (type-of($components) == 'list' or type-of($components) == 'color') and length($components) >= 1 + $color-base: null + $color-invert: null + $color-light: null + $color-dark: null + $value: null + + // The param can either be a single color + // or a list of 2 colors + @if type-of($components) == 'color' + $color-base: $components + $color-invert: findColorInvert($color-base) + $color-light: findLightColor($color-base) + $color-dark: findDarkColor($color-base) + @else if type-of($components) == 'list' + $color-base: nth($components, 1) + // If Invert, Light and Dark are provided + @if length($components) > 3 + $color-invert: nth($components, 2) + $color-light: nth($components, 3) + $color-dark: nth($components, 4) + // If only Invert and Light are provided + @else if length($components) > 2 + $color-invert: nth($components, 2) + $color-light: nth($components, 3) + $color-dark: findDarkColor($color-base) + // If only Invert is provided + @else + $color-invert: nth($components, 2) + $color-light: findLightColor($color-base) + $color-dark: findDarkColor($color-base) + + $value: ($color-base, $color-invert, $color-light, $color-dark) + + // We only want to merge the map if the color base is an actual color + @if type-of($color-base) == 'color' + // We merge this colors elements as map with Bulma's colors map + // (we can override them this way, no multiple definition for the same name) + // $merged-colors: map_merge($merged-colors, ($name: ($color-base, $color-invert, $color-light, $color-dark))) + $merged-colors: map_merge($merged-colors, ($name: $value)) + + @return $merged-colors + +@function powerNumber($number, $exp) + $value: 1 + @if $exp > 0 + @for $i from 1 through $exp + $value: $value * $number + @else if $exp < 0 + @for $i from 1 through -$exp + $value: $value / $number + @return $value + +@function colorLuminance($color) + $color-rgb: ('red': red($color),'green': green($color),'blue': blue($color)) + @each $name, $value in $color-rgb + $adjusted: 0 + $value: $value / 255 + @if $value < 0.03928 + $value: $value / 12.92 + @else + $value: ($value + .055) / 1.055 + $value: powerNumber($value, 2) + $color-rgb: map-merge($color-rgb, ($name: $value)) + @return (map-get($color-rgb, 'red') * .2126) + (map-get($color-rgb, 'green') * .7152) + (map-get($color-rgb, 'blue') * .0722) + +@function findColorInvert($color) + @if (colorLuminance($color) > 0.55) + @return rgba(#000, 0.7) + @else + @return #fff + +@function findLightColor($color) + @if type-of($color) == 'color' + $l: 96% + @if lightness($color) > 96% + $l: lightness($color) + @return change-color($color, $lightness: $l) + @return $background + +@function findDarkColor($color) + @if type-of($color) == 'color' + $base-l: 29% + $luminance: colorLuminance($color) + $luminance-delta: (0.53 - $luminance) + $target-l: round($base-l + ($luminance-delta * 53)) + @return change-color($color, $lightness: max($base-l, $target-l)) + @return $text-strong diff --git a/themes/helm/assets/sass/bulma/sass/utilities/initial-variables.sass b/themes/helm/assets/sass/bulma/sass/utilities/initial-variables.sass new file mode 100644 index 0000000000..03bbc128c7 --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/utilities/initial-variables.sass @@ -0,0 +1,77 @@ +// Colors + +$black: hsl(0, 0%, 4%) !default +$black-bis: hsl(0, 0%, 7%) !default +$black-ter: hsl(0, 0%, 14%) !default + +$grey-darker: hsl(0, 0%, 21%) !default +$grey-dark: hsl(0, 0%, 29%) !default +$grey: hsl(0, 0%, 48%) !default +$grey-light: hsl(0, 0%, 71%) !default +$grey-lighter: hsl(0, 0%, 86%) !default +$grey-lightest: hsl(0, 0%, 93%) !default + +$white-ter: hsl(0, 0%, 96%) !default +$white-bis: hsl(0, 0%, 98%) !default +$white: hsl(0, 0%, 100%) !default + +$orange: hsl(14, 100%, 53%) !default +$yellow: hsl(48, 100%, 67%) !default +$green: hsl(141, 53%, 53%) !default +$turquoise: hsl(171, 100%, 41%) !default +$cyan: hsl(204, 71%, 53%) !default +$blue: hsl(217, 71%, 53%) !default +$purple: hsl(271, 100%, 71%) !default +$red: hsl(348, 86%, 61%) !default + +// Typography + +$family-sans-serif: BlinkMacSystemFont, -apple-system, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", "Helvetica", "Arial", sans-serif !default +$family-monospace: monospace !default +$render-mode: optimizeLegibility !default + +$size-1: 3rem !default +$size-2: 2.5rem !default +$size-3: 2rem !default +$size-4: 1.5rem !default +$size-5: 1.25rem !default +$size-6: 1rem !default +$size-7: 0.75rem !default + +$weight-light: 300 !default +$weight-normal: 400 !default +$weight-medium: 500 !default +$weight-semibold: 600 !default +$weight-bold: 700 !default + +// Spacing + +$block-spacing: 1.5rem !default + +// Responsiveness + +// The container horizontal gap, which acts as the offset for breakpoints +$gap: 32px !default +// 960, 1152, and 1344 have been chosen because they are divisible by both 12 and 16 +$tablet: 769px !default +// 960px container + 4rem +$desktop: 960px + (2 * $gap) !default +// 1152px container + 4rem +$widescreen: 1152px + (2 * $gap) !default +$widescreen-enabled: true !default +// 1344px container + 4rem +$fullhd: 1344px + (2 * $gap) !default +$fullhd-enabled: true !default + +// Miscellaneous + +$easing: ease-out !default +$radius-small: 2px !default +$radius: 4px !default +$radius-large: 6px !default +$radius-rounded: 290486px !default +$speed: 86ms !default + +// Flags + +$variable-columns: true !default diff --git a/themes/helm/assets/sass/bulma/sass/utilities/mixins.sass b/themes/helm/assets/sass/bulma/sass/utilities/mixins.sass new file mode 100644 index 0000000000..4ef2985be9 --- /dev/null +++ b/themes/helm/assets/sass/bulma/sass/utilities/mixins.sass @@ -0,0 +1,261 @@ +@import "initial-variables" + +=clearfix + &::after + clear: both + content: " " + display: table + +=center($width, $height: 0) + position: absolute + @if $height != 0 + left: calc(50% - (#{$width} / 2)) + top: calc(50% - (#{$height} / 2)) + @else + left: calc(50% - (#{$width} / 2)) + top: calc(50% - (#{$width} / 2)) + +=fa($size, $dimensions) + display: inline-block + font-size: $size + height: $dimensions + line-height: $dimensions + text-align: center + vertical-align: top + width: $dimensions + +=hamburger($dimensions) + cursor: pointer + display: block + height: $dimensions + position: relative + width: $dimensions + span + background-color: currentColor + display: block + height: 1px + left: calc(50% - 8px) + position: absolute + transform-origin: center + transition-duration: $speed + transition-property: background-color, opacity, transform + transition-timing-function: $easing + width: 16px + &:nth-child(1) + top: calc(50% - 6px) + &:nth-child(2) + top: calc(50% - 1px) + &:nth-child(3) + top: calc(50% + 4px) + &:hover + background-color: rgba(black, 0.05) + // Modifers + &.is-active + span + &:nth-child(1) + transform: translateY(5px) rotate(45deg) + &:nth-child(2) + opacity: 0 + &:nth-child(3) + transform: translateY(-5px) rotate(-45deg) + +=overflow-touch + -webkit-overflow-scrolling: touch + +=placeholder + $placeholders: ':-moz' ':-webkit-input' '-moz' '-ms-input' + @each $placeholder in $placeholders + &:#{$placeholder}-placeholder + @content + +// Responsiveness + +=from($device) + @media screen and (min-width: $device) + @content + +=until($device) + @media screen and (max-width: $device - 1px) + @content + +=mobile + @media screen and (max-width: $tablet - 1px) + @content + +=tablet + @media screen and (min-width: $tablet), print + @content + +=tablet-only + @media screen and (min-width: $tablet) and (max-width: $desktop - 1px) + @content + +=touch + @media screen and (max-width: $desktop - 1px) + @content + +=desktop + @media screen and (min-width: $desktop) + @content + +=desktop-only + @if $widescreen-enabled + @media screen and (min-width: $desktop) and (max-width: $widescreen - 1px) + @content + +=until-widescreen + @if $widescreen-enabled + @media screen and (max-width: $widescreen - 1px) + @content + +=widescreen + @if $widescreen-enabled + @media screen and (min-width: $widescreen) + @content + +=widescreen-only + @if $widescreen-enabled and $fullhd-enabled + @media screen and (min-width: $widescreen) and (max-width: $fullhd - 1px) + @content + +=until-fullhd + @if $fullhd-enabled + @media screen and (max-width: $fullhd - 1px) + @content + +=fullhd + @if $fullhd-enabled + @media screen and (min-width: $fullhd) + @content + +// Placeholders + +=unselectable + -webkit-touch-callout: none + -webkit-user-select: none + -moz-user-select: none + -ms-user-select: none + user-select: none + +%unselectable + +unselectable + +=arrow($color: transparent) + border: 3px solid $color + border-radius: 2px + border-right: 0 + border-top: 0 + content: " " + display: block + height: 0.625em + margin-top: -0.4375em + pointer-events: none + position: absolute + top: 50% + transform: rotate(-45deg) + transform-origin: center + width: 0.625em + +%arrow + +arrow + +=block($spacing: $block-spacing) + &:not(:last-child) + margin-bottom: $spacing + +%block + +block + +=delete + @extend %unselectable + -moz-appearance: none + -webkit-appearance: none + background-color: rgba($scheme-invert, 0.2) + border: none + border-radius: $radius-rounded + cursor: pointer + pointer-events: auto + display: inline-block + flex-grow: 0 + flex-shrink: 0 + font-size: 0 + height: 20px + max-height: 20px + max-width: 20px + min-height: 20px + min-width: 20px + outline: none + position: relative + vertical-align: top + width: 20px + &::before, + &::after + background-color: $scheme-main + content: "" + display: block + left: 50% + position: absolute + top: 50% + transform: translateX(-50%) translateY(-50%) rotate(45deg) + transform-origin: center center + &::before + height: 2px + width: 50% + &::after + height: 50% + width: 2px + &:hover, + &:focus + background-color: rgba($scheme-invert, 0.3) + &:active + background-color: rgba($scheme-invert, 0.4) + // Sizes + &.is-small + height: 16px + max-height: 16px + max-width: 16px + min-height: 16px + min-width: 16px + width: 16px + &.is-medium + height: 24px + max-height: 24px + max-width: 24px + min-height: 24px + min-width: 24px + width: 24px + &.is-large + height: 32px + max-height: 32px + max-width: 32px + min-height: 32px + min-width: 32px + width: 32px + +%delete + +delete + +=loader + animation: spinAround 500ms infinite linear + border: 2px solid $grey-lighter + border-radius: $radius-rounded + border-right-color: transparent + border-top-color: transparent + content: "" + display: block + height: 1em + position: relative + width: 1em + +%loader + +loader + +=overlay($offset: 0) + bottom: $offset + left: $offset + position: absolute + right: $offset + top: $offset + +%overlay + +overlay diff --git a/themes/helm/assets/sass/docs-404.scss b/themes/helm/assets/sass/docs-404.scss new file mode 100755 index 0000000000..fc58c89553 --- /dev/null +++ b/themes/helm/assets/sass/docs-404.scss @@ -0,0 +1,17 @@ +.section-404 { + position: relative; + min-height: 670px; + + #particles-js { + position: absolute; + width: 100%; + } + + h1 { + text-transform: none; + font-size: $scalex8; + letter-spacing: 0.05em; + margin: 5em 7.5% 2.5em; + position: relative; + } +} diff --git a/themes/helm/assets/sass/docs-content.scss b/themes/helm/assets/sass/docs-content.scss new file mode 100755 index 0000000000..892b5886e0 --- /dev/null +++ b/themes/helm/assets/sass/docs-content.scss @@ -0,0 +1,419 @@ +.content-wrapper { + padding-top: 1em; + padding-bottom: 10em; + font-size: $scalex5; + font-weight: normal; + line-height: 1.5; + z-index: 500; + position: relative; + @include klinicReg; + + h1 { + margin-top: 1em; + padding-top: 2.5em; + padding-bottom: 1.5rem; + } + + article { + padding: 2em 0 0; + overflow:auto; + + h1 { + font-size: $scalex8; + color: $navy; + margin: 1em 0 1em; + padding-top: 4.5em; + } + } + + h2 { + color: $navyl; + font-size: $scalex7; + @include klinicBold; + letter-spacing: -0.0335rem; + margin: 0 0 0.875em; + padding-top: 2.5em; + } + + h3 { + color: $grey4; + @include klinicBold; + margin: 3em 0 1.825em; + letter-spacing: -0.025rem; + + pre, + code { + padding: 0 0.2em; + background: lighten($light2, 1%); + font-weight: bold; + font-size: 1.35rem; + + } + } + + h4 { + font-size: $scalex5; + } + + h1, h2, h3, h4, p, ul, ol, blockquote { + max-width: 75rem; + } + + // show anchors on hover over titles, for deep linking (w/ app.js) + a.header-link { + position: absolute; + left: 0; + opacity: 0; + font-size: 1.25rem; + padding-top: 0.333em; + background-color: transparent; + @include transition(all, 0.3s, ease-in-out); + } + + h1:hover, + h2:hover, + h3:hover, + h4:hover, + h5:hover, + h6:hover { + + .header-link { + opacity: 1; + left: -1.25em; + border-bottom: none; + background-color: transparent; + } + } + + p { + color: $grey4; + margin: 0.825rem 0 1.667rem; + font-size: $scalex5; + + &.lead { + font-size: $scalex4; + } + + &:first-child { + font-size: $scalex6; + color: $grey4; + line-height: 1.575; + margin-bottom: 1.925rem; + padding-right: 7.5%; + } + + a { + padding-left: 0.35em; + padding-right: 0.35em; + } + } + + .prev-next { + border-top: 2px solid lighten($navyl, 33.33%); + padding: 1.5rem 0 0; + margin-top: 5rem; + + a { + display: inline-block; + min-width: 66.67%; + padding: 1rem 0.5rem; + } + } + + blockquote { + margin: 2rem 0 2.5rem 4.5vw; + background-color: rgba(249, 158, 172, 0.125); + + p, + p:first-child { + display: inline-block; + padding: 1.25rem 1.5rem; + margin: 0 2vw 0 0; + line-height: 1.85; + font-size: 1.1rem; + color: $navyd; + font-family: $mono; + + a { + background-color: rgba(249, 158, 172, 0.25); + } + } + } + + .quick-links { + padding-top: 5rem; + + h3 { + color: $blue; + + &:hover { + color: $blue; + } + } + + .quick-item { + position: relative; + display: block; + clear: both; + padding: 1rem 1rem 1.5rem; + background: transparent; + + &:hover { + color: $blue4; + border-bottom: none; + } + + &:after { + height: 2px; + background: desaturate(lighten($blue1, 35%), 20%); + width: 100%; + display: block; + content: " "; + position: absolute; + top: 1px; + } + + h4 { + display: inline-block; + float: left; + clear: both; + color: $blue4; + font-size: 1.125em; + width: 30%; + } + p { + display: inline-block; + float: right; + text-align: left; + width: 58%; + + } + } + } + + .helm-commands > .quick-item h4 { + width: auto; + } + + code { + background-color: lighten($light1, 2.5%); + color: black; + } + + .code-box { + margin: 0px; + width: 100%; + height: 220px; + overflow: auto; + } + + &.markdown pre, + pre { + border: none; + padding: 1em 1em; + margin: 0.25em 0 2.5em; + font-size: 1rem; + line-height: 1.636; + border-left: 2px solid $code; + border-radius: 0.4vw; + + code { + padding: 0; + background: transparent; + font-size: 1rem; + } + } + + strong { + letter-spacing: 0.0125em; + } + + code { + padding: 0.5em 0.5em; + border: none; + font-size: 1.1rem; + } + + &.markdown ul, + &.markdown ol, + ul, + ol { + padding: 0 0.25rem; + margin-bottom: 2em; + color: $grey4; + font-size: $scalex4; + line-height: 1.7; + + li { + font-size: 1.125em; + + a { + padding-left: 0.35em; + padding-right: 0.35em; + } + } + } + + ul { + list-style: disc; + color: $navy; + font-size: $scalex5; + + li { + padding-bottom: 0.25em; + color: $grey4; + line-height: 1.85; + font-size: $scalex5; + } + + li::before { + // content: "\2022"; + // color: $navy; + // padding-bottom: 0.5em; + } + } + + table { + margin: 2.5rem 0; + padding: 0; + border: none; + width: 100%; + + th, + td { + border: none; + vertical-align: top; + text-align: left; + padding: 0.5em 0.2em 1.25em 0; + width: auto; + } + + td { + color: $grey4; + font-size: $scalex4; + + code { + font-size: 1em; + background: transparent; + letter-spacing: -0.025em; + } + } + } + + a { + color: $navyd; + background: lighten($blue, 40%); + @include transition; + + &:hover { + color: darken($navyd, 5%); + border-bottom: 2px solid $navyd; + background: lighten($salmon, 15%); + } + } + + .quick-links { + padding-top: 5rem; + + h3 { + color: $blue; + text-align: center; + } + .quick-item { + position: relative; + display: inline-block; + width: 100%; + clear: both; + padding: 1rem 1rem 1.5rem; + background: transparent; + + &:hover { + color: $blue4; + border-bottom: none; + } + + &:after { + height: 2px; + background: desaturate(lighten($blue1, 35%), 20%); + width: 100%; + display: block; + content: " "; + position: absolute; + top: 1px; + } + + h4 { + display: inline-block; + float: left; + clear: both; + color: $blue4; + font-size: 1.125em; + width: 30%; + } + p { + display: inline-block; + float: right; + text-align: left; + width: 58%; + } + } + } + + img { + box-shadow: 0 0 3px $grey1; + padding: 0.5em; + background-color: white; + max-width: 100%; + margin-bottom: 0.75em; + + &:hover { + @include box-shadow(0, 0, 4px, $grey2); + } + } + + iframe, + embed, + .youtube-player { + min-height: 320px; + } + + .footnotes { + font-size: $scalex2; + + ol { + font-size: $scalex2; + + li { + font-size: $scalex2; + + p, + p:first-child { + font-size: $scalex2; + } + } + } + } +} + +a { + color: $navy; +} + +a.external { + position: relative; + @include transition; + + .icon { + position: absolute; + margin-top: -0.5em; + margin-right: -0.5em; + opacity: 0; + font-size: 0.825em; + } + + &:hover { + .icon { + opacity: 1; + } + } +} \ No newline at end of file diff --git a/themes/helm/assets/sass/docs-footer.scss b/themes/helm/assets/sass/docs-footer.scss new file mode 100755 index 0000000000..401cbef1e1 --- /dev/null +++ b/themes/helm/assets/sass/docs-footer.scss @@ -0,0 +1,138 @@ + + +.footer-links { + margin-left: $sidebarWidth; + background: + url('/img/topography.png') repeat top left, + linear-gradient(180deg, darken($navy, 3.5%) 0%, $navy 100%); + background-blend-mode: color-burn; + background-attachment: fixed; + padding: 2rem 3.5vw 1.5rem; + max-width: 100%; + + hr { + background-color: $blue1; + } + + .copyright { + p { + color: $grey1; + + a { + color: $blue1; + + &:hover { + color: $blue2; + } + } + } + } + + dl { + font-family: 'Space Mono'; + padding-bottom: 2rem; + + dt, + dd { + color: lighten($blue3, 12.5%); + @include klinicReg; + font-family: 'Space Mono'; + } + dt { + @include klinicBold; + margin: 1.2rem 0; + color: black; + + a { + color: lighten($blue3, 12.5%); + @include wave; + + &:hover { + color: lighten($blue3, 50%); + } + } + } + + dd { + margin: 0 0 0.5rem; + + a { + color: white; + line-height: 1.5; + display: inline-block; + background-color: transparent !important; + border-bottom: 2px solid transparent; + @include wave; + } + + em { + color: darken($light2, 25%); + font-style: normal; + font-size: 0.7rem; + padding-left: 0.333sem; + } + } + } +} + + +.contrib-text { + p { + color: white; + font-size: 1rem; + margin: 0 auto; + padding-left: 2rem; + + &.lead { + font-size: 1.2rem; + margin: 2rem auto 3rem; + position: relative; + line-height: 4; + + &:after { + content: " "; + display: block; + width: 14%; + position: absolute; + bottom: -1.25rem; + left: 43%; + height: 5px; + background: $grey1; + opacity: 0.25; + } + } + + img { + max-height: 24px; + margin: -2px 0 0 22px; + } + + a { + color: white; + font-weight: bold; + } + } +} + +.cncf-wrap { + min-height: 2rem; + text-align: center; + + img { + max-width: 10rem; + min-width: 20vw; + margin: 1.25rem 1.667vw; + } + + p { + margin: 1.5vw 2.5% 0 0; + display: inline-block; + color: white; + font-size: 1.125vw; + font-weight: bold; + + &:hover { + color: $blue2; + } + } +} diff --git a/themes/helm/assets/sass/docs-responsive.scss b/themes/helm/assets/sass/docs-responsive.scss new file mode 100755 index 0000000000..1c5dc066fa --- /dev/null +++ b/themes/helm/assets/sass/docs-responsive.scss @@ -0,0 +1,625 @@ +/* +// tablet + sm desktop +*/ +@media only screen and (min-width: 769px) and (max-width: 1023px) { + #banner { + position: relative; + + p { + font-size: 1.25vw; + } + } + + .page-docs .content-docs, .page-blog .content-docs { + padding-left: 0; + } + + .footer-links { + margin-left: 0; + z-index: 1620; + } + + .sidebar, + .sidebar-nav, + .sidebar .sidebar-buttons { + border-right: 2px solid $navy; + } + + // hamburger for sidebar + .sidebar-wrapper { + z-index: 1330; + width: 6.5rem; + background: none; + + // left border + &:before { + content: " "; + display: block; + top: 0; + bottom: 0; + left: 0; + width: 8px; + background: $navy; + position: fixed; + z-index: 1445; + } + + // bottom border + &:after { + content: " "; + display: block; + bottom: 0; + left: 0; + height: 8px; + width: ($sidebarWidth + 2rem); + background: $navy; + position: fixed; + z-index: 1445; + } + + input.hamburger-trigger { + display: block; + width: 3rem; + height: 3rem; + position: absolute; + top: 1.25rem; + left: 12.5rem; + z-index: 1650; + opacity: 0; + cursor: context-menu; + } + + .hamburger { + position: fixed; + top: 2.5rem; + left: 13.5rem; + z-index: 1640; + @include transition; + + span { + display: block; + width: 33px; + height: 4px; + margin-bottom: 5px; + position: relative; + background: $navyd; + border-radius: 3px; + z-index: 1; + transform-origin: 4px 0px; + transition: transform 0.5s cubic-bezier(0.77,0.2,0.05,1.0), + background 0.5s cubic-bezier(0.77,0.2,0.05,1.0), + opacity 0.55s ease; + + &:first-child { + transform-origin: 0% 0%; + } + + &:nth-last-child(2) { + transform-origin: 0% 100%; + } + } + } + + &.is-scrolled { + .hamburger-trigger { + top: 1.25rem; + } + .hamburger { + top: 2.5rem; + } + } + + + .sidebar { + transform-origin: 0% 0%; + transform: translate(-105%, 0); + transition: transform 0.5s cubic-bezier(0.77,0.2,0.05,1.0); + position: absolute; + width: $sidebarWidth; + background: none transparent; + + .search-container { + margin: 10rem 1.5rem 0; + } + + .sidebar-nav { + background: white; + margin-top: -2rem; + padding-top: 4.5rem; + } + } + + // hamburger is open + input.hamburger-trigger:checked { + ~ .hamburger span { + opacity: 1; + transform: rotate(45deg) translate(-10px, -14px); + background: $navyl; + + &:nth-last-child(3) { + opacity: 0; + transform: rotate(0deg) scale(0.2, 0.2); + } + + &:nth-last-child(2) { + transform: rotate(-45deg) translate(-5px, 10px); + } + } + + ~ .sidebar { + transform: none; + } + } + } +} // end tablet + +// mobile and tablet combined +@media only screen and (max-width: 1023px) { + section.footer-links { + padding-left: 10vw; + padding-right: 10vw; + + img { + float: left; + margin: 0 0 3rem; + } + + hr { + clear: both; + } + + dl { + dt { + margin: 0; + } + dd { + display: none; + } + } + } + + section.home-intro { + min-height: 70vh; + + img.logo { + top: 30vw; + } + + h1 { + top: 30vw; + } + h2 { + top: 37.5vw; + bottom: auto; + width: 58vw; + } + } +} + + +/* +// mobile adjustments +*/ +@media only screen and (max-width: 768px) { + html, + body, + #helm { + width: 100vw !important; + overflow-x: hidden; + overflow-y: auto; + } + + // mobile menu + .navbar-burger { + position: fixed; + top: 0.5rem; + right: 0.5rem; + z-index: 1300; + background: $salmonl; + color: $navyl; + + &.is-active { + color: white; + background-color: $dark; + position: fixed; + } + } + + .navbar-top { + li.versioner { + right: 12em; + } + } + + // .navbar-top-fixed.is-active, + .navbar-brand, + .navbar-top.navbar-top-fixed.is-active { + display: none !important; + } + + .navbar-top:not(.navbar-top-fixed) { + .navbar-menu.is-active { + background-color: $navyd; + display: inline-block !important; + left: 0 !important; + right: 0 !important; + margin: 0 !important; + position: fixed; + top: 0; + padding: 1.5rem 0 4rem 0; + z-index: 1100; + width: 100vw; + min-height: 5rem; + + a.navbar-item { + padding: 0.75rem 2rem; + color: white; + } + } + } + + .home-intro { + + img.logo { + position: absolute; + top: 11.25rem !important; + left: 10vw; + right: auto; + margin: 0; + width: 18.5vw; + } + + .boat.boat-badge{ + display: none; + } + + h1 { + font-size: 5vw; + position: absolute; + left: 38%; + top: 12rem !important; + margin: 0; + max-width: 50%; + line-height: 1.2; + letter-spacing: -0.015rem; + } + + h2 { + top: 37.5vh !important; + left: 14vw; + right: 14vw; + font-size: 3vw; + position: absolute; + bottom: auto; + width: 70vw !important; + padding: 1.5rem 2.5vw; + border: none; + } + } + + .home-overview-wrap { + padding-bottom: 0.5rem; + + .content-wrapper { + padding: 0 2vw 3rem; + } + + article.lead { + padding: 0; + + p:first-child { + font-size: 4.25vw; + + } + } + + .tile-actions { + + ul.tabs { + li a { + font-size: 2vw; + } + } + + .tabcontent { + input { + font-size: 4vw; + } + button { + font-size: 3.75vw; + } + } + + .tile.is-child { + h2 { + font-size: 5vw; + margin-bottom: 2rem; + } + + p { + font-size: 4vw; + margin-bottom: 1.5rem; + } + } + } + + .level-faqs { + width: 92vw; + + p.heading { + font-size: 4vw; + } + p.title { + font-size: 3.5vw; + padding-bottom: 0.5rem; + } + } + } + + .helm-community { + h2 { + font-size: 4.75vw; + } + p { + font-size: 4vw; + } + + .community-boxes { + .box { + padding-left: 4vw; + padding-right: 4vw; + } + } + } + + // blog + .page-blog-list, + .page-blog-single { + section.content-blog { + + .content-wrapper { + max-width: 100vw !important; + padding: 2rem 0 3rem; + } + } + } + + .blog-single { + article.content-wrapper { + h1 { + font-size: 6.5vw; + margin-top: 4rem; + } + } + } + + .page-docs, + .page-blog { + #banner { + display: none; + + &.is-active { + display: block; + top: 9.5rem; + position: fixed; + z-index: 1220; + border-top: 1px solid $navyl; + border-bottom: 1px solid $navyl; + background: $navyl; + + p { + padding: 0.25rem 0; + } + } + + a, p { + color: white; + + strong { + color: white; + } + } + + a { + text-decoration: underline; + } + + p small { + font-size: 3.33vw; + } + } + + .navbar-top { + padding-top: 0; + min-height: 3rem; + } + } + + section.content-docs { + order: 1; + } + + aside.sidebar-wrapper { + order: 2; + } + + // docs sidebar layout + .sidebar-wrapper { + position: relative; + top: auto; + bottom: auto; + left: auto; + min-height: 2rem; + width: 100vw; + overflow: visible; + + .sidebar { + position: relative; + margin-top: 2.5rem; + width: 100vw; + min-height: 2rem; + padding: 0; + border: none; + background: url("/img/topography.png") left 100px repeat-x; + } + + &.is-active { + display: block; + } + + // toggle docs menu on mobile + #sidebar-toggle { + width: 100vw; + position: relative; + text-align: center; + margin: 0 auto; + padding: 0.5rem 0; + background: $light2; + z-index: 1211; + @include klinicBold; + + &:hover { + color: $navyd; + } + + &.active .icon { + transform: rotate(180deg); + } + } + + .sidebar-content-wrapper { + display: none; + padding: 1rem 7.5vw; + border: 12px solid $light2; + margin-left: 8px; + z-index: 940; + + .sidebar-nav { + width: 80vw; + position: relative; + top: auto; + bottom: auto; + } + + .search-container { + margin-top: 0; + } + + &.active { + display: block; + left: 0; + right: 0; + width: 96.8%; + min-height: 100vh; + z-index: 1850; + background: url("/img/topography.png") left 100px repeat-x; + } + + ul.sidebar-main { + padding-bottom: 0; + } + } + } + .page-docs .content-docs { + padding-left: 0; + padding-top: 0; + } + + .page-docs .content-docs { + padding-left: 0; + padding-right: 0; + } + + footer { + .helm-contrib-logos { + padding-left: 4vw; + padding-right: 4vw; + } + } + + // content sizes + .content-wrapper { + max-width: 90vw !important; + padding: 2rem 5vw 3rem; + + h1 { + font-size: 5vw; + padding-top: 1rem; + } + + article { + padding-left: 7.5vw; + padding-right: 7.5vw; + + h1 { + font-size: 5.35vw; + padding-top: 2rem; + } + } + + p { + font-size: 3vw; + } + + p, ol, ul, dl, blockquote { + padding-right: 0; + } + + .quick-links { + .quick-item { + border: 1px solid $navyl; + min-height: 7.25rem; + padding: 1rem 1.5rem; + background: $light1; + margin-bottom: 0.5em; + + h4 { + font-size: 4vw; + width: 100%; + margin: 0; + } + p { + width: 100%; + font-size: 3.25vw; + line-height: 1.6; + } + + &.nav-dropdown { + display: none !important; + } + } + } + } + + // algolia search + .st-default-autocomplete { + width: 90% !important; + min-width: 320px !important; + left: 5% !important; + } + + .cncf { + padding-top: 2rem; + padding-bottom: 2rem; + + img, + p { + float: none; + min-width: 80%; + margin: 1.5rem auto; + } + + img { + min-width: 10%; + max-width: 40vw; + } + } + + .footer-links { + margin-left: 0; + + p.lead { + font-size: 1rem; + } + } +} diff --git a/themes/helm/assets/sass/docs-sidebar.scss b/themes/helm/assets/sass/docs-sidebar.scss new file mode 100755 index 0000000000..d8df628426 --- /dev/null +++ b/themes/helm/assets/sass/docs-sidebar.scss @@ -0,0 +1,215 @@ +// wrap the sidebar links in a vertical scrollable section +// 100% height (minus the height of h1 and sidebar-button) + +.sidebar-wrapper { + min-height: 100vh; + width: $sidebarWidth; + z-index: 550; + position: fixed; + top: 8px; + bottom: 8px; + left: 8px; + padding:0; + background: url('/img/topography.png') left top repeat; + background-attachment: fixed; + + &.is-scrolled .sidebar-nav { + top: 8.5rem; + } +} + +.sidebar { + min-height: 100vh; + z-index: 700; + width: $sidebarWidth; + border-right: 1px solid lighten($blue1, 40%); + + // fixed scrollable wrapper for the links + .sidebar-nav { + position: fixed; + top: 12rem; + bottom: 6.5rem; + overflow-y: scroll; + overflow-x: hidden; + width: $sidebarWidth; + } + + a { + @include transition; + } + + ul { + margin: 0 auto 0.5em; + padding: 2rem 0 2rem; + @include transition; + + li { + a { + display: block; + padding: 0.4em 2vw 0.4em; + font-size: 1.025rem; + line-height: 1.333; + text-transform: capitalize; + background-color: transparent; + @include klinicBold; + @include transition(all, 0.3s, cubic-bezier(0.25,0.1,0.25,1)); + + &.active, + &[state="open"] { + color: $navyl; + background: white; + + .ripple span { + width: 100%; + opacity: 1; + } + + & + ul { + display: block; + } + } + + &:hover { + background: lighten($light2, 5%); + } + } + + ul { + margin: 0; + padding: 0.75em 0 1.25em; + display: none; + + li.toctree-12 { + margin: 0; + + a { + padding: 0.25em 0.5vw 0.25em 3vw; + line-height: 1.4; + color: $navyl; + font-family: $base; + font-size: $scalex3; + border-right: 3px solid white; + @include transition; + + &:hover { + color: $navy; + background: lighten($blue3, 50%); + border-right: 3px solid lighten($blue2, 12.5%); + } + } + + > a.active { + border-right: 3px solid $navy; + background: rgba(255,255,255,0.67); + color: $navy; + } + } + } + } + } + + .sidebar-buttons { + width: $sidebarWidth; + height: 6.5rem; + border-top: 1px solid lighten($blue1, 40%); + border-right: 1px solid lighten($blue1, 40%); + background: white; + position: fixed; + bottom: 0; + + .button-wrap { + padding: 1rem 1.5rem; + width: $sidebarWidth; + } + + .button { + margin: 0.333em auto; + display: block; + padding: .75rem 0; + min-height: 3.5rem; + background-color: desaturate(lighten($blue1, 35%), 20%); + border: 2px solid lighten($blue1, 17.5%); + color: $blue3; + + &:hover { + background-color: $blue; + color: white; + } + + &:hover { + background-color: $blue; + color: white; + } + + i { + margin: -0.05em 0.5em 0 -0.667em; + // color: $blue3; + font-size: $scalex3; + } + } + } + + .search-container { + z-index: 1020; + position: relative; + padding-top: 1rem; + margin: 5rem 1.5vw 0; + position: relative; + @include transition; + + input { + font-size: 0.75rem; + width: 100%; + background: $light1; + border: none; + border-bottom: 2px solid lighten($navyl, 33.33%); + padding: 0.75rem 1vw; + font-family: $mono; + color: $navyl; + @include transition; + + &:focus { + background: $salmonl; + color: $navyd; + } + } + + .icon { + position: absolute; + top: 1.5rem; + right: 0.5rem; + color: $navyl; + } + + & > .algolia-autocomplete{ + display: block !important; + margin: auto; + width: 98%; + } + } +} + +.sidebar-wrapper.is-scrolled { + ul.sidebar-main { + padding-top: 2rem; + } + + .search-container { + margin-top: 4.125rem; + } +} + +.left-off-canvas-toggle .fa { + &:before { + color: $blue3; + } + background-color: white; +} + +// custom algolia search results +.algolia-autocomplete.algolia-autocomplete-left { + .ds-dropdown-menu { + z-index: 1540 !important; + background-color: white !important; + } +} \ No newline at end of file diff --git a/themes/helm/assets/sass/docs-topbar.scss b/themes/helm/assets/sass/docs-topbar.scss new file mode 100755 index 0000000000..a27defd931 --- /dev/null +++ b/themes/helm/assets/sass/docs-topbar.scss @@ -0,0 +1,258 @@ +#banner { + background: $light2; + color: white; + position: absolute; + top: 0; + left: 0; + right: 0; + margin: 0; + text-align: center; + z-index: 850; + + p { + color: $navy; + padding: 0.75rem 0 1rem; + } + + a { + color: $navyl; + @include ripple; + } + + display: block; +} + +.navbar-top { + z-index: 1150; + position: absolute; + top: 0; + left: 0; + right: 0; + min-height: 5.125rem; + background: transparent; + display: flex; + justify-content: center; + border: none; + @include transition; + + &.navbar-top-fixed { + position: fixed; + left: 8px; + right: 8px; + top: -120px; + padding-top: 0; + min-height: 5rem; + background: white url('/img/topography.png') left top repeat; + background-attachment: fixed; + z-index: 1140; + + &.is-active { + display: block; + top: 8px; + } + } + + a.navbar-item { + color: $navy; + font-size: 1rem; + @include ripple; + @include klinicBold; + padding: 1.75rem 1.5vw; + + &:hover { + @include opacity(rgba($salmon, 0.5), white); + } + } + + .navbar-menu { + align-items: center; + justify-content: center; + } + + a.button { + margin: 1rem 0; + background-color: rgba(255,255,255,0.5); + font-size: 1rem; + letter-spacing: -0.02em; + position: absolute; + height: 3rem !important; + right: 1rem; + padding: 1rem 1.25vw; + border: 2px solid $navyl; + color: $navyl; + @include transition; + + &:hover { + background-color: $navyl; + color: white; + border-color: $navyl; + } + } + + li.versioner { + padding: 1rem 0.5rem 0 !important; + margin: 0 -3rem -1px !important; + position: absolute; + right: 3.5rem; + + &.l18ner { + right: 10rem; + + a.versioner-trigger { + min-width: auto; + padding-right: 2.25rem; + } + + .l18n-prompt a { + background-color: $light1; + display: block; + text-align: center; + line-height: 1.75; + margin: 0.5rem auto; + } + + ul.dropdown-menu { + padding-top: 1rem; + li.navbar-item { + a { + + code { + color: $navy; + background-color: lighten($yellow, 25%); + border-radius: 50%; + display: inline-block; + line-height: 2; + margin-right: 0.667rem; + } + + &.active { + font-weight: bold; + color: $dark; + + code { + color: $dark; + background-color: lighten($salmon, 7.5%); + } + } + } + } + } + } + + a.versioner-trigger { + background: rgba(255,255,255,0.5); + min-width: 6.25rem; + padding: 0.82rem 0.8rem; + display: inline-block; + text-align: left; + position: relative; + color: $navyl; + font-size: .825rem; + @include klinicBold; + @include border-radius; + letter-spacing: 0; + border: 1px solid darken($light2, 5%); + overflow: visible; + } + + // versioning dropdown + ul.dropdown-menu { + padding: 0; + margin: 0 0 0 1rem; + text-align: left; + min-width: 12.5rem; + + li { + margin: 0; + display: block; + + a.navbar-item { + margin: 0; + color: $blue3; + text-align: left; + font-size: 1rem; + padding: 0.5rem 1rem; + min-height: 1rem; + line-height: 1.8; + display: block; + + em { + color: $grey2; + font-family: monospace; + font-size: 0.825em; + font-style: normal; + font-weight: normal; + padding-left: 0.5rem; + } + + &.active { + font-weight: bold; + } + } + } + } + } +} + +.navbar-brand { + min-height: 0 !important; + + a { + position: absolute; + top: 5rem; + left: 5rem; + + svg { + width: 10rem; + } + } +} + + +// Modifiers + + // Home + .page-home, + .page-404 { + .navbar-top-fixed .container { + margin-left: 0; + margin-right: 0; + } + + .navbar-brand { + display: none; + } + } + + .docs, + .page-docs { + .navbar-top { + a.button { + display: none; + } + } + } + + .home, + .page-blog { + .versioner { + display: none; + } + + li.versioner.l18ner { + display: block; + right: 13.75rem; + } + } + + body.ko { + .navbar-top { + li.versioner { + right: 12vw; + } + + li.versioner.l18ner { + right: 20vw; + } + } + } diff --git a/themes/helm/assets/sass/helm-blog.scss b/themes/helm/assets/sass/helm-blog.scss new file mode 100755 index 0000000000..0104e01f55 --- /dev/null +++ b/themes/helm/assets/sass/helm-blog.scss @@ -0,0 +1,144 @@ +.blog-layout { + padding-left: 0 !important; + background-color: white; + + h1.blog-logo { + margin: 0; + padding: 0; + min-height: 5.125rem; + z-index: 1020; + text-transform: none; + position: fixed; + width: 300px; + left: 0; + top: 0; + display: block; + background-color: white; + border-bottom: 1px solid lighten($blue1, 35%); + border-right: 1px solid lighten($blue1, 35%); + + a { + padding: 0.333em 2.25rem; + background-color: white; + display: inline-block; + max-height: 4rem; + line-height: 4rem; + position: absolute; + font-size: 1.5rem; + color: $blue3; + letter-spacing: -0.125rem; + text-align: left; + @include klinicReg; + + em { + font-style: normal; + } + + &:first-of-type { + min-width: 30%; + left: 0; + } + + &:last-of-type { + min-width: 70%; + right: 0; + } + + img, + svg { + display: block; + fill: currentColor; + @include transition; + } + + svg { + margin-top: 0.5rem; + } + + span { + top: 1em; + position: absolute; + font-size: 1.5rem; + color: $blue3; + left: 6.5rem; + letter-spacing: -0.125rem; + @include klinicReg; + } + + &:hover { + background: $light2; + + svg { + color: white !important; + } + } + } + } + + .footer-links { + margin-left: 0; + } + + .content-wrap { + article { + h1 { + padding-top: 4rem; + } + + .date { + color: $blue3; + + } + + .author { + font-weight: bold; + padding-top: 2rem; + font-size: 1.25rem; + } + } + + .pagination { + padding-top: 3.5rem; + + span, a { + padding: 1rem; + font-size: 1.25rem; + font-weight: bold; + background: $light2; + @include box-shadow; + } + } + } +} + +.blog-single { + article.content-wrapper { + h1 { + font-size: 2.667rem; + margin-top: 7.5rem; + } + } +} + +.rss { + background-color: lighten($light2, 5%); + margin: -2rem auto 7.5rem; + max-width: 50rem; + display: block; + text-align: center; + border-radius: 0.75rem; + + a { + padding: 1.5rem 2rem 1.5rem; + display: block; + text-align: center; + + span { + margin: 0 1rem; + + svg { + max-height: 0.75rem; + } + } + } +} diff --git a/themes/helm/assets/sass/helm-boat.scss b/themes/helm/assets/sass/helm-boat.scss new file mode 100644 index 0000000000..5a525526d4 --- /dev/null +++ b/themes/helm/assets/sass/helm-boat.scss @@ -0,0 +1,209 @@ +@keyframes boat-bob { + 0% { + bottom: 2vw; + } + 50% { + bottom: 3.5vw; + } + 100% { + bottom: 2vw; + } +} + +@keyframes boat-badge-bob { + 0% { + top: 0.425vw; + } + 50% { + top: 0.75vw; + } + 100% { + top: 0.425vw; + } +} + +// boat full width default +.boat { + width: 100vw; + position: absolute; + top: auto; + bottom: 8px; + left: 0; + right: 0; + min-height: 10vw; + z-index: 1070; + + .boat-ship { + position: absolute; + margin-top: 0.5vw; + left: 3.25vw; + bottom: 2vw; + max-width: 15vw; + z-index: 1060; + animation: boat-bob 7s ease-in-out infinite; + @include transition; + } + + &:after { + content: "ahoy!"; + font-family: $mono; + font-size: .75rem; + padding: 0.75em; + color: $navy; + background: $salmonl; + position: absolute; + bottom: 8vw; + left: 13.5vw; + line-height: 1; + z-index: 1005; + opacity: 0; + @include transition; + } + + &:hover:after { + opacity: 1; + bottom: 11vw; + } + + .wave-wrapper { + position: absolute; + margin: 0; + left: 0; + // offsets for navy border + right: 15px; + bottom: -8px; + height: 15vw; + overflow: hidden; + z-index: 1014; + background-color: transparent; + @include transition; + + &:before { + position: absolute; + bottom: 0; + left: 0; + right: 0; + content: " "; + height: 3.5vw; + width: 100%; + background: $navyl; + @include transition; + } + + .waves { + position:relative; + width: 100%; + height: 3vw; + margin-top: 9.5vw; + margin-bottom: -7px; + min-height: 0.5vw; + max-height: 2vw; + @include transition; + } + } + + .parallax > use { + animation: move-forever 25s ease-in-out infinite; + } + .parallax > use:nth-child(1) { + animation-delay: -2s; + animation-duration: 7s; + } + .parallax > use:nth-child(2) { + animation-delay: -3s; + animation-duration: 10s; + } + .parallax > use:nth-child(3) { + animation-delay: -4s; + animation-duration: 13s; + } + .parallax > use:nth-child(4) { + animation-delay: -5s; + animation-duration: 20s; + } + @keyframes move-forever { + 0% { + transform: translate3d(-90px,0,0); + } + 100% { + transform: translate3d(85px,0,0); + } + } +} + +// boat fixed nav 'badge' mode +.boat.boat-badge { + position: fixed; + top: 1.25vw; + left: 2vw; + width: 7.5vw; + height: 7.5vw; + z-index: 1320; + + &, + .boat-ship, + .wave-wrapper, + .wave-wrapper:before, + .wave-wrapper:after { + bottom: auto; + right: auto; + } + + .boat-ship { + left: 0.636vw; + top: 0.2vw; + z-index: 1025; + max-width: 7vw; + animation: boat-badge-bob 7s ease-in-out infinite; + } + + .wave-wrapper { + width: 7.5vw; + height: 7.5vw; + border-radius: 50%; + border: 3px solid rgba(255,255,255, 0.05); + background-blend-mode: screen; + background: rgba(219,225,243,0.5); + + .waves { + margin-top: 3.75vw; + margin-bottom: -7px; + min-height: 0.25vw; + max-height: 1.5vw; + } + + &:before { + width: 100%; + height: 3vw; + top: 5.25vw; + } + } + + &:after { + left: 7.5vw; + top: 2.5vw; + z-index: 1007; + padding: 0.25rem; + height: 1.2rem; + font-size: 0.667rem; + } + + &:hover:after { + top: 0.75vw; + } +} + + +/*Shrinking for mobile +@media (max-width: 768px) { + .waves { + height:40px; + min-height:40px; + } + .content { + height:30vh; + } + h1 { + font-size:24px; + } +}*/ \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/src/sass/helm/_buttons.scss b/themes/helm/assets/sass/helm-buttons.scss old mode 100644 new mode 100755 similarity index 100% rename from docs.helm.sh/rootfs/public/src/sass/helm/_buttons.scss rename to themes/helm/assets/sass/helm-buttons.scss diff --git a/themes/helm/assets/sass/helm-home.scss b/themes/helm/assets/sass/helm-home.scss new file mode 100755 index 0000000000..2b3709d304 --- /dev/null +++ b/themes/helm/assets/sass/helm-home.scss @@ -0,0 +1,632 @@ +// overwrites global styles on homepage +.page-home { + .navbar-top { + min-height: 4.25rem; + + .container { + min-height: 1rem; + } + } +} + +.page-home + .footer-links { + margin-left: 0; + + dl { + dt { + font-size: 1.25rem; + } + } +} + +// unique homepage layouts +.home-intro { + min-height: 100vh; + background: url('/img/topography.png') left top repeat; + background-attachment: fixed; + position: relative; + margin-bottom: -16px; + + img.logo { + position: absolute; + top: 50vh; + margin-top: -14vw; + right: 60vw; + width: 10vw; + } + + h1 { + font-size: 2.775vw; + position: absolute; + left: 44vw; + top: 50vh; + margin-top: -13.25vw; + max-width: 40vw; + line-height: 1.2; + letter-spacing: -0.015rem; + + strong { + display: block; + font-style: normal; + color: $navy; + } + + em { + margin-bottom: -0.25vw; + } + } + + h2 { + border: 5px solid $light1; + font-size: 2vw; + position: absolute; + background: rgba(255,255,255,0.67); + bottom: 8.5vw; + left: 25vw; + width: 48vw; + padding: 2vw 5.5vw 2vw 2.5vw; + line-height: 1.5; + letter-spacing: -0.015rem; + vertical-align: center; + letter-spacing: 0.05em; + color: $navyd; + font-family: $base; + z-index: 1110; + + a { + color: $navyl; + @include ripple; + } + } +} + + +// v2 era layout + +.home-overview-wrap { + background: + url('/img/topography.png') repeat top left, + linear-gradient(180deg, darken($navy, 5%) 0%, $navy 100%); + background-blend-mode: color-burn; + background-attachment: fixed; + padding-top: 7.5rem; + // padding-bottom: 5rem; + min-height: 100vh; + + .content-wrapper { + max-width: 80vw; + padding-bottom: 5rem; + + h2, h3, p { + color: white; + } + + .lead { + text-align: left; + + p { + color: white; + padding-right: 5vw; + line-height: 1.925; + } + + h3 { + margin: 2.5rem 0 1.25rem; + } + } + + ul { + margin: 0 2vw; + padding: 0; + color: white; + + li { + color: white; + } + } + + a { + background: $navyd; + opacity: 0.9; + color: white; + text-decoration: underline; + } + + a:hover { + background: $navyl; + color: white; + } + } + + h2 { + font-weight: bold; + color: white; + } + + img.pyramid { + max-width: 10vw; + } + + .tile-features { + .tile.is-parent { + padding: 3rem 0 0; + } + + .tile.is-child { + background: darken($navyd, 7%); + border-radius: 0.5vw; + padding: 0.75rem 1rem; + box-shadow: none; + + p { + font-size: 1rem; + line-height: 1.636; + margin: 0.75rem 0 0.25rem; + + &.title { + font-size: 1.333vw; + margin: 0; + color: white; + } + + code { + background: none; + color: white; + font-size: 0.925rem; + } + } + } + } + + .tile-actions { + padding: 0; + margin: 2rem 6.25vw 4.5rem; + + .tile.is-child { + padding: 0.75vw 2.5vw 3vw; + border: 10px solid white; + background: url('/img/topography.png') left top repeat; + background-color: rgba(35,35,35,0.02); + background-blend-mode: color-burn; + background-attachment: fixed; + + &:first-of-type { + border-right: none; + } + + p { + font-size: 1.25vw; + line-height: 1.7; + color: $dark1; + } + + img { + max-width: 66.67%; + margin: 2.5vw auto 0; + box-shadow: 0 2px 5px $dark1; + } + } + + h2 { + color: $navyd; + font-size: 2vw; + text-align: center; + } + + ul.tabs { + border-bottom: 3px solid $light1; + margin: 2.5vw 0 0.75vw; + position: relative; + z-index: 200; + overflow: visible; + + li { + margin: 0 0 -2px; + border: none; + padding: 0; + z-index: 680; + position: relative; + + a { + @include klinicBold; + font-size: 1vw; + border-bottom: 3px solid $light1; + margin: 0; + + &.active { + color: $navyl; + border-bottom: 2px solid $navyl; + } + } + } + } + + @keyframes fadeEffect { + from { opacity: 0; } + to { opacity: 1; } + } + + .tabcontent { + display: none; + animation: fadeEffect 1s; /* Fading effect takes 1 second */ + position: relative; + padding-bottom: 4.25rem; + + &.active { + display: block; + } + + code, + pre, + input { + overflow-wrap: break-word; + white-space: -moz-pre-wrap !important; /* Mozilla, since 1999 */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + white-space: pre-wrap; /* css-3 */ + word-wrap: break-word; /* Internet Explorer 5.5+ */ + white-space: -webkit-pre-wrap; /* Newer versions of Chrome/Safari*/ + word-break: break-all; + white-space: normal; + background: $light2; + border: none; + outline: none; + color: $navyd; + font-size: 1.333vw; + font-family: monospace; + font-weight: 400; + width: 100%; + padding: 1.2rem 6.25rem 1.2rem 1.2rem; + + &:before { + display: none; + } + } + + button { + position: absolute; + right: 0.5rem; + top: 0.45rem; + background: white; + border: 2px solid $navyl; + font-size: 1.1vw; + color: $navyl; + @include transition; + + &:hover { + background-color: $navyl; + color: white; + } + &:active { + background: $green; + color: white; + } + } + } + } + + .level-faqs { + background-color: $light2; + min-width: 37.5vw; + margin: 1rem auto 7.5rem; + padding: 1vw; + border-radius: 5rem; + + img { + max-width: 6vw; + margin-left: -1vw; + } + + p { + min-width: 25vw; + } + + p.heading { + @include klinicBold; + font-size: 1.25vw; + margin-bottom: 0.333rem; + text-transform: none; + } + + p.title { + font-size: 1vw; + } + } +} + +.home-overview { + position: relative; + + .large-3 { + min-height: 280px; + } + + h2 { + @include klinicBold; + color: white; + margin: 1.5rem 0 2.5rem; + display: inline-block; + + .fa { + color: $pink; + } + } + + h3 { + color: white; + margin: 0.25em 0 0.5em; + font-size: 1.5rem; + padding-top: 90px; + position: relative; + @include klinicBold; + + small { + position: absolute; + top: 8.667em; + color: white; + width: 10em; + left: 50%; + font-size: 0.6em; + margin-left: -5em; + } + } + + .columns { + position: relative; + } + + img { + position: absolute; + top: 0; + left: 50%; + margin-left: -29px; + } + + p { + font-size: 0.925rem; + padding: 0 5%; + line-height: 1.5; + + code { + border: none; + } + } + + .row { + background-color: white; + + &:first-child { + border-radius: 0.5em 0.5em 0 0; + } + &:last-child { + padding-bottom: 0.5em; + border-radius: 0 0 0.5em 0.5em; + } + } +} + +.get-helm { + padding-bottom: 50px; + border: 2px dashed $lightblue; + padding: 2em; + margin-bottom: 4em; + position: relative; + z-index: 100; + + &:after { + position: absolute; + display: block; + content: " "; + top: 0.667em; + left: -0.25em; + width: 100%; + height: 375px; + z-index: -5; + background-color: $darkblue; + transform: rotateX(12deg); + opacity: 0.425; + } + + h2 { + margin: 0 0 0.5em; + padding: 0; + } + + img { + margin: 0.333em 0; + } +} + +.get-charts { + padding-left: 3.5rem; + + h2 { + margin: 2.5rem 0 1rem; + padding: 0; + } +} + +.helm-community { + color: $navy; + padding-top: 2rem; + padding-bottom: 5rem; + background: linear-gradient( 0deg, #fff, #F7F7F7); + border-bottom: 1px solid $light1; + + h2 { + @include klinicBold; + margin: 5rem auto 1rem; + } + + h2 + p { + margin-bottom: 4.25rem; + } + + p { + font-size: 1.25rem; + padding-right: 0; + } + + .community-boxes { + margin: 0 6vw; + + .box { + padding: 0.4rem 1.667vw; + box-shadow: 0 5px 12px $light2; + + &:hover { + box-shadow: 0 1px 10px $light2; + @include transition; + } + .title { + font-size: 1.5rem; + } + + a { + // text-decoration: underline; + color: $navy; + border-bottom: 1px solid $navyl; + @include ripple; + text-align: left; + } + + dl, p, ul, ol { + margin: 0 0 1.5rem + } + + p, dd, dt { + font-size: 1.12rem; + line-height: 1.5; + color: $dark; + } + + .placeholder { + background: $salmonl; + font-style: italic; + padding: 1.125rem 0; + text-align: center; + margin: 1rem 0; + display: inline-block; + width: 100%; + color: $grey2; + border-radius: 0.5rem; + } + + dd { + padding: 0.25rem 0; + + em { + font-size: 1rem; + color: darken($light2, 50%); + } + } + + h3, dl dt { + @include klinicBold; + color: $navyl; + font-size: 1.125rem; + margin-top: 1.25rem; + + a { + color: $navyl; + } + } + + .subtitle { + font-size: 0.925rem; + margin: 0.25rem 0 1.5rem; + font-weight: normal; + background: $light1; + display: inline-block; + padding: 0.5rem 0.75rem; + line-height: 1.4; + } + } + } +} + +.helm-contrib-logos { + text-align: center; + padding-bottom: 8rem; + padding-top: 1.5rem; + + img { + padding: 0; + display: inline-block; + margin: 0 2vw; + width: 23vw; + max-width: 12rem; + } + + .helm-logo { + margin: 0 auto 2.25em; + display: block; + text-align: center; + padding: 3.5em 0 0; + } + + hr { + background-color: $lightblue; + height: 2px; + opacity: 0.25; + width: 50%; + margin: 1rem 25%; + } + + p { + color: $dark1; + text-align: center; + padding: 0; + margin: 0 auto; + font-size: 1.333em; + line-height: 2; + letter-spacing: 0.025em; + color: #9B9B9B; + + a { + font-weight: bold; + color: $darkblue; + border-bottom: 2px solid transparent; + + &:hover { + border-bottom: 2px solid $blue; + } + } + + small { + padding-top: 1rem; + font-size: 0.925em; + } + } +} + +.full-width { + min-width: 100%; +} + +.cncf { + background: RGBA(246, 246, 246, 1.00); + min-height: 5rem; + margin-top: 4rem; + text-align: center; + padding-left: 0 !important; + + img { + float: left; + display: inline-block; + max-width: 14rem; + margin: 3rem 5%; + } + + p { + float: right; + margin: 3.5rem 5%; + display: inline-block; + font-family: helvetica; + color: #777; + + &:hover { + color: $lightblue; + } + } +} diff --git a/themes/helm/assets/sass/helm-layout.scss b/themes/helm/assets/sass/helm-layout.scss new file mode 100755 index 0000000000..6e51c56824 --- /dev/null +++ b/themes/helm/assets/sass/helm-layout.scss @@ -0,0 +1,145 @@ +html, +body { + min-height: 100%; + padding: 0; + margin: 0; + background: $navyd; + + // page blue border style + .page-wrapper { + border: 8px solid $navy; + border-bottom: none; + position: relative; + background: white; + + &:before, + &:after { + position: fixed; + z-index: 1200; + content: " "; + display: block; + top: 0; + left: 0; + right: 0; + height: 8px; + width: 100%; + background: $navy; + } + &:before { + top: 0; + } + &:after { + bottom: 0; + top: auto; + } + } +} + +.main { + min-height: 760px; +} + +.content-wrapper { + padding: 7rem 0 5rem; + max-width: 66.67vw; + margin-left: auto; + margin-right: auto; +} + +// docs layout +$sidebarWidth: 18.5rem; + +.page-docs, +.page-blog { + + .navbar-top { + background: url('/img/topography.png') left top repeat; + background-attachment: fixed; + + &:after { + height: 1px; + position: absolute; + bottom: 0; + display: block; + content: " "; + background-color: lighten($blue1, 40%); + left: $sidebarWidth; + right: 0; + } + } + + .navbar-brand { + width: 15rem; + position: relative; + + a { + display: block; + position: absolute; + top: 0rem; + left: -1.25rem; + padding: 0.725rem 1.75rem 0.667rem 1.75rem; + width: $sidebarWidth; + @include transition; + + svg { + width: 3rem; + fill: white; + @include transition; + } + + &:after { + display: inline-block; + content: "Docs"; + @include klinicBold; + position: absolute; + top: 1.75rem; + left: 6rem; + } + + &:hover { + @include opacity(rgba($salmon, 0.5), white); + + img, svg { + transform: rotate(180deg); + } + } + } + } + + .navbar-top-fixed { + .navbar-brand a { + padding: 0.725rem 1.75rem 0.4rem 1.75rem + } + } + + .navbar-menu { + position: absolute; + // margin: 0 0 0 -12.5rem !important; + left: 50%; + margin: 0 0 0 ( -$sidebarWidth ); + } + + .content-docs { + padding-top: 5.5rem; + padding-left: $sidebarWidth; + } + + .page-wrapper { + max-width: 75vw; + min-height: 920px; + + .sidebar { + width: 25%; + width: 300px; + min-height: 100%; + } + } +} + +.page-blog .navbar-brand a { + border-bottom: 1px solid $light1; + + &:after { + content: "Blog"; + } +} diff --git a/themes/helm/assets/sass/helm-mixins.scss b/themes/helm/assets/sass/helm-mixins.scss new file mode 100755 index 0000000000..3a05ce8de7 --- /dev/null +++ b/themes/helm/assets/sass/helm-mixins.scss @@ -0,0 +1,328 @@ +/* Helm.sh Styles */ +// +// Variables +// +// 1. Colours +// 2. Setup Fonts +// 3. CSS3 & Vendor Prefixes + + +// 1. +// Helm 3 Colours +// +// Primary Colors + +$navy:#091C84; +$navyd:#090E6F; +$navyl:#1B53C2; + +$dark: #050843; +$light2: #B7C2E9; +$light1: #DBE1F3; + +$blue: #3B82BF; +$green: #2F84A7; +$red: #95297C; +$yellow: #D1AA9B; + +$code: desaturate(lighten($navyl, 50%), 10%); + + +// old colors + +$blue1: #2DAFE9; +$blue2: #2BA0D3; +$blue3: #2090CD; +$blue4: #277A9F; + +// Shading +$grey1: #ccc; +$grey2: #999; +$grey3: #666; +$grey4: #333333; + +// $light2: #EBF7FC; +// $light1: lighten($light2, 2.5%); + + + // old helm.sh colors, discontinue these + $grey : #E4E4E4; + $light1 : #F4F4F4; + $light2 : #E4E4E4; + + $black : #555555; + $dark1 : #4E4E4E; + $dark2 : #464646; + + $blue : #3FB1E5; + $pink : #FF2A53; + $green : #38BB4C; + + $darkpink : #EF637E; + $darkblue : #27759A; + $darkgreen : #44A653; + + $salmon : #F99EAC; + $salmonl : #F8DCDF; + + $lightpink : #FF7590; + $lightblue : #7FCCF0; + $lightgreen : #68D478; + + +// 2. +// Fonts +// + +$base: "Public Sans", Helvetica, Arial, sans-serif; +$mono: "Space Mono", "Courier New", monaco, monospace; + +@font-face { + font-family: 'Public Sans'; + src: url('../fonts/publicsans-regular-webfont.woff2') format('woff2'), + url('../fonts/publicsans-regular-webfont.woff') format('woff'); + font-weight: normal; + font-style: normal; +} +@font-face { + font-family: 'Public Sans'; + src: url('../fonts/publicsans-medium-webfont.woff2') format('woff2'), + url('../fonts/publicsans-medium-webfont.woff') format('woff'); + font-weight: bold; + font-style: normal; +} + +@font-face { + font-family: 'Space Mono'; + src: url('../fonts/spacemono-regular-webfont.woff2') format('woff2'), + url('../fonts/spacemono-regular-webfont.woff') format('woff'); + font-weight: normal; + font-style: normal; +} +@font-face { + font-family: 'Space Mono'; + src: url('../fonts/spacemono-bold-webfont.woff2') format('woff2'), + url('../fonts/spacemono-bold-webfont.woff') format('woff'); + font-weight: bold; + font-style: normal; +} + + +@mixin klinicBold { + font-family: $mono; + font-weight: bold; + letter-spacing: 0.035rem; + -webkit-font-smoothing: antialiased; +} + +@mixin klinicReg { + font-family: $mono; + font-weight: normal; + -webkit-font-smoothing: antialiased; +} +@mixin helvetica { + font-family: $base; +} + +@mixin upperCase { + text-transform: uppercase; +} + +@mixin normCase { + text-transform: none; +} + + +// 3. +// Load CSS & Vendor Prefixes +// + +@mixin transition($property:all, $duration:0.3s, $easing:ease-in-out) { + transition: $property $duration $easing; +} + +@mixin border-radius($radius1:3px, $radius2:3px) { + -webkit-border-radius: $radius1 $radius2 $radius1 $radius2; + -moz-border-radius: $radius1 $radius2 $radius1 $radius2; + border-radius: $radius1 $radius2 $radius1 $radius2; +} + +@mixin box-shadow($xlength:0, $ylength:2px, $size:0, $color:rgba(30,30,30,0.25)) { + -webkit-box-shadow: $xlength $ylength $size $color; + -moz-box-shadow: $xlength $ylength $size $color; + box-shadow: $xlength $ylength $size $color; +} + +@mixin keyframe ($animation_name) { + @-webkit-keyframes $animation_name { + @content; + } + @-moz-keyframes $animation_name { + @content; + } + @-o-keyframes $animation_name { + @content; + } + @keyframes $animation_name { + @content; + } +} + +@mixin animation ($delay, $duration, $animation) { + -webkit-animation-delay: $delay; + -webkit-animation-duration: $duration; + -webkit-animation-name: $animation; + -webkit-animation-fill-mode: forwards; + -moz-animation-delay: $delay; + -moz-animation-duration: $duration; + -moz-animation-name: $animation; + -moz-animation-fill-mode: forwards; + animation-delay: $delay; + animation-duration: $duration; + animation-name: $animation; + animation-fill-mode: forwards; +} + +@mixin opacity($color, $background) { + $percent: alpha($color) * 100%; + $opaque: opacify($color, 1); + $solid-color: mix($opaque, $background, $percent); + background-color: $solid-color; + background-color: $color; +} + +/** + * Media query breakpoints + */ + $desktopFloor: 64.0625em; + $tabletFloor: 40.063em; + $tabletCeiling: 64.0624em; + $mobileCeiling: 40em; + + @mixin mobile { + @media only screen and (max-width: $mobileCeiling) { + @content; + } + } + + @mixin tablet { + @media only screen and (min-width: $tabletFloor) { + @content; + } + } + + @mixin mobileAndTablet { + @media only screen and (max-width: $tabletCeiling) { + @content; + } + } + + @mixin desktop { + @media only screen and (min-width: $desktopFloor) { + @content; + } + } + + @mixin landscape { + @media only screen and (min-width: 569px) and (max-width: 736px) and (orientation: landscape) { + @content; + } + } + + @mixin smallLandscape { + @media only screen and (max-width: 568px) and (orientation: landscape) { + @content; + } + } + + // vertical alignment + @mixin fullheight { + min-height: 100%; + height: 100%; + } + + @mixin centerer { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + } + + @mixin topper { + position: absolute; + top: 0%; + } + + @mixin bottomer { + position: absolute; + bottom: 0%; + } + + // link effect + @mixin ripple($color: $navyl) { + position: relative; + display: inline-block; + text-align: center; + @include transition; + + &::after { + display: inline-block; + content: ""; + background: $color; + height: 3px; + position: absolute; + bottom: 0; + left: 50%; + width: 10%; + opacity: 0; + margin: 0 0 0 -5%; + @include transition; + } + + &:hover::after { + width: 100%; + left: 0; + margin-left: 0; + opacity: 1; + } + } + +// link effect +@mixin wave($color: $salmon) { + position: relative; + display: inline-block; + text-align: center; + overflow: hidden; + vertical-align: middle; + line-height: 1.5; + z-index: 200; + margin: 0 -0.5em; + padding: 0 0.5em; + @include transition; + + &::after { + display: inline-block; + content: " "; + background: $salmon; + background-blend-mode: screen; + width: 120%; + height: 2em; + position: absolute; + left: 0; + opacity: 0; + bottom: -2.5em; + z-index: -10; + @include transition; + } + + &:hover { + color: $navyl !important; + // padding-left: 0.2em; + // padding-right: 0.2em; + + &::after { + bottom: 0; + opacity: 1; + } + } +} \ No newline at end of file diff --git a/themes/helm/assets/sass/helm-typography.scss b/themes/helm/assets/sass/helm-typography.scss new file mode 100755 index 0000000000..0a1a5aa972 --- /dev/null +++ b/themes/helm/assets/sass/helm-typography.scss @@ -0,0 +1,176 @@ +// +/* Typography & Vertical Rythm +// +*/ + + +// Typography Variables + + $base-font-size: 17px; + + //scale down + $scalex0: $base-font-size * 0.625; // 11.4 / 10 + $scalex1: $base-font-size * 0.75; // 13.7 / 12 + $scalex2: $base-font-size * 0.8125; // 14.8 / 14 + $scalex3: $base-font-size * 0.875; // 16 / 14 (

    ) + $scalex4: $base-font-size * 0.9375; // 17.1 / 16 + + //scale up + $scalex5: $base-font-size * 1.12; // 20.5 / 18 + $scalex6: $base-font-size * 1.25; // 22.8 / 20 + $scalex7: $base-font-size * 1.5; // 27.4 / 24 + $scalex8: $base-font-size * 2; // 36.6 / 32 + $scalex9: $base-font-size * 2.25; // 41.1 / 36 + $scalex10: $base-font-size * 2.95; // 54.9 / 48 + + +$base-line-height: 1.636; +$base-vertical-space: 2.5em; +$base-pad-right: 5%; + + +// Size Modifier Classes +.x0 { font-size: $scalex0; } +.x1 { font-size: $scalex1; } +.x2 { font-size: $scalex2; } +.x3 { font-size: $scalex3; } +.x4 { font-size: $scalex4; } +.x5 { font-size: $scalex5; } +.x6 { font-size: $scalex6; } +.x7 { font-size: $scalex7; } +.x8 { font-size: $scalex8; } +.x9 { font-size: $scalex9; } +.x10 { font-size: $scalex10; } + +// Ensure Aliasing +// +html, +body { + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + + +// Base Typography Styles +// +h1, h2, h3, h4, h5, h6 { + @include klinicReg; + margin-top: $base-vertical-space / 3; + margin-bottom: $base-vertical-space / 3; +} + +.title { + text-transform: none; + color: $navy; +} + +h1 { + color: $navy; + font-size: $scalex9; + @include klinicBold; + letter-spacing: -0.0125rem; +} + +h2 { + font-size: $base-font-size * 2.25; + + &.onboard-welcome, + .onboard-welcome { + color: $blue4; + font-size: $scalex10; + @include klinicBold; + } + + &.onboard-tasks, + .onboard-tasks { + color: $blue3; + } + + &.onboard, + .onboard { + color: $blue4; + } + + &.welcome-text, + .welcome-text { + color: $blue4; + font-size: $base-font-size * 1.75; + @include klinicReg; + } +} + +h3 { + font-size: $base-font-size * 1.25; +} + +.content { + h3 { + @include klinicBold; + font-size: $scalex1; + color: $dark; + } +} + +h4 { + font-size: $base-font-size * 0.75; + @include klinicBold; + + &.day, + .day { + color: $grey2; + } +} + +h5 { + color: $grey4; +} + +.content h5, +.line-chart-wrap h5 { + @include klinicReg; + @include upperCase; + font-size: $base-font-size * 0.75; +} + +p, ol, ul, dl, blockquote { + font-size: $scalex3; + padding-right: $base-pad-right; + font-family: $base; + letter-spacing: 0.01em; +} + +p { + line-height: 2.15; + color: $grey3; +} + +ol, ul { + margin-left: 1.8rem; + margin-bottom: $base-vertical-space; + + li { + margin-bottom: 0.5em; + } +} + +a { + color: $blue2; +} + + +.text-upper { + @include upperCase; +} + +.regular-text { + @include klinicReg; +} + +.prefix, .postfix { + @include klinicBold; + @include border-radius; + @include upperCase; + font-size: $scalex3; + height: 3.3125rem; + line-height: 3.3125rem; +} diff --git a/themes/helm/assets/sass/materialdesignicons/_animated.scss b/themes/helm/assets/sass/materialdesignicons/_animated.scss new file mode 100644 index 0000000000..a49efad3d4 --- /dev/null +++ b/themes/helm/assets/sass/materialdesignicons/_animated.scss @@ -0,0 +1,27 @@ +// From Font Awesome +.#{$mdi-css-prefix}-spin:before { + -webkit-animation: #{$mdi-css-prefix}-spin 2s infinite linear; + animation: #{$mdi-css-prefix}-spin 2s infinite linear; +} + +@-webkit-keyframes #{$mdi-css-prefix}-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} + +@keyframes #{$mdi-css-prefix}-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} \ No newline at end of file diff --git a/themes/helm/assets/sass/materialdesignicons/_core.scss b/themes/helm/assets/sass/materialdesignicons/_core.scss new file mode 100644 index 0000000000..e074cff973 --- /dev/null +++ b/themes/helm/assets/sass/materialdesignicons/_core.scss @@ -0,0 +1,10 @@ +.#{$mdi-css-prefix}:before, +.#{$mdi-css-prefix}-set { + display: inline-block; + font: normal normal normal #{$mdi-font-size-base}/1 '#{$mdi-font-name}'; // shortening font declaration + font-size: inherit; // can't have font-size inherit on line above, so need to override + text-rendering: auto; // optimizelegibility throws things off #1094 + line-height: inherit; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} \ No newline at end of file diff --git a/themes/helm/assets/sass/materialdesignicons/_extras.scss b/themes/helm/assets/sass/materialdesignicons/_extras.scss new file mode 100644 index 0000000000..b64b4b4428 --- /dev/null +++ b/themes/helm/assets/sass/materialdesignicons/_extras.scss @@ -0,0 +1,65 @@ +$mdi-sizes: 18 24 36 48; +@each $mdi-size in $mdi-sizes { + .#{$mdi-css-prefix}-#{$mdi-size}px { + &.#{$mdi-css-prefix}-set, + &.#{$mdi-css-prefix}:before { + font-size: $mdi-size * 1px; + } + } +} + +.#{$mdi-css-prefix}-dark { + &:before { + color: rgba(0, 0, 0, 0.54); + } + &.#{$mdi-css-prefix}-inactive:before { + color: rgba(0, 0, 0, 0.26); + } +} +.#{$mdi-css-prefix}-light { + &:before { + color: rgba(255, 255, 255, 1); + } + &.#{$mdi-css-prefix}-inactive:before { + color: rgba(255, 255, 255, 0.3); + } +} + +$mdi-degrees: 45 90 135 180 225 270 315; +@each $mdi-degree in $mdi-degrees { + .#{$mdi-css-prefix}-rotate-#{$mdi-degree}{ + &:before { + -webkit-transform: rotate(#{$mdi-degree}deg); + -ms-transform: rotate(#{$mdi-degree}deg); + transform: rotate(#{$mdi-degree}deg); + } + /* + // Not included in production + &.#{$mdi-css-prefix}-flip-h:before { + -webkit-transform: scaleX(-1) rotate(#{$mdi-degree}deg); + transform: scaleX(-1) rotate(#{$mdi-degree}deg); + filter: FlipH; + -ms-filter: "FlipH"; + } + &.#{$mdi-css-prefix}-flip-v:before { + -webkit-transform: scaleY(-1) rotate(#{$mdi-degree}deg); + -ms-transform: rotate(#{$mdi-degree}deg); + transform: scaleY(-1) rotate(#{$mdi-degree}deg); + filter: FlipV; + -ms-filter: "FlipV"; + } + */ + } +} +.#{$mdi-css-prefix}-flip-h:before { + -webkit-transform: scaleX(-1); + transform: scaleX(-1); + filter: FlipH; + -ms-filter: "FlipH"; +} +.#{$mdi-css-prefix}-flip-v:before { + -webkit-transform: scaleY(-1); + transform: scaleY(-1); + filter: FlipV; + -ms-filter: "FlipV"; +} \ No newline at end of file diff --git a/themes/helm/assets/sass/materialdesignicons/_functions.scss b/themes/helm/assets/sass/materialdesignicons/_functions.scss new file mode 100644 index 0000000000..43518203bd --- /dev/null +++ b/themes/helm/assets/sass/materialdesignicons/_functions.scss @@ -0,0 +1,20 @@ +@function char($character-code) { + @if function-exists("selector-append") { + @return unquote("\"\\#{$character-code}\""); + } + + @if "\\#{'x'}" == "\\x" { + @return str-slice("\x", 1, 1) + $character-code; + } + @else { + @return #{"\"\\"}#{$character-code + "\""}; + } +} + +@function mdi($name) { + @if map-has-key($mdi-icons, $name) == false { + @warn "Icon #{$name} not found."; + @return ""; + } + @return char(map-get($mdi-icons, $name)); +} \ No newline at end of file diff --git a/themes/helm/assets/sass/materialdesignicons/_icons.scss b/themes/helm/assets/sass/materialdesignicons/_icons.scss new file mode 100644 index 0000000000..1da1eb7983 --- /dev/null +++ b/themes/helm/assets/sass/materialdesignicons/_icons.scss @@ -0,0 +1,10 @@ +@each $key, $value in $mdi-icons { + .#{$mdi-css-prefix}-#{$key}::before { + content: char($value); + } +} + +.#{$mdi-css-prefix}-blank::before { + content: "\F68C"; + visibility: hidden; +} \ No newline at end of file diff --git a/themes/helm/assets/sass/materialdesignicons/_path.scss b/themes/helm/assets/sass/materialdesignicons/_path.scss new file mode 100644 index 0000000000..6dcf3aa080 --- /dev/null +++ b/themes/helm/assets/sass/materialdesignicons/_path.scss @@ -0,0 +1,10 @@ +@font-face { + font-family: '#{$mdi-font-name}'; + src: url('#{$mdi-font-path}/#{$mdi-filename}-webfont.eot?v=#{$mdi-version}'); + src: url('#{$mdi-font-path}/#{$mdi-filename}-webfont.eot?#iefix&v=#{$mdi-version}') format('embedded-opentype'), + url('#{$mdi-font-path}/#{$mdi-filename}-webfont.woff2?v=#{$mdi-version}') format('woff2'), + url('#{$mdi-font-path}/#{$mdi-filename}-webfont.woff?v=#{$mdi-version}') format('woff'), + url('#{$mdi-font-path}/#{$mdi-filename}-webfont.ttf?v=#{$mdi-version}') format('truetype'); + font-weight: normal; + font-style: normal; +} diff --git a/themes/helm/assets/sass/materialdesignicons/_variables.scss b/themes/helm/assets/sass/materialdesignicons/_variables.scss new file mode 100644 index 0000000000..af4c16c8e3 --- /dev/null +++ b/themes/helm/assets/sass/materialdesignicons/_variables.scss @@ -0,0 +1,4906 @@ +$mdi-filename: "materialdesignicons"; +$mdi-font-name: "Material Design Icons"; +$mdi-font-family: "materialdesignicons"; +$mdi-font-weight: "normal"; +$mdi-font-path: "../fonts" !default; +$mdi-font-size-base: 24px !default; +$mdi-css-prefix: mdi !default; +$mdi-version: "4.8.95" !default; + +$mdi-icons: ( + "ab-testing": F001C, + "access-point": F002, + "access-point-network": F003, + "access-point-network-off": FBBD, + "account": F004, + "account-alert": F005, + "account-alert-outline": FB2C, + "account-arrow-left": FB2D, + "account-arrow-left-outline": FB2E, + "account-arrow-right": FB2F, + "account-arrow-right-outline": FB30, + "account-badge": FD83, + "account-badge-alert": FD84, + "account-badge-alert-outline": FD85, + "account-badge-horizontal": FDF0, + "account-badge-horizontal-outline": FDF1, + "account-badge-outline": FD86, + "account-box": F006, + "account-box-multiple": F933, + "account-box-multiple-outline": F002C, + "account-box-outline": F007, + "account-cancel": F030A, + "account-cancel-outline": F030B, + "account-card-details": F5D2, + "account-card-details-outline": FD87, + "account-cash": F00C2, + "account-cash-outline": F00C3, + "account-check": F008, + "account-check-outline": FBBE, + "account-child": FA88, + "account-child-circle": FA89, + "account-child-outline": F00F3, + "account-circle": F009, + "account-circle-outline": FB31, + "account-clock": FB32, + "account-clock-outline": FB33, + "account-convert": F00A, + "account-convert-outline": F032C, + "account-details": F631, + "account-edit": F6BB, + "account-edit-outline": F001D, + "account-group": F848, + "account-group-outline": FB34, + "account-heart": F898, + "account-heart-outline": FBBF, + "account-key": F00B, + "account-key-outline": FBC0, + "account-lock": F0189, + "account-lock-outline": F018A, + "account-minus": F00D, + "account-minus-outline": FAEB, + "account-multiple": F00E, + "account-multiple-check": F8C4, + "account-multiple-check-outline": F0229, + "account-multiple-minus": F5D3, + "account-multiple-minus-outline": FBC1, + "account-multiple-outline": F00F, + "account-multiple-plus": F010, + "account-multiple-plus-outline": F7FF, + "account-multiple-remove": F0235, + "account-multiple-remove-outline": F0236, + "account-network": F011, + "account-network-outline": FBC2, + "account-off": F012, + "account-off-outline": FBC3, + "account-outline": F013, + "account-plus": F014, + "account-plus-outline": F800, + "account-question": FB35, + "account-question-outline": FB36, + "account-remove": F015, + "account-remove-outline": FAEC, + "account-search": F016, + "account-search-outline": F934, + "account-settings": F630, + "account-settings-outline": F00F4, + "account-star": F017, + "account-star-outline": FBC4, + "account-supervisor": FA8A, + "account-supervisor-circle": FA8B, + "account-supervisor-outline": F0158, + "account-switch": F019, + "account-tie": FCBF, + "account-tie-outline": F00F5, + "account-tie-voice": F0333, + "account-tie-voice-off": F0335, + "account-tie-voice-off-outline": F0336, + "account-tie-voice-outline": F0334, + "accusoft": F849, + "adjust": F01A, + "adobe": F935, + "adobe-acrobat": FFBD, + "air-conditioner": F01B, + "air-filter": FD1F, + "air-horn": FD88, + "air-humidifier": F00C4, + "air-purifier": FD20, + "airbag": FBC5, + "airballoon": F01C, + "airballoon-outline": F002D, + "airplane": F01D, + "airplane-landing": F5D4, + "airplane-off": F01E, + "airplane-takeoff": F5D5, + "airplay": F01F, + "airport": F84A, + "alarm": F020, + "alarm-bell": F78D, + "alarm-check": F021, + "alarm-light": F78E, + "alarm-light-outline": FBC6, + "alarm-multiple": F022, + "alarm-note": FE8E, + "alarm-note-off": FE8F, + "alarm-off": F023, + "alarm-plus": F024, + "alarm-snooze": F68D, + "album": F025, + "alert": F026, + "alert-box": F027, + "alert-box-outline": FCC0, + "alert-circle": F028, + "alert-circle-check": F0218, + "alert-circle-check-outline": F0219, + "alert-circle-outline": F5D6, + "alert-decagram": F6BC, + "alert-decagram-outline": FCC1, + "alert-octagon": F029, + "alert-octagon-outline": FCC2, + "alert-octagram": F766, + "alert-octagram-outline": FCC3, + "alert-outline": F02A, + "alert-rhombus": F01F9, + "alert-rhombus-outline": F01FA, + "alien": F899, + "alien-outline": F00F6, + "align-horizontal-center": F01EE, + "align-horizontal-left": F01ED, + "align-horizontal-right": F01EF, + "align-vertical-bottom": F01F0, + "align-vertical-center": F01F1, + "align-vertical-top": F01F2, + "all-inclusive": F6BD, + "allergy": F0283, + "alpha": F02B, + "alpha-a": 0041, + "alpha-a-box": FAED, + "alpha-a-box-outline": FBC7, + "alpha-a-circle": FBC8, + "alpha-a-circle-outline": FBC9, + "alpha-b": 0042, + "alpha-b-box": FAEE, + "alpha-b-box-outline": FBCA, + "alpha-b-circle": FBCB, + "alpha-b-circle-outline": FBCC, + "alpha-c": 0043, + "alpha-c-box": FAEF, + "alpha-c-box-outline": FBCD, + "alpha-c-circle": FBCE, + "alpha-c-circle-outline": FBCF, + "alpha-d": 0044, + "alpha-d-box": FAF0, + "alpha-d-box-outline": FBD0, + "alpha-d-circle": FBD1, + "alpha-d-circle-outline": FBD2, + "alpha-e": 0045, + "alpha-e-box": FAF1, + "alpha-e-box-outline": FBD3, + "alpha-e-circle": FBD4, + "alpha-e-circle-outline": FBD5, + "alpha-f": 0046, + "alpha-f-box": FAF2, + "alpha-f-box-outline": FBD6, + "alpha-f-circle": FBD7, + "alpha-f-circle-outline": FBD8, + "alpha-g": 0047, + "alpha-g-box": FAF3, + "alpha-g-box-outline": FBD9, + "alpha-g-circle": FBDA, + "alpha-g-circle-outline": FBDB, + "alpha-h": 0048, + "alpha-h-box": FAF4, + "alpha-h-box-outline": FBDC, + "alpha-h-circle": FBDD, + "alpha-h-circle-outline": FBDE, + "alpha-i": 0049, + "alpha-i-box": FAF5, + "alpha-i-box-outline": FBDF, + "alpha-i-circle": FBE0, + "alpha-i-circle-outline": FBE1, + "alpha-j": 004A, + "alpha-j-box": FAF6, + "alpha-j-box-outline": FBE2, + "alpha-j-circle": FBE3, + "alpha-j-circle-outline": FBE4, + "alpha-k": 004B, + "alpha-k-box": FAF7, + "alpha-k-box-outline": FBE5, + "alpha-k-circle": FBE6, + "alpha-k-circle-outline": FBE7, + "alpha-l": 004C, + "alpha-l-box": FAF8, + "alpha-l-box-outline": FBE8, + "alpha-l-circle": FBE9, + "alpha-l-circle-outline": FBEA, + "alpha-m": 004D, + "alpha-m-box": FAF9, + "alpha-m-box-outline": FBEB, + "alpha-m-circle": FBEC, + "alpha-m-circle-outline": FBED, + "alpha-n": 004E, + "alpha-n-box": FAFA, + "alpha-n-box-outline": FBEE, + "alpha-n-circle": FBEF, + "alpha-n-circle-outline": FBF0, + "alpha-o": 004F, + "alpha-o-box": FAFB, + "alpha-o-box-outline": FBF1, + "alpha-o-circle": FBF2, + "alpha-o-circle-outline": FBF3, + "alpha-p": 0050, + "alpha-p-box": FAFC, + "alpha-p-box-outline": FBF4, + "alpha-p-circle": FBF5, + "alpha-p-circle-outline": FBF6, + "alpha-q": 0051, + "alpha-q-box": FAFD, + "alpha-q-box-outline": FBF7, + "alpha-q-circle": FBF8, + "alpha-q-circle-outline": FBF9, + "alpha-r": 0052, + "alpha-r-box": FAFE, + "alpha-r-box-outline": FBFA, + "alpha-r-circle": FBFB, + "alpha-r-circle-outline": FBFC, + "alpha-s": 0053, + "alpha-s-box": FAFF, + "alpha-s-box-outline": FBFD, + "alpha-s-circle": FBFE, + "alpha-s-circle-outline": FBFF, + "alpha-t": 0054, + "alpha-t-box": FB00, + "alpha-t-box-outline": FC00, + "alpha-t-circle": FC01, + "alpha-t-circle-outline": FC02, + "alpha-u": 0055, + "alpha-u-box": FB01, + "alpha-u-box-outline": FC03, + "alpha-u-circle": FC04, + "alpha-u-circle-outline": FC05, + "alpha-v": 0056, + "alpha-v-box": FB02, + "alpha-v-box-outline": FC06, + "alpha-v-circle": FC07, + "alpha-v-circle-outline": FC08, + "alpha-w": 0057, + "alpha-w-box": FB03, + "alpha-w-box-outline": FC09, + "alpha-w-circle": FC0A, + "alpha-w-circle-outline": FC0B, + "alpha-x": 0058, + "alpha-x-box": FB04, + "alpha-x-box-outline": FC0C, + "alpha-x-circle": FC0D, + "alpha-x-circle-outline": FC0E, + "alpha-y": 0059, + "alpha-y-box": FB05, + "alpha-y-box-outline": FC0F, + "alpha-y-circle": FC10, + "alpha-y-circle-outline": FC11, + "alpha-z": 005A, + "alpha-z-box": FB06, + "alpha-z-box-outline": FC12, + "alpha-z-circle": FC13, + "alpha-z-circle-outline": FC14, + "alphabetical": F02C, + "alphabetical-off": F002E, + "alphabetical-variant": F002F, + "alphabetical-variant-off": F0030, + "altimeter": F5D7, + "amazon": F02D, + "amazon-alexa": F8C5, + "amazon-drive": F02E, + "ambulance": F02F, + "ammunition": FCC4, + "ampersand": FA8C, + "amplifier": F030, + "amplifier-off": F01E0, + "anchor": F031, + "android": F032, + "android-auto": FA8D, + "android-debug-bridge": F033, + "android-head": F78F, + "android-messages": FD21, + "android-studio": F034, + "angle-acute": F936, + "angle-obtuse": F937, + "angle-right": F938, + "angular": F6B1, + "angularjs": F6BE, + "animation": F5D8, + "animation-outline": FA8E, + "animation-play": F939, + "animation-play-outline": FA8F, + "ansible": F00C5, + "antenna": F0144, + "anvil": F89A, + "apache-kafka": F0031, + "api": F00C6, + "api-off": F0282, + "apple": F035, + "apple-finder": F036, + "apple-icloud": F038, + "apple-ios": F037, + "apple-keyboard-caps": F632, + "apple-keyboard-command": F633, + "apple-keyboard-control": F634, + "apple-keyboard-option": F635, + "apple-keyboard-shift": F636, + "apple-safari": F039, + "application": F614, + "application-export": FD89, + "application-import": FD8A, + "approximately-equal": FFBE, + "approximately-equal-box": FFBF, + "apps": F03B, + "apps-box": FD22, + "arch": F8C6, + "archive": F03C, + "archive-arrow-down": F0284, + "archive-arrow-down-outline": F0285, + "archive-arrow-up": F0286, + "archive-arrow-up-outline": F0287, + "archive-outline": F0239, + "arm-flex": F008F, + "arm-flex-outline": F0090, + "arrange-bring-forward": F03D, + "arrange-bring-to-front": F03E, + "arrange-send-backward": F03F, + "arrange-send-to-back": F040, + "arrow-all": F041, + "arrow-bottom-left": F042, + "arrow-bottom-left-bold-outline": F9B6, + "arrow-bottom-left-thick": F9B7, + "arrow-bottom-right": F043, + "arrow-bottom-right-bold-outline": F9B8, + "arrow-bottom-right-thick": F9B9, + "arrow-collapse": F615, + "arrow-collapse-all": F044, + "arrow-collapse-down": F791, + "arrow-collapse-horizontal": F84B, + "arrow-collapse-left": F792, + "arrow-collapse-right": F793, + "arrow-collapse-up": F794, + "arrow-collapse-vertical": F84C, + "arrow-decision": F9BA, + "arrow-decision-auto": F9BB, + "arrow-decision-auto-outline": F9BC, + "arrow-decision-outline": F9BD, + "arrow-down": F045, + "arrow-down-bold": F72D, + "arrow-down-bold-box": F72E, + "arrow-down-bold-box-outline": F72F, + "arrow-down-bold-circle": F047, + "arrow-down-bold-circle-outline": F048, + "arrow-down-bold-hexagon-outline": F049, + "arrow-down-bold-outline": F9BE, + "arrow-down-box": F6BF, + "arrow-down-circle": FCB7, + "arrow-down-circle-outline": FCB8, + "arrow-down-drop-circle": F04A, + "arrow-down-drop-circle-outline": F04B, + "arrow-down-thick": F046, + "arrow-expand": F616, + "arrow-expand-all": F04C, + "arrow-expand-down": F795, + "arrow-expand-horizontal": F84D, + "arrow-expand-left": F796, + "arrow-expand-right": F797, + "arrow-expand-up": F798, + "arrow-expand-vertical": F84E, + "arrow-horizontal-lock": F0186, + "arrow-left": F04D, + "arrow-left-bold": F730, + "arrow-left-bold-box": F731, + "arrow-left-bold-box-outline": F732, + "arrow-left-bold-circle": F04F, + "arrow-left-bold-circle-outline": F050, + "arrow-left-bold-hexagon-outline": F051, + "arrow-left-bold-outline": F9BF, + "arrow-left-box": F6C0, + "arrow-left-circle": FCB9, + "arrow-left-circle-outline": FCBA, + "arrow-left-drop-circle": F052, + "arrow-left-drop-circle-outline": F053, + "arrow-left-right": FE90, + "arrow-left-right-bold": FE91, + "arrow-left-right-bold-outline": F9C0, + "arrow-left-thick": F04E, + "arrow-right": F054, + "arrow-right-bold": F733, + "arrow-right-bold-box": F734, + "arrow-right-bold-box-outline": F735, + "arrow-right-bold-circle": F056, + "arrow-right-bold-circle-outline": F057, + "arrow-right-bold-hexagon-outline": F058, + "arrow-right-bold-outline": F9C1, + "arrow-right-box": F6C1, + "arrow-right-circle": FCBB, + "arrow-right-circle-outline": FCBC, + "arrow-right-drop-circle": F059, + "arrow-right-drop-circle-outline": F05A, + "arrow-right-thick": F055, + "arrow-split-horizontal": F93A, + "arrow-split-vertical": F93B, + "arrow-top-left": F05B, + "arrow-top-left-bold-outline": F9C2, + "arrow-top-left-bottom-right": FE92, + "arrow-top-left-bottom-right-bold": FE93, + "arrow-top-left-thick": F9C3, + "arrow-top-right": F05C, + "arrow-top-right-bold-outline": F9C4, + "arrow-top-right-bottom-left": FE94, + "arrow-top-right-bottom-left-bold": FE95, + "arrow-top-right-thick": F9C5, + "arrow-up": F05D, + "arrow-up-bold": F736, + "arrow-up-bold-box": F737, + "arrow-up-bold-box-outline": F738, + "arrow-up-bold-circle": F05F, + "arrow-up-bold-circle-outline": F060, + "arrow-up-bold-hexagon-outline": F061, + "arrow-up-bold-outline": F9C6, + "arrow-up-box": F6C2, + "arrow-up-circle": FCBD, + "arrow-up-circle-outline": FCBE, + "arrow-up-down": FE96, + "arrow-up-down-bold": FE97, + "arrow-up-down-bold-outline": F9C7, + "arrow-up-drop-circle": F062, + "arrow-up-drop-circle-outline": F063, + "arrow-up-thick": F05E, + "arrow-vertical-lock": F0187, + "artist": F802, + "artist-outline": FCC5, + "artstation": FB37, + "aspect-ratio": FA23, + "assistant": F064, + "asterisk": F6C3, + "at": F065, + "atlassian": F803, + "atm": FD23, + "atom": F767, + "atom-variant": FE98, + "attachment": F066, + "audio-video": F93C, + "audio-video-off": F01E1, + "audiobook": F067, + "augmented-reality": F84F, + "auto-fix": F068, + "auto-upload": F069, + "autorenew": F06A, + "av-timer": F06B, + "aws": FDF2, + "axe": F8C7, + "axis": FD24, + "axis-arrow": FD25, + "axis-arrow-lock": FD26, + "axis-lock": FD27, + "axis-x-arrow": FD28, + "axis-x-arrow-lock": FD29, + "axis-x-rotate-clockwise": FD2A, + "axis-x-rotate-counterclockwise": FD2B, + "axis-x-y-arrow-lock": FD2C, + "axis-y-arrow": FD2D, + "axis-y-arrow-lock": FD2E, + "axis-y-rotate-clockwise": FD2F, + "axis-y-rotate-counterclockwise": FD30, + "axis-z-arrow": FD31, + "axis-z-arrow-lock": FD32, + "axis-z-rotate-clockwise": FD33, + "axis-z-rotate-counterclockwise": FD34, + "azure": F804, + "azure-devops": F0091, + "babel": FA24, + "baby": F06C, + "baby-bottle": FF56, + "baby-bottle-outline": FF57, + "baby-carriage": F68E, + "baby-carriage-off": FFC0, + "baby-face": FE99, + "baby-face-outline": FE9A, + "backburger": F06D, + "backspace": F06E, + "backspace-outline": FB38, + "backspace-reverse": FE9B, + "backspace-reverse-outline": FE9C, + "backup-restore": F06F, + "bacteria": FEF2, + "bacteria-outline": FEF3, + "badminton": F850, + "bag-carry-on": FF58, + "bag-carry-on-check": FD41, + "bag-carry-on-off": FF59, + "bag-checked": FF5A, + "bag-personal": FDF3, + "bag-personal-off": FDF4, + "bag-personal-off-outline": FDF5, + "bag-personal-outline": FDF6, + "baguette": FF5B, + "balloon": FA25, + "ballot": F9C8, + "ballot-outline": F9C9, + "ballot-recount": FC15, + "ballot-recount-outline": FC16, + "bandage": FD8B, + "bandcamp": F674, + "bank": F070, + "bank-minus": FD8C, + "bank-outline": FE9D, + "bank-plus": FD8D, + "bank-remove": FD8E, + "bank-transfer": FA26, + "bank-transfer-in": FA27, + "bank-transfer-out": FA28, + "barcode": F071, + "barcode-off": F0261, + "barcode-scan": F072, + "barley": F073, + "barley-off": FB39, + "barn": FB3A, + "barrel": F074, + "baseball": F851, + "baseball-bat": F852, + "basecamp": F075, + "bash": F01AE, + "basket": F076, + "basket-fill": F077, + "basket-outline": F01AC, + "basket-unfill": F078, + "basketball": F805, + "basketball-hoop": FC17, + "basketball-hoop-outline": FC18, + "bat": FB3B, + "battery": F079, + "battery-10": F07A, + "battery-10-bluetooth": F93D, + "battery-20": F07B, + "battery-20-bluetooth": F93E, + "battery-30": F07C, + "battery-30-bluetooth": F93F, + "battery-40": F07D, + "battery-40-bluetooth": F940, + "battery-50": F07E, + "battery-50-bluetooth": F941, + "battery-60": F07F, + "battery-60-bluetooth": F942, + "battery-70": F080, + "battery-70-bluetooth": F943, + "battery-80": F081, + "battery-80-bluetooth": F944, + "battery-90": F082, + "battery-90-bluetooth": F945, + "battery-alert": F083, + "battery-alert-bluetooth": F946, + "battery-alert-variant": F00F7, + "battery-alert-variant-outline": F00F8, + "battery-bluetooth": F947, + "battery-bluetooth-variant": F948, + "battery-charging": F084, + "battery-charging-10": F89B, + "battery-charging-100": F085, + "battery-charging-20": F086, + "battery-charging-30": F087, + "battery-charging-40": F088, + "battery-charging-50": F89C, + "battery-charging-60": F089, + "battery-charging-70": F89D, + "battery-charging-80": F08A, + "battery-charging-90": F08B, + "battery-charging-high": F02D1, + "battery-charging-low": F02CF, + "battery-charging-medium": F02D0, + "battery-charging-outline": F89E, + "battery-charging-wireless": F806, + "battery-charging-wireless-10": F807, + "battery-charging-wireless-20": F808, + "battery-charging-wireless-30": F809, + "battery-charging-wireless-40": F80A, + "battery-charging-wireless-50": F80B, + "battery-charging-wireless-60": F80C, + "battery-charging-wireless-70": F80D, + "battery-charging-wireless-80": F80E, + "battery-charging-wireless-90": F80F, + "battery-charging-wireless-alert": F810, + "battery-charging-wireless-outline": F811, + "battery-heart": F023A, + "battery-heart-outline": F023B, + "battery-heart-variant": F023C, + "battery-high": F02CE, + "battery-low": F02CC, + "battery-medium": F02CD, + "battery-minus": F08C, + "battery-negative": F08D, + "battery-off": F0288, + "battery-off-outline": F0289, + "battery-outline": F08E, + "battery-plus": F08F, + "battery-positive": F090, + "battery-unknown": F091, + "battery-unknown-bluetooth": F949, + "battlenet": FB3C, + "beach": F092, + "beaker": FCC6, + "beaker-alert": F0254, + "beaker-alert-outline": F0255, + "beaker-check": F0256, + "beaker-check-outline": F0257, + "beaker-minus": F0258, + "beaker-minus-outline": F0259, + "beaker-outline": F68F, + "beaker-plus": F025A, + "beaker-plus-outline": F025B, + "beaker-question": F025C, + "beaker-question-outline": F025D, + "beaker-remove": F025E, + "beaker-remove-outline": F025F, + "beats": F097, + "bed-double": F0092, + "bed-double-outline": F0093, + "bed-empty": F89F, + "bed-king": F0094, + "bed-king-outline": F0095, + "bed-queen": F0096, + "bed-queen-outline": F0097, + "bed-single": F0098, + "bed-single-outline": F0099, + "bee": FFC1, + "bee-flower": FFC2, + "beehive-outline": F00F9, + "beer": F098, + "beer-outline": F0337, + "behance": F099, + "bell": F09A, + "bell-alert": FD35, + "bell-alert-outline": FE9E, + "bell-check": F0210, + "bell-check-outline": F0211, + "bell-circle": FD36, + "bell-circle-outline": FD37, + "bell-off": F09B, + "bell-off-outline": FA90, + "bell-outline": F09C, + "bell-plus": F09D, + "bell-plus-outline": FA91, + "bell-ring": F09E, + "bell-ring-outline": F09F, + "bell-sleep": F0A0, + "bell-sleep-outline": FA92, + "beta": F0A1, + "betamax": F9CA, + "biathlon": FDF7, + "bible": F0A2, + "bicycle": F00C7, + "bicycle-basket": F0260, + "bike": F0A3, + "bike-fast": F014A, + "billboard": F0032, + "billiards": FB3D, + "billiards-rack": FB3E, + "bing": F0A4, + "binoculars": F0A5, + "bio": F0A6, + "biohazard": F0A7, + "bitbucket": F0A8, + "bitcoin": F812, + "black-mesa": F0A9, + "blackberry": F0AA, + "blender": FCC7, + "blender-software": F0AB, + "blinds": F0AC, + "blinds-open": F0033, + "block-helper": F0AD, + "blogger": F0AE, + "blood-bag": FCC8, + "bluetooth": F0AF, + "bluetooth-audio": F0B0, + "bluetooth-connect": F0B1, + "bluetooth-off": F0B2, + "bluetooth-settings": F0B3, + "bluetooth-transfer": F0B4, + "blur": F0B5, + "blur-linear": F0B6, + "blur-off": F0B7, + "blur-radial": F0B8, + "bolnisi-cross": FCC9, + "bolt": FD8F, + "bomb": F690, + "bomb-off": F6C4, + "bone": F0B9, + "book": F0BA, + "book-information-variant": F009A, + "book-lock": F799, + "book-lock-open": F79A, + "book-minus": F5D9, + "book-minus-multiple": FA93, + "book-multiple": F0BB, + "book-open": F0BD, + "book-open-outline": FB3F, + "book-open-page-variant": F5DA, + "book-open-variant": F0BE, + "book-outline": FB40, + "book-play": FE9F, + "book-play-outline": FEA0, + "book-plus": F5DB, + "book-plus-multiple": FA94, + "book-remove": FA96, + "book-remove-multiple": FA95, + "book-search": FEA1, + "book-search-outline": FEA2, + "book-variant": F0BF, + "book-variant-multiple": F0BC, + "bookmark": F0C0, + "bookmark-check": F0C1, + "bookmark-minus": F9CB, + "bookmark-minus-outline": F9CC, + "bookmark-multiple": FDF8, + "bookmark-multiple-outline": FDF9, + "bookmark-music": F0C2, + "bookmark-off": F9CD, + "bookmark-off-outline": F9CE, + "bookmark-outline": F0C3, + "bookmark-plus": F0C5, + "bookmark-plus-outline": F0C4, + "bookmark-remove": F0C6, + "bookshelf": F028A, + "boom-gate": FEA3, + "boom-gate-alert": FEA4, + "boom-gate-alert-outline": FEA5, + "boom-gate-down": FEA6, + "boom-gate-down-outline": FEA7, + "boom-gate-outline": FEA8, + "boom-gate-up": FEA9, + "boom-gate-up-outline": FEAA, + "boombox": F5DC, + "boomerang": F00FA, + "bootstrap": F6C5, + "border-all": F0C7, + "border-all-variant": F8A0, + "border-bottom": F0C8, + "border-bottom-variant": F8A1, + "border-color": F0C9, + "border-horizontal": F0CA, + "border-inside": F0CB, + "border-left": F0CC, + "border-left-variant": F8A2, + "border-none": F0CD, + "border-none-variant": F8A3, + "border-outside": F0CE, + "border-right": F0CF, + "border-right-variant": F8A4, + "border-style": F0D0, + "border-top": F0D1, + "border-top-variant": F8A5, + "border-vertical": F0D2, + "bottle-soda": F009B, + "bottle-soda-classic": F009C, + "bottle-soda-outline": F009D, + "bottle-tonic": F0159, + "bottle-tonic-outline": F015A, + "bottle-tonic-plus": F015B, + "bottle-tonic-plus-outline": F015C, + "bottle-tonic-skull": F015D, + "bottle-tonic-skull-outline": F015E, + "bottle-wine": F853, + "bottle-wine-outline": F033B, + "bow-tie": F677, + "bowl": F617, + "bowling": F0D3, + "box": F0D4, + "box-cutter": F0D5, + "box-shadow": F637, + "boxing-glove": FB41, + "braille": F9CF, + "brain": F9D0, + "bread-slice": FCCA, + "bread-slice-outline": FCCB, + "bridge": F618, + "briefcase": F0D6, + "briefcase-account": FCCC, + "briefcase-account-outline": FCCD, + "briefcase-check": F0D7, + "briefcase-check-outline": F0349, + "briefcase-clock": F00FB, + "briefcase-clock-outline": F00FC, + "briefcase-download": F0D8, + "briefcase-download-outline": FC19, + "briefcase-edit": FA97, + "briefcase-edit-outline": FC1A, + "briefcase-minus": FA29, + "briefcase-minus-outline": FC1B, + "briefcase-outline": F813, + "briefcase-plus": FA2A, + "briefcase-plus-outline": FC1C, + "briefcase-remove": FA2B, + "briefcase-remove-outline": FC1D, + "briefcase-search": FA2C, + "briefcase-search-outline": FC1E, + "briefcase-upload": F0D9, + "briefcase-upload-outline": FC1F, + "brightness-1": F0DA, + "brightness-2": F0DB, + "brightness-3": F0DC, + "brightness-4": F0DD, + "brightness-5": F0DE, + "brightness-6": F0DF, + "brightness-7": F0E0, + "brightness-auto": F0E1, + "brightness-percent": FCCE, + "broom": F0E2, + "brush": F0E3, + "buddhism": F94A, + "buffer": F619, + "bug": F0E4, + "bug-check": FA2D, + "bug-check-outline": FA2E, + "bug-outline": FA2F, + "bugle": FD90, + "bulldozer": FB07, + "bullet": FCCF, + "bulletin-board": F0E5, + "bullhorn": F0E6, + "bullhorn-outline": FB08, + "bullseye": F5DD, + "bullseye-arrow": F8C8, + "bulma": F0312, + "bunk-bed": F032D, + "bus": F0E7, + "bus-alert": FA98, + "bus-articulated-end": F79B, + "bus-articulated-front": F79C, + "bus-clock": F8C9, + "bus-double-decker": F79D, + "bus-marker": F023D, + "bus-multiple": FF5C, + "bus-school": F79E, + "bus-side": F79F, + "bus-stop": F0034, + "bus-stop-covered": F0035, + "bus-stop-uncovered": F0036, + "cached": F0E8, + "cactus": FD91, + "cake": F0E9, + "cake-layered": F0EA, + "cake-variant": F0EB, + "calculator": F0EC, + "calculator-variant": FA99, + "calendar": F0ED, + "calendar-account": FEF4, + "calendar-account-outline": FEF5, + "calendar-alert": FA30, + "calendar-arrow-left": F015F, + "calendar-arrow-right": F0160, + "calendar-blank": F0EE, + "calendar-blank-multiple": F009E, + "calendar-blank-outline": FB42, + "calendar-check": F0EF, + "calendar-check-outline": FC20, + "calendar-clock": F0F0, + "calendar-edit": F8A6, + "calendar-export": FB09, + "calendar-heart": F9D1, + "calendar-import": FB0A, + "calendar-minus": FD38, + "calendar-month": FDFA, + "calendar-month-outline": FDFB, + "calendar-multiple": F0F1, + "calendar-multiple-check": F0F2, + "calendar-multiselect": FA31, + "calendar-outline": FB43, + "calendar-plus": F0F3, + "calendar-question": F691, + "calendar-range": F678, + "calendar-range-outline": FB44, + "calendar-remove": F0F4, + "calendar-remove-outline": FC21, + "calendar-repeat": FEAB, + "calendar-repeat-outline": FEAC, + "calendar-search": F94B, + "calendar-star": F9D2, + "calendar-text": F0F5, + "calendar-text-outline": FC22, + "calendar-today": F0F6, + "calendar-week": FA32, + "calendar-week-begin": FA33, + "calendar-weekend": FEF6, + "calendar-weekend-outline": FEF7, + "call-made": F0F7, + "call-merge": F0F8, + "call-missed": F0F9, + "call-received": F0FA, + "call-split": F0FB, + "camcorder": F0FC, + "camcorder-box": F0FD, + "camcorder-box-off": F0FE, + "camcorder-off": F0FF, + "camera": F100, + "camera-account": F8CA, + "camera-burst": F692, + "camera-control": FB45, + "camera-enhance": F101, + "camera-enhance-outline": FB46, + "camera-front": F102, + "camera-front-variant": F103, + "camera-gopro": F7A0, + "camera-image": F8CB, + "camera-iris": F104, + "camera-metering-center": F7A1, + "camera-metering-matrix": F7A2, + "camera-metering-partial": F7A3, + "camera-metering-spot": F7A4, + "camera-off": F5DF, + "camera-outline": FD39, + "camera-party-mode": F105, + "camera-plus": FEF8, + "camera-plus-outline": FEF9, + "camera-rear": F106, + "camera-rear-variant": F107, + "camera-retake": FDFC, + "camera-retake-outline": FDFD, + "camera-switch": F108, + "camera-timer": F109, + "camera-wireless": FD92, + "camera-wireless-outline": FD93, + "campfire": FEFA, + "cancel": F739, + "candle": F5E2, + "candycane": F10A, + "cannabis": F7A5, + "caps-lock": FA9A, + "car": F10B, + "car-2-plus": F0037, + "car-3-plus": F0038, + "car-back": FDFE, + "car-battery": F10C, + "car-brake-abs": FC23, + "car-brake-alert": FC24, + "car-brake-hold": FD3A, + "car-brake-parking": FD3B, + "car-brake-retarder": F0039, + "car-child-seat": FFC3, + "car-clutch": F003A, + "car-connected": F10D, + "car-convertible": F7A6, + "car-coolant-level": F003B, + "car-cruise-control": FD3C, + "car-defrost-front": FD3D, + "car-defrost-rear": FD3E, + "car-door": FB47, + "car-door-lock": F00C8, + "car-electric": FB48, + "car-esp": FC25, + "car-estate": F7A7, + "car-hatchback": F7A8, + "car-info": F01E9, + "car-key": FB49, + "car-light-dimmed": FC26, + "car-light-fog": FC27, + "car-light-high": FC28, + "car-limousine": F8CC, + "car-multiple": FB4A, + "car-off": FDFF, + "car-parking-lights": FD3F, + "car-pickup": F7A9, + "car-seat": FFC4, + "car-seat-cooler": FFC5, + "car-seat-heater": FFC6, + "car-shift-pattern": FF5D, + "car-side": F7AA, + "car-sports": F7AB, + "car-tire-alert": FC29, + "car-traction-control": FD40, + "car-turbocharger": F003C, + "car-wash": F10E, + "car-windshield": F003D, + "car-windshield-outline": F003E, + "caravan": F7AC, + "card": FB4B, + "card-bulleted": FB4C, + "card-bulleted-off": FB4D, + "card-bulleted-off-outline": FB4E, + "card-bulleted-outline": FB4F, + "card-bulleted-settings": FB50, + "card-bulleted-settings-outline": FB51, + "card-outline": FB52, + "card-plus": F022A, + "card-plus-outline": F022B, + "card-search": F009F, + "card-search-outline": F00A0, + "card-text": FB53, + "card-text-outline": FB54, + "cards": F638, + "cards-club": F8CD, + "cards-diamond": F8CE, + "cards-diamond-outline": F003F, + "cards-heart": F8CF, + "cards-outline": F639, + "cards-playing-outline": F63A, + "cards-spade": F8D0, + "cards-variant": F6C6, + "carrot": F10F, + "cart": F110, + "cart-arrow-down": FD42, + "cart-arrow-right": FC2A, + "cart-arrow-up": FD43, + "cart-minus": FD44, + "cart-off": F66B, + "cart-outline": F111, + "cart-plus": F112, + "cart-remove": FD45, + "case-sensitive-alt": F113, + "cash": F114, + "cash-100": F115, + "cash-marker": FD94, + "cash-minus": F028B, + "cash-multiple": F116, + "cash-plus": F028C, + "cash-refund": FA9B, + "cash-register": FCD0, + "cash-remove": F028D, + "cash-usd": F01A1, + "cash-usd-outline": F117, + "cassette": F9D3, + "cast": F118, + "cast-audio": F0040, + "cast-connected": F119, + "cast-education": FE6D, + "cast-off": F789, + "castle": F11A, + "cat": F11B, + "cctv": F7AD, + "ceiling-light": F768, + "cellphone": F11C, + "cellphone-android": F11D, + "cellphone-arrow-down": F9D4, + "cellphone-basic": F11E, + "cellphone-dock": F11F, + "cellphone-erase": F94C, + "cellphone-information": FF5E, + "cellphone-iphone": F120, + "cellphone-key": F94D, + "cellphone-link": F121, + "cellphone-link-off": F122, + "cellphone-lock": F94E, + "cellphone-message": F8D2, + "cellphone-message-off": F00FD, + "cellphone-nfc": FEAD, + "cellphone-nfc-off": F0303, + "cellphone-off": F94F, + "cellphone-play": F0041, + "cellphone-screenshot": FA34, + "cellphone-settings": F123, + "cellphone-settings-variant": F950, + "cellphone-sound": F951, + "cellphone-text": F8D1, + "cellphone-wireless": F814, + "celtic-cross": FCD1, + "centos": F0145, + "certificate": F124, + "certificate-outline": F01B3, + "chair-rolling": FFBA, + "chair-school": F125, + "charity": FC2B, + "chart-arc": F126, + "chart-areaspline": F127, + "chart-areaspline-variant": FEAE, + "chart-bar": F128, + "chart-bar-stacked": F769, + "chart-bell-curve": FC2C, + "chart-bell-curve-cumulative": FFC7, + "chart-bubble": F5E3, + "chart-donut": F7AE, + "chart-donut-variant": F7AF, + "chart-gantt": F66C, + "chart-histogram": F129, + "chart-line": F12A, + "chart-line-stacked": F76A, + "chart-line-variant": F7B0, + "chart-multiline": F8D3, + "chart-multiple": F023E, + "chart-pie": F12B, + "chart-scatter-plot": FEAF, + "chart-scatter-plot-hexbin": F66D, + "chart-snakey": F020A, + "chart-snakey-variant": F020B, + "chart-timeline": F66E, + "chart-timeline-variant": FEB0, + "chart-tree": FEB1, + "chat": FB55, + "chat-alert": FB56, + "chat-alert-outline": F02F4, + "chat-outline": FEFB, + "chat-processing": FB57, + "chat-processing-outline": F02F5, + "chat-sleep": F02FC, + "chat-sleep-outline": F02FD, + "check": F12C, + "check-all": F12D, + "check-bold": FE6E, + "check-box-multiple-outline": FC2D, + "check-box-outline": FC2E, + "check-circle": F5E0, + "check-circle-outline": F5E1, + "check-decagram": F790, + "check-network": FC2F, + "check-network-outline": FC30, + "check-outline": F854, + "check-underline": FE70, + "check-underline-circle": FE71, + "check-underline-circle-outline": FE72, + "checkbook": FA9C, + "checkbox-blank": F12E, + "checkbox-blank-circle": F12F, + "checkbox-blank-circle-outline": F130, + "checkbox-blank-off": F0317, + "checkbox-blank-off-outline": F0318, + "checkbox-blank-outline": F131, + "checkbox-intermediate": F855, + "checkbox-marked": F132, + "checkbox-marked-circle": F133, + "checkbox-marked-circle-outline": F134, + "checkbox-marked-outline": F135, + "checkbox-multiple-blank": F136, + "checkbox-multiple-blank-circle": F63B, + "checkbox-multiple-blank-circle-outline": F63C, + "checkbox-multiple-blank-outline": F137, + "checkbox-multiple-marked": F138, + "checkbox-multiple-marked-circle": F63D, + "checkbox-multiple-marked-circle-outline": F63E, + "checkbox-multiple-marked-outline": F139, + "checkerboard": F13A, + "checkerboard-minus": F022D, + "checkerboard-plus": F022C, + "checkerboard-remove": F022E, + "cheese": F02E4, + "chef-hat": FB58, + "chemical-weapon": F13B, + "chess-bishop": F85B, + "chess-king": F856, + "chess-knight": F857, + "chess-pawn": F858, + "chess-queen": F859, + "chess-rook": F85A, + "chevron-double-down": F13C, + "chevron-double-left": F13D, + "chevron-double-right": F13E, + "chevron-double-up": F13F, + "chevron-down": F140, + "chevron-down-box": F9D5, + "chevron-down-box-outline": F9D6, + "chevron-down-circle": FB0B, + "chevron-down-circle-outline": FB0C, + "chevron-left": F141, + "chevron-left-box": F9D7, + "chevron-left-box-outline": F9D8, + "chevron-left-circle": FB0D, + "chevron-left-circle-outline": FB0E, + "chevron-right": F142, + "chevron-right-box": F9D9, + "chevron-right-box-outline": F9DA, + "chevron-right-circle": FB0F, + "chevron-right-circle-outline": FB10, + "chevron-triple-down": FD95, + "chevron-triple-left": FD96, + "chevron-triple-right": FD97, + "chevron-triple-up": FD98, + "chevron-up": F143, + "chevron-up-box": F9DB, + "chevron-up-box-outline": F9DC, + "chevron-up-circle": FB11, + "chevron-up-circle-outline": FB12, + "chili-hot": F7B1, + "chili-medium": F7B2, + "chili-mild": F7B3, + "chip": F61A, + "christianity": F952, + "christianity-outline": FCD2, + "church": F144, + "cigar": F01B4, + "circle": F764, + "circle-double": FEB2, + "circle-edit-outline": F8D4, + "circle-expand": FEB3, + "circle-medium": F9DD, + "circle-off-outline": F00FE, + "circle-outline": F765, + "circle-slice-1": FA9D, + "circle-slice-2": FA9E, + "circle-slice-3": FA9F, + "circle-slice-4": FAA0, + "circle-slice-5": FAA1, + "circle-slice-6": FAA2, + "circle-slice-7": FAA3, + "circle-slice-8": FAA4, + "circle-small": F9DE, + "circular-saw": FE73, + "cisco-webex": F145, + "city": F146, + "city-variant": FA35, + "city-variant-outline": FA36, + "clipboard": F147, + "clipboard-account": F148, + "clipboard-account-outline": FC31, + "clipboard-alert": F149, + "clipboard-alert-outline": FCD3, + "clipboard-arrow-down": F14A, + "clipboard-arrow-down-outline": FC32, + "clipboard-arrow-left": F14B, + "clipboard-arrow-left-outline": FCD4, + "clipboard-arrow-right": FCD5, + "clipboard-arrow-right-outline": FCD6, + "clipboard-arrow-up": FC33, + "clipboard-arrow-up-outline": FC34, + "clipboard-check": F14C, + "clipboard-check-multiple": F028E, + "clipboard-check-multiple-outline": F028F, + "clipboard-check-outline": F8A7, + "clipboard-file": F0290, + "clipboard-file-outline": F0291, + "clipboard-flow": F6C7, + "clipboard-flow-outline": F0142, + "clipboard-list": F00FF, + "clipboard-list-outline": F0100, + "clipboard-multiple": F0292, + "clipboard-multiple-outline": F0293, + "clipboard-outline": F14D, + "clipboard-play": FC35, + "clipboard-play-multiple": F0294, + "clipboard-play-multiple-outline": F0295, + "clipboard-play-outline": FC36, + "clipboard-plus": F750, + "clipboard-plus-outline": F034A, + "clipboard-pulse": F85C, + "clipboard-pulse-outline": F85D, + "clipboard-text": F14E, + "clipboard-text-multiple": F0296, + "clipboard-text-multiple-outline": F0297, + "clipboard-text-outline": FA37, + "clipboard-text-play": FC37, + "clipboard-text-play-outline": FC38, + "clippy": F14F, + "clock": F953, + "clock-alert": F954, + "clock-alert-outline": F5CE, + "clock-check": FFC8, + "clock-check-outline": FFC9, + "clock-digital": FEB4, + "clock-end": F151, + "clock-fast": F152, + "clock-in": F153, + "clock-out": F154, + "clock-outline": F150, + "clock-start": F155, + "close": F156, + "close-box": F157, + "close-box-multiple": FC39, + "close-box-multiple-outline": FC3A, + "close-box-outline": F158, + "close-circle": F159, + "close-circle-outline": F15A, + "close-network": F15B, + "close-network-outline": FC3B, + "close-octagon": F15C, + "close-octagon-outline": F15D, + "close-outline": F6C8, + "closed-caption": F15E, + "closed-caption-outline": FD99, + "cloud": F15F, + "cloud-alert": F9DF, + "cloud-braces": F7B4, + "cloud-check": F160, + "cloud-check-outline": F02F7, + "cloud-circle": F161, + "cloud-download": F162, + "cloud-download-outline": FB59, + "cloud-lock": F021C, + "cloud-lock-outline": F021D, + "cloud-off-outline": F164, + "cloud-outline": F163, + "cloud-print": F165, + "cloud-print-outline": F166, + "cloud-question": FA38, + "cloud-search": F955, + "cloud-search-outline": F956, + "cloud-sync": F63F, + "cloud-sync-outline": F0301, + "cloud-tags": F7B5, + "cloud-upload": F167, + "cloud-upload-outline": FB5A, + "clover": F815, + "coach-lamp": F0042, + "coat-rack": F00C9, + "code-array": F168, + "code-braces": F169, + "code-braces-box": F0101, + "code-brackets": F16A, + "code-equal": F16B, + "code-greater-than": F16C, + "code-greater-than-or-equal": F16D, + "code-less-than": F16E, + "code-less-than-or-equal": F16F, + "code-not-equal": F170, + "code-not-equal-variant": F171, + "code-parentheses": F172, + "code-parentheses-box": F0102, + "code-string": F173, + "code-tags": F174, + "code-tags-check": F693, + "codepen": F175, + "coffee": F176, + "coffee-maker": F00CA, + "coffee-off": FFCA, + "coffee-off-outline": FFCB, + "coffee-outline": F6C9, + "coffee-to-go": F177, + "coffee-to-go-outline": F0339, + "coffin": FB5B, + "cog-clockwise": F0208, + "cog-counterclockwise": F0209, + "cogs": F8D5, + "coin": F0196, + "coin-outline": F178, + "coins": F694, + "collage": F640, + "collapse-all": FAA5, + "collapse-all-outline": FAA6, + "color-helper": F179, + "comma": FE74, + "comma-box": FE75, + "comma-box-outline": FE76, + "comma-circle": FE77, + "comma-circle-outline": FE78, + "comment": F17A, + "comment-account": F17B, + "comment-account-outline": F17C, + "comment-alert": F17D, + "comment-alert-outline": F17E, + "comment-arrow-left": F9E0, + "comment-arrow-left-outline": F9E1, + "comment-arrow-right": F9E2, + "comment-arrow-right-outline": F9E3, + "comment-check": F17F, + "comment-check-outline": F180, + "comment-edit": F01EA, + "comment-edit-outline": F02EF, + "comment-eye": FA39, + "comment-eye-outline": FA3A, + "comment-multiple": F85E, + "comment-multiple-outline": F181, + "comment-outline": F182, + "comment-plus": F9E4, + "comment-plus-outline": F183, + "comment-processing": F184, + "comment-processing-outline": F185, + "comment-question": F816, + "comment-question-outline": F186, + "comment-quote": F0043, + "comment-quote-outline": F0044, + "comment-remove": F5DE, + "comment-remove-outline": F187, + "comment-search": FA3B, + "comment-search-outline": FA3C, + "comment-text": F188, + "comment-text-multiple": F85F, + "comment-text-multiple-outline": F860, + "comment-text-outline": F189, + "compare": F18A, + "compass": F18B, + "compass-off": FB5C, + "compass-off-outline": FB5D, + "compass-outline": F18C, + "concourse-ci": F00CB, + "console": F18D, + "console-line": F7B6, + "console-network": F8A8, + "console-network-outline": FC3C, + "consolidate": F0103, + "contact-mail": F18E, + "contact-mail-outline": FEB5, + "contact-phone": FEB6, + "contact-phone-outline": FEB7, + "contactless-payment": FD46, + "contacts": F6CA, + "contain": FA3D, + "contain-end": FA3E, + "contain-start": FA3F, + "content-copy": F18F, + "content-cut": F190, + "content-duplicate": F191, + "content-paste": F192, + "content-save": F193, + "content-save-alert": FF5F, + "content-save-alert-outline": FF60, + "content-save-all": F194, + "content-save-all-outline": FF61, + "content-save-edit": FCD7, + "content-save-edit-outline": FCD8, + "content-save-move": FE79, + "content-save-move-outline": FE7A, + "content-save-outline": F817, + "content-save-settings": F61B, + "content-save-settings-outline": FB13, + "contrast": F195, + "contrast-box": F196, + "contrast-circle": F197, + "controller-classic": FB5E, + "controller-classic-outline": FB5F, + "cookie": F198, + "coolant-temperature": F3C8, + "copyright": F5E6, + "cordova": F957, + "corn": F7B7, + "counter": F199, + "cow": F19A, + "cowboy": FEB8, + "cpu-32-bit": FEFC, + "cpu-64-bit": FEFD, + "crane": F861, + "creation": F1C9, + "creative-commons": FD47, + "credit-card": F0010, + "credit-card-clock": FEFE, + "credit-card-clock-outline": FFBC, + "credit-card-marker": F6A7, + "credit-card-marker-outline": FD9A, + "credit-card-minus": FFCC, + "credit-card-minus-outline": FFCD, + "credit-card-multiple": F0011, + "credit-card-multiple-outline": F19C, + "credit-card-off": F0012, + "credit-card-off-outline": F5E4, + "credit-card-outline": F19B, + "credit-card-plus": F0013, + "credit-card-plus-outline": F675, + "credit-card-refund": F0014, + "credit-card-refund-outline": FAA7, + "credit-card-remove": FFCE, + "credit-card-remove-outline": FFCF, + "credit-card-scan": F0015, + "credit-card-scan-outline": F19D, + "credit-card-settings": F0016, + "credit-card-settings-outline": F8D6, + "credit-card-wireless": F801, + "credit-card-wireless-outline": FD48, + "cricket": FD49, + "crop": F19E, + "crop-free": F19F, + "crop-landscape": F1A0, + "crop-portrait": F1A1, + "crop-rotate": F695, + "crop-square": F1A2, + "crosshairs": F1A3, + "crosshairs-gps": F1A4, + "crosshairs-off": FF62, + "crosshairs-question": F0161, + "crown": F1A5, + "crown-outline": F01FB, + "cryengine": F958, + "crystal-ball": FB14, + "cube": F1A6, + "cube-outline": F1A7, + "cube-scan": FB60, + "cube-send": F1A8, + "cube-unfolded": F1A9, + "cup": F1AA, + "cup-off": F5E5, + "cup-outline": F033A, + "cup-water": F1AB, + "cupboard": FF63, + "cupboard-outline": FF64, + "cupcake": F959, + "curling": F862, + "currency-bdt": F863, + "currency-brl": FB61, + "currency-btc": F1AC, + "currency-cny": F7B9, + "currency-eth": F7BA, + "currency-eur": F1AD, + "currency-eur-off": F0340, + "currency-gbp": F1AE, + "currency-ils": FC3D, + "currency-inr": F1AF, + "currency-jpy": F7BB, + "currency-krw": F7BC, + "currency-kzt": F864, + "currency-ngn": F1B0, + "currency-php": F9E5, + "currency-rial": FEB9, + "currency-rub": F1B1, + "currency-sign": F7BD, + "currency-try": F1B2, + "currency-twd": F7BE, + "currency-usd": F1B3, + "currency-usd-off": F679, + "current-ac": F95A, + "current-dc": F95B, + "cursor-default": F1B4, + "cursor-default-click": FCD9, + "cursor-default-click-outline": FCDA, + "cursor-default-gesture": F0152, + "cursor-default-gesture-outline": F0153, + "cursor-default-outline": F1B5, + "cursor-move": F1B6, + "cursor-pointer": F1B7, + "cursor-text": F5E7, + "database": F1B8, + "database-check": FAA8, + "database-edit": FB62, + "database-export": F95D, + "database-import": F95C, + "database-lock": FAA9, + "database-marker": F0321, + "database-minus": F1B9, + "database-plus": F1BA, + "database-refresh": FCDB, + "database-remove": FCDC, + "database-search": F865, + "database-settings": FCDD, + "death-star": F8D7, + "death-star-variant": F8D8, + "deathly-hallows": FB63, + "debian": F8D9, + "debug-step-into": F1BB, + "debug-step-out": F1BC, + "debug-step-over": F1BD, + "decagram": F76B, + "decagram-outline": F76C, + "decimal": F00CC, + "decimal-comma": F00CD, + "decimal-comma-decrease": F00CE, + "decimal-comma-increase": F00CF, + "decimal-decrease": F1BE, + "decimal-increase": F1BF, + "delete": F1C0, + "delete-alert": F00D0, + "delete-alert-outline": F00D1, + "delete-circle": F682, + "delete-circle-outline": FB64, + "delete-empty": F6CB, + "delete-empty-outline": FEBA, + "delete-forever": F5E8, + "delete-forever-outline": FB65, + "delete-off": F00D2, + "delete-off-outline": F00D3, + "delete-outline": F9E6, + "delete-restore": F818, + "delete-sweep": F5E9, + "delete-sweep-outline": FC3E, + "delete-variant": F1C1, + "delta": F1C2, + "desk": F0264, + "desk-lamp": F95E, + "deskphone": F1C3, + "desktop-classic": F7BF, + "desktop-mac": F1C4, + "desktop-mac-dashboard": F9E7, + "desktop-tower": F1C5, + "desktop-tower-monitor": FAAA, + "details": F1C6, + "dev-to": FD4A, + "developer-board": F696, + "deviantart": F1C7, + "devices": FFD0, + "diabetes": F0151, + "dialpad": F61C, + "diameter": FC3F, + "diameter-outline": FC40, + "diameter-variant": FC41, + "diamond": FB66, + "diamond-outline": FB67, + "diamond-stone": F1C8, + "dice-1": F1CA, + "dice-1-outline": F0175, + "dice-2": F1CB, + "dice-2-outline": F0176, + "dice-3": F1CC, + "dice-3-outline": F0177, + "dice-4": F1CD, + "dice-4-outline": F0178, + "dice-5": F1CE, + "dice-5-outline": F0179, + "dice-6": F1CF, + "dice-6-outline": F017A, + "dice-d10": F017E, + "dice-d10-outline": F76E, + "dice-d12": F017F, + "dice-d12-outline": F866, + "dice-d20": F0180, + "dice-d20-outline": F5EA, + "dice-d4": F017B, + "dice-d4-outline": F5EB, + "dice-d6": F017C, + "dice-d6-outline": F5EC, + "dice-d8": F017D, + "dice-d8-outline": F5ED, + "dice-multiple": F76D, + "dice-multiple-outline": F0181, + "dictionary": F61D, + "digital-ocean": F0262, + "dip-switch": F7C0, + "directions": F1D0, + "directions-fork": F641, + "disc": F5EE, + "disc-alert": F1D1, + "disc-player": F95F, + "discord": F66F, + "dishwasher": FAAB, + "dishwasher-alert": F01E3, + "dishwasher-off": F01E4, + "disqus": F1D2, + "disqus-outline": F1D3, + "distribute-horizontal-center": F01F4, + "distribute-horizontal-left": F01F3, + "distribute-horizontal-right": F01F5, + "distribute-vertical-bottom": F01F6, + "distribute-vertical-center": F01F7, + "distribute-vertical-top": F01F8, + "diving-flippers": FD9B, + "diving-helmet": FD9C, + "diving-scuba": FD9D, + "diving-scuba-flag": FD9E, + "diving-scuba-tank": FD9F, + "diving-scuba-tank-multiple": FDA0, + "diving-snorkel": FDA1, + "division": F1D4, + "division-box": F1D5, + "dlna": FA40, + "dna": F683, + "dns": F1D6, + "dns-outline": FB68, + "do-not-disturb": F697, + "do-not-disturb-off": F698, + "dock-bottom": F00D4, + "dock-left": F00D5, + "dock-right": F00D6, + "dock-window": F00D7, + "docker": F867, + "doctor": FA41, + "dog": FA42, + "dog-service": FAAC, + "dog-side": FA43, + "dolby": F6B2, + "dolly": FEBB, + "domain": F1D7, + "domain-off": FD4B, + "domain-plus": F00D8, + "domain-remove": F00D9, + "domino-mask": F0045, + "donkey": F7C1, + "door": F819, + "door-closed": F81A, + "door-closed-lock": F00DA, + "door-open": F81B, + "doorbell": F0311, + "doorbell-video": F868, + "dot-net": FAAD, + "dots-horizontal": F1D8, + "dots-horizontal-circle": F7C2, + "dots-horizontal-circle-outline": FB69, + "dots-vertical": F1D9, + "dots-vertical-circle": F7C3, + "dots-vertical-circle-outline": FB6A, + "douban": F699, + "download": F1DA, + "download-multiple": F9E8, + "download-network": F6F3, + "download-network-outline": FC42, + "download-off": F00DB, + "download-off-outline": F00DC, + "download-outline": FB6B, + "drag": F1DB, + "drag-horizontal": F1DC, + "drag-horizontal-variant": F031B, + "drag-variant": FB6C, + "drag-vertical": F1DD, + "drag-vertical-variant": F031C, + "drama-masks": FCDE, + "draw": FF66, + "drawing": F1DE, + "drawing-box": F1DF, + "dresser": FF67, + "dresser-outline": FF68, + "dribbble": F1E0, + "dribbble-box": F1E1, + "drone": F1E2, + "dropbox": F1E3, + "drupal": F1E4, + "duck": F1E5, + "dumbbell": F1E6, + "dump-truck": FC43, + "ear-hearing": F7C4, + "ear-hearing-off": FA44, + "earth": F1E7, + "earth-arrow-right": F033C, + "earth-box": F6CC, + "earth-box-off": F6CD, + "earth-off": F1E8, + "edge": F1E9, + "edge-legacy": F027B, + "egg": FAAE, + "egg-easter": FAAF, + "eight-track": F9E9, + "eject": F1EA, + "eject-outline": FB6D, + "electric-switch": FEBC, + "electric-switch-closed": F0104, + "electron-framework": F0046, + "elephant": F7C5, + "elevation-decline": F1EB, + "elevation-rise": F1EC, + "elevator": F1ED, + "elevator-down": F02ED, + "elevator-up": F02EC, + "ellipse": FEBD, + "ellipse-outline": FEBE, + "email": F1EE, + "email-alert": F6CE, + "email-alert-outline": FD1E, + "email-box": FCDF, + "email-check": FAB0, + "email-check-outline": FAB1, + "email-edit": FF00, + "email-edit-outline": FF01, + "email-lock": F1F1, + "email-mark-as-unread": FB6E, + "email-minus": FF02, + "email-minus-outline": FF03, + "email-multiple": FF04, + "email-multiple-outline": FF05, + "email-newsletter": FFD1, + "email-open": F1EF, + "email-open-multiple": FF06, + "email-open-multiple-outline": FF07, + "email-open-outline": F5EF, + "email-outline": F1F0, + "email-plus": F9EA, + "email-plus-outline": F9EB, + "email-receive": F0105, + "email-receive-outline": F0106, + "email-search": F960, + "email-search-outline": F961, + "email-send": F0107, + "email-send-outline": F0108, + "email-sync": F02F2, + "email-sync-outline": F02F3, + "email-variant": F5F0, + "ember": FB15, + "emby": F6B3, + "emoticon": FC44, + "emoticon-angry": FC45, + "emoticon-angry-outline": FC46, + "emoticon-confused": F0109, + "emoticon-confused-outline": F010A, + "emoticon-cool": FC47, + "emoticon-cool-outline": F1F3, + "emoticon-cry": FC48, + "emoticon-cry-outline": FC49, + "emoticon-dead": FC4A, + "emoticon-dead-outline": F69A, + "emoticon-devil": FC4B, + "emoticon-devil-outline": F1F4, + "emoticon-excited": FC4C, + "emoticon-excited-outline": F69B, + "emoticon-frown": FF69, + "emoticon-frown-outline": FF6A, + "emoticon-happy": FC4D, + "emoticon-happy-outline": F1F5, + "emoticon-kiss": FC4E, + "emoticon-kiss-outline": FC4F, + "emoticon-lol": F023F, + "emoticon-lol-outline": F0240, + "emoticon-neutral": FC50, + "emoticon-neutral-outline": F1F6, + "emoticon-outline": F1F2, + "emoticon-poop": F1F7, + "emoticon-poop-outline": FC51, + "emoticon-sad": FC52, + "emoticon-sad-outline": F1F8, + "emoticon-tongue": F1F9, + "emoticon-tongue-outline": FC53, + "emoticon-wink": FC54, + "emoticon-wink-outline": FC55, + "engine": F1FA, + "engine-off": FA45, + "engine-off-outline": FA46, + "engine-outline": F1FB, + "epsilon": F010B, + "equal": F1FC, + "equal-box": F1FD, + "equalizer": FEBF, + "equalizer-outline": FEC0, + "eraser": F1FE, + "eraser-variant": F642, + "escalator": F1FF, + "escalator-down": F02EB, + "escalator-up": F02EA, + "eslint": FC56, + "et": FAB2, + "ethereum": F869, + "ethernet": F200, + "ethernet-cable": F201, + "ethernet-cable-off": F202, + "etsy": F203, + "ev-station": F5F1, + "eventbrite": F7C6, + "evernote": F204, + "excavator": F0047, + "exclamation": F205, + "exclamation-thick": F0263, + "exit-run": FA47, + "exit-to-app": F206, + "expand-all": FAB3, + "expand-all-outline": FAB4, + "expansion-card": F8AD, + "expansion-card-variant": FFD2, + "exponent": F962, + "exponent-box": F963, + "export": F207, + "export-variant": FB6F, + "eye": F208, + "eye-check": FCE0, + "eye-check-outline": FCE1, + "eye-circle": FB70, + "eye-circle-outline": FB71, + "eye-minus": F0048, + "eye-minus-outline": F0049, + "eye-off": F209, + "eye-off-outline": F6D0, + "eye-outline": F6CF, + "eye-plus": F86A, + "eye-plus-outline": F86B, + "eye-settings": F86C, + "eye-settings-outline": F86D, + "eyedropper": F20A, + "eyedropper-variant": F20B, + "face": F643, + "face-agent": FD4C, + "face-outline": FB72, + "face-profile": F644, + "face-profile-woman": F00A1, + "face-recognition": FC57, + "face-woman": F00A2, + "face-woman-outline": F00A3, + "facebook": F20C, + "facebook-box": F20D, + "facebook-messenger": F20E, + "facebook-workplace": FB16, + "factory": F20F, + "fan": F210, + "fan-off": F81C, + "fast-forward": F211, + "fast-forward-10": FD4D, + "fast-forward-30": FCE2, + "fast-forward-5": F0223, + "fast-forward-outline": F6D1, + "fax": F212, + "feather": F6D2, + "feature-search": FA48, + "feature-search-outline": FA49, + "fedora": F8DA, + "ferris-wheel": FEC1, + "ferry": F213, + "file": F214, + "file-account": F73A, + "file-account-outline": F004A, + "file-alert": FA4A, + "file-alert-outline": FA4B, + "file-cabinet": FAB5, + "file-cad": FF08, + "file-cad-box": FF09, + "file-cancel": FDA2, + "file-cancel-outline": FDA3, + "file-certificate": F01B1, + "file-certificate-outline": F01B2, + "file-chart": F215, + "file-chart-outline": F004B, + "file-check": F216, + "file-check-outline": FE7B, + "file-clock": F030C, + "file-clock-outline": F030D, + "file-cloud": F217, + "file-cloud-outline": F004C, + "file-code": F22E, + "file-code-outline": F004D, + "file-compare": F8A9, + "file-delimited": F218, + "file-delimited-outline": FEC2, + "file-document": F219, + "file-document-box": F21A, + "file-document-box-check": FEC3, + "file-document-box-check-outline": FEC4, + "file-document-box-minus": FEC5, + "file-document-box-minus-outline": FEC6, + "file-document-box-multiple": FAB6, + "file-document-box-multiple-outline": FAB7, + "file-document-box-outline": F9EC, + "file-document-box-plus": FEC7, + "file-document-box-plus-outline": FEC8, + "file-document-box-remove": FEC9, + "file-document-box-remove-outline": FECA, + "file-document-box-search": FECB, + "file-document-box-search-outline": FECC, + "file-document-edit": FDA4, + "file-document-edit-outline": FDA5, + "file-document-outline": F9ED, + "file-download": F964, + "file-download-outline": F965, + "file-edit": F0212, + "file-edit-outline": F0213, + "file-excel": F21B, + "file-excel-box": F21C, + "file-excel-box-outline": F004E, + "file-excel-outline": F004F, + "file-export": F21D, + "file-export-outline": F0050, + "file-eye": FDA6, + "file-eye-outline": FDA7, + "file-find": F21E, + "file-find-outline": FB73, + "file-hidden": F613, + "file-image": F21F, + "file-image-outline": FECD, + "file-import": F220, + "file-import-outline": F0051, + "file-key": F01AF, + "file-key-outline": F01B0, + "file-link": F01A2, + "file-link-outline": F01A3, + "file-lock": F221, + "file-lock-outline": F0052, + "file-move": FAB8, + "file-move-outline": F0053, + "file-multiple": F222, + "file-multiple-outline": F0054, + "file-music": F223, + "file-music-outline": FE7C, + "file-outline": F224, + "file-pdf": F225, + "file-pdf-box": F226, + "file-pdf-box-outline": FFD3, + "file-pdf-outline": FE7D, + "file-percent": F81D, + "file-percent-outline": F0055, + "file-phone": F01A4, + "file-phone-outline": F01A5, + "file-plus": F751, + "file-plus-outline": FF0A, + "file-powerpoint": F227, + "file-powerpoint-box": F228, + "file-powerpoint-box-outline": F0056, + "file-powerpoint-outline": F0057, + "file-presentation-box": F229, + "file-question": F86E, + "file-question-outline": F0058, + "file-remove": FB74, + "file-remove-outline": F0059, + "file-replace": FB17, + "file-replace-outline": FB18, + "file-restore": F670, + "file-restore-outline": F005A, + "file-search": FC58, + "file-search-outline": FC59, + "file-send": F22A, + "file-send-outline": F005B, + "file-settings": F00A4, + "file-settings-outline": F00A5, + "file-settings-variant": F00A6, + "file-settings-variant-outline": F00A7, + "file-star": F005C, + "file-star-outline": F005D, + "file-swap": FFD4, + "file-swap-outline": FFD5, + "file-sync": F0241, + "file-sync-outline": F0242, + "file-table": FC5A, + "file-table-box": F010C, + "file-table-box-multiple": F010D, + "file-table-box-multiple-outline": F010E, + "file-table-box-outline": F010F, + "file-table-outline": FC5B, + "file-tree": F645, + "file-undo": F8DB, + "file-undo-outline": F005E, + "file-upload": FA4C, + "file-upload-outline": FA4D, + "file-video": F22B, + "file-video-outline": FE10, + "file-word": F22C, + "file-word-box": F22D, + "file-word-box-outline": F005F, + "file-word-outline": F0060, + "film": F22F, + "filmstrip": F230, + "filmstrip-off": F231, + "filter": F232, + "filter-menu": F0110, + "filter-menu-outline": F0111, + "filter-minus": FF0B, + "filter-minus-outline": FF0C, + "filter-outline": F233, + "filter-plus": FF0D, + "filter-plus-outline": FF0E, + "filter-remove": F234, + "filter-remove-outline": F235, + "filter-variant": F236, + "filter-variant-minus": F013D, + "filter-variant-plus": F013E, + "filter-variant-remove": F0061, + "finance": F81E, + "find-replace": F6D3, + "fingerprint": F237, + "fingerprint-off": FECE, + "fire": F238, + "fire-extinguisher": FF0F, + "fire-hydrant": F0162, + "fire-hydrant-alert": F0163, + "fire-hydrant-off": F0164, + "fire-truck": F8AA, + "firebase": F966, + "firefox": F239, + "fireplace": FE11, + "fireplace-off": FE12, + "firework": FE13, + "fish": F23A, + "fishbowl": FF10, + "fishbowl-outline": FF11, + "fit-to-page": FF12, + "fit-to-page-outline": FF13, + "flag": F23B, + "flag-checkered": F23C, + "flag-minus": FB75, + "flag-minus-outline": F00DD, + "flag-outline": F23D, + "flag-plus": FB76, + "flag-plus-outline": F00DE, + "flag-remove": FB77, + "flag-remove-outline": F00DF, + "flag-triangle": F23F, + "flag-variant": F240, + "flag-variant-outline": F23E, + "flare": FD4E, + "flash": F241, + "flash-alert": FF14, + "flash-alert-outline": FF15, + "flash-auto": F242, + "flash-circle": F81F, + "flash-off": F243, + "flash-outline": F6D4, + "flash-red-eye": F67A, + "flashlight": F244, + "flashlight-off": F245, + "flask": F093, + "flask-empty": F094, + "flask-empty-minus": F0265, + "flask-empty-minus-outline": F0266, + "flask-empty-outline": F095, + "flask-empty-plus": F0267, + "flask-empty-plus-outline": F0268, + "flask-empty-remove": F0269, + "flask-empty-remove-outline": F026A, + "flask-minus": F026B, + "flask-minus-outline": F026C, + "flask-outline": F096, + "flask-plus": F026D, + "flask-plus-outline": F026E, + "flask-remove": F026F, + "flask-remove-outline": F0270, + "flask-round-bottom": F0276, + "flask-round-bottom-empty": F0277, + "flask-round-bottom-empty-outline": F0278, + "flask-round-bottom-outline": F0279, + "flattr": F246, + "fleur-de-lis": F032E, + "flickr": FCE3, + "flip-horizontal": F0112, + "flip-to-back": F247, + "flip-to-front": F248, + "flip-vertical": F0113, + "floor-lamp": F8DC, + "floor-lamp-dual": F0062, + "floor-lamp-variant": F0063, + "floor-plan": F820, + "floppy": F249, + "floppy-variant": F9EE, + "flower": F24A, + "flower-outline": F9EF, + "flower-poppy": FCE4, + "flower-tulip": F9F0, + "flower-tulip-outline": F9F1, + "focus-auto": FF6B, + "focus-field": FF6C, + "focus-field-horizontal": FF6D, + "focus-field-vertical": FF6E, + "folder": F24B, + "folder-account": F24C, + "folder-account-outline": FB78, + "folder-alert": FDA8, + "folder-alert-outline": FDA9, + "folder-clock": FAB9, + "folder-clock-outline": FABA, + "folder-download": F24D, + "folder-download-outline": F0114, + "folder-edit": F8DD, + "folder-edit-outline": FDAA, + "folder-google-drive": F24E, + "folder-heart": F0115, + "folder-heart-outline": F0116, + "folder-home": F00E0, + "folder-home-outline": F00E1, + "folder-image": F24F, + "folder-information": F00E2, + "folder-information-outline": F00E3, + "folder-key": F8AB, + "folder-key-network": F8AC, + "folder-key-network-outline": FC5C, + "folder-key-outline": F0117, + "folder-lock": F250, + "folder-lock-open": F251, + "folder-marker": F0298, + "folder-marker-outline": F0299, + "folder-move": F252, + "folder-move-outline": F0271, + "folder-multiple": F253, + "folder-multiple-image": F254, + "folder-multiple-outline": F255, + "folder-network": F86F, + "folder-network-outline": FC5D, + "folder-open": F76F, + "folder-open-outline": FDAB, + "folder-outline": F256, + "folder-plus": F257, + "folder-plus-outline": FB79, + "folder-pound": FCE5, + "folder-pound-outline": FCE6, + "folder-remove": F258, + "folder-remove-outline": FB7A, + "folder-search": F967, + "folder-search-outline": F968, + "folder-settings": F00A8, + "folder-settings-outline": F00A9, + "folder-settings-variant": F00AA, + "folder-settings-variant-outline": F00AB, + "folder-star": F69C, + "folder-star-outline": FB7B, + "folder-swap": FFD6, + "folder-swap-outline": FFD7, + "folder-sync": FCE7, + "folder-sync-outline": FCE8, + "folder-table": F030E, + "folder-table-outline": F030F, + "folder-text": FC5E, + "folder-text-outline": FC5F, + "folder-upload": F259, + "folder-upload-outline": F0118, + "folder-zip": F6EA, + "folder-zip-outline": F7B8, + "font-awesome": F03A, + "food": F25A, + "food-apple": F25B, + "food-apple-outline": FC60, + "food-croissant": F7C7, + "food-fork-drink": F5F2, + "food-off": F5F3, + "food-variant": F25C, + "foot-print": FF6F, + "football": F25D, + "football-australian": F25E, + "football-helmet": F25F, + "forklift": F7C8, + "format-align-bottom": F752, + "format-align-center": F260, + "format-align-justify": F261, + "format-align-left": F262, + "format-align-middle": F753, + "format-align-right": F263, + "format-align-top": F754, + "format-annotation-minus": FABB, + "format-annotation-plus": F646, + "format-bold": F264, + "format-clear": F265, + "format-color-fill": F266, + "format-color-highlight": FE14, + "format-color-marker-cancel": F033E, + "format-color-text": F69D, + "format-columns": F8DE, + "format-float-center": F267, + "format-float-left": F268, + "format-float-none": F269, + "format-float-right": F26A, + "format-font": F6D5, + "format-font-size-decrease": F9F2, + "format-font-size-increase": F9F3, + "format-header-1": F26B, + "format-header-2": F26C, + "format-header-3": F26D, + "format-header-4": F26E, + "format-header-5": F26F, + "format-header-6": F270, + "format-header-decrease": F271, + "format-header-equal": F272, + "format-header-increase": F273, + "format-header-pound": F274, + "format-horizontal-align-center": F61E, + "format-horizontal-align-left": F61F, + "format-horizontal-align-right": F620, + "format-indent-decrease": F275, + "format-indent-increase": F276, + "format-italic": F277, + "format-letter-case": FB19, + "format-letter-case-lower": FB1A, + "format-letter-case-upper": FB1B, + "format-letter-ends-with": FFD8, + "format-letter-matches": FFD9, + "format-letter-starts-with": FFDA, + "format-line-spacing": F278, + "format-line-style": F5C8, + "format-line-weight": F5C9, + "format-list-bulleted": F279, + "format-list-bulleted-square": FDAC, + "format-list-bulleted-triangle": FECF, + "format-list-bulleted-type": F27A, + "format-list-checkbox": F969, + "format-list-checks": F755, + "format-list-numbered": F27B, + "format-list-numbered-rtl": FCE9, + "format-list-text": F029A, + "format-overline": FED0, + "format-page-break": F6D6, + "format-paint": F27C, + "format-paragraph": F27D, + "format-pilcrow": F6D7, + "format-quote-close": F27E, + "format-quote-close-outline": F01D3, + "format-quote-open": F756, + "format-quote-open-outline": F01D2, + "format-rotate-90": F6A9, + "format-section": F69E, + "format-size": F27F, + "format-strikethrough": F280, + "format-strikethrough-variant": F281, + "format-subscript": F282, + "format-superscript": F283, + "format-text": F284, + "format-text-rotation-angle-down": FFDB, + "format-text-rotation-angle-up": FFDC, + "format-text-rotation-down": FD4F, + "format-text-rotation-down-vertical": FFDD, + "format-text-rotation-none": FD50, + "format-text-rotation-up": FFDE, + "format-text-rotation-vertical": FFDF, + "format-text-variant": FE15, + "format-text-wrapping-clip": FCEA, + "format-text-wrapping-overflow": FCEB, + "format-text-wrapping-wrap": FCEC, + "format-textbox": FCED, + "format-textdirection-l-to-r": F285, + "format-textdirection-r-to-l": F286, + "format-title": F5F4, + "format-underline": F287, + "format-vertical-align-bottom": F621, + "format-vertical-align-center": F622, + "format-vertical-align-top": F623, + "format-wrap-inline": F288, + "format-wrap-square": F289, + "format-wrap-tight": F28A, + "format-wrap-top-bottom": F28B, + "forum": F28C, + "forum-outline": F821, + "forward": F28D, + "forwardburger": FD51, + "fountain": F96A, + "fountain-pen": FCEE, + "fountain-pen-tip": FCEF, + "foursquare": F28E, + "freebsd": F8DF, + "frequently-asked-questions": FED1, + "fridge": F290, + "fridge-alert": F01DC, + "fridge-alert-outline": F01DD, + "fridge-bottom": F292, + "fridge-off": F01DA, + "fridge-off-outline": F01DB, + "fridge-outline": F28F, + "fridge-top": F291, + "fruit-cherries": F0064, + "fruit-citrus": F0065, + "fruit-grapes": F0066, + "fruit-grapes-outline": F0067, + "fruit-pineapple": F0068, + "fruit-watermelon": F0069, + "fuel": F7C9, + "fullscreen": F293, + "fullscreen-exit": F294, + "function": F295, + "function-variant": F870, + "furigana-horizontal": F00AC, + "furigana-vertical": F00AD, + "fuse": FC61, + "fuse-blade": FC62, + "gamepad": F296, + "gamepad-circle": FE16, + "gamepad-circle-down": FE17, + "gamepad-circle-left": FE18, + "gamepad-circle-outline": FE19, + "gamepad-circle-right": FE1A, + "gamepad-circle-up": FE1B, + "gamepad-down": FE1C, + "gamepad-left": FE1D, + "gamepad-right": FE1E, + "gamepad-round": FE1F, + "gamepad-round-down": FE7E, + "gamepad-round-left": FE7F, + "gamepad-round-outline": FE80, + "gamepad-round-right": FE81, + "gamepad-round-up": FE82, + "gamepad-square": FED2, + "gamepad-square-outline": FED3, + "gamepad-up": FE83, + "gamepad-variant": F297, + "gamepad-variant-outline": FED4, + "gamma": F0119, + "gantry-crane": FDAD, + "garage": F6D8, + "garage-alert": F871, + "garage-alert-variant": F0300, + "garage-open": F6D9, + "garage-open-variant": F02FF, + "garage-variant": F02FE, + "gas-cylinder": F647, + "gas-station": F298, + "gas-station-outline": FED5, + "gate": F299, + "gate-and": F8E0, + "gate-arrow-right": F0194, + "gate-nand": F8E1, + "gate-nor": F8E2, + "gate-not": F8E3, + "gate-open": F0195, + "gate-or": F8E4, + "gate-xnor": F8E5, + "gate-xor": F8E6, + "gatsby": FE84, + "gauge": F29A, + "gauge-empty": F872, + "gauge-full": F873, + "gauge-low": F874, + "gavel": F29B, + "gender-female": F29C, + "gender-male": F29D, + "gender-male-female": F29E, + "gender-male-female-variant": F016A, + "gender-non-binary": F016B, + "gender-transgender": F29F, + "gentoo": F8E7, + "gesture": F7CA, + "gesture-double-tap": F73B, + "gesture-pinch": FABC, + "gesture-spread": FABD, + "gesture-swipe": FD52, + "gesture-swipe-down": F73C, + "gesture-swipe-horizontal": FABE, + "gesture-swipe-left": F73D, + "gesture-swipe-right": F73E, + "gesture-swipe-up": F73F, + "gesture-swipe-vertical": FABF, + "gesture-tap": F740, + "gesture-tap-box": F02D4, + "gesture-tap-button": F02D3, + "gesture-tap-hold": FD53, + "gesture-two-double-tap": F741, + "gesture-two-tap": F742, + "ghost": F2A0, + "ghost-off": F9F4, + "gif": FD54, + "gift": FE85, + "gift-outline": F2A1, + "git": F2A2, + "github-box": F2A3, + "github-circle": F2A4, + "github-face": F6DA, + "gitlab": FB7C, + "glass-cocktail": F356, + "glass-flute": F2A5, + "glass-mug": F2A6, + "glass-mug-variant": F0141, + "glass-pint-outline": F0338, + "glass-stange": F2A7, + "glass-tulip": F2A8, + "glass-wine": F875, + "glassdoor": F2A9, + "glasses": F2AA, + "globe-light": F0302, + "globe-model": F8E8, + "gmail": F2AB, + "gnome": F2AC, + "go-kart": FD55, + "go-kart-track": FD56, + "gog": FB7D, + "gold": F027A, + "golf": F822, + "golf-cart": F01CF, + "golf-tee": F00AE, + "gondola": F685, + "goodreads": FD57, + "google": F2AD, + "google-adwords": FC63, + "google-analytics": F7CB, + "google-assistant": F7CC, + "google-cardboard": F2AE, + "google-chrome": F2AF, + "google-circles": F2B0, + "google-circles-communities": F2B1, + "google-circles-extended": F2B2, + "google-circles-group": F2B3, + "google-classroom": F2C0, + "google-cloud": F0221, + "google-controller": F2B4, + "google-controller-off": F2B5, + "google-drive": F2B6, + "google-earth": F2B7, + "google-fit": F96B, + "google-glass": F2B8, + "google-hangouts": F2C9, + "google-home": F823, + "google-keep": F6DB, + "google-lens": F9F5, + "google-maps": F5F5, + "google-my-business": F006A, + "google-nearby": F2B9, + "google-pages": F2BA, + "google-photos": F6DC, + "google-physical-web": F2BB, + "google-play": F2BC, + "google-plus": F2BD, + "google-plus-box": F2BE, + "google-podcast": FED6, + "google-spreadsheet": F9F6, + "google-street-view": FC64, + "google-translate": F2BF, + "gradient": F69F, + "grain": FD58, + "graph": F006B, + "graph-outline": F006C, + "graphql": F876, + "grave-stone": FB7E, + "grease-pencil": F648, + "greater-than": F96C, + "greater-than-or-equal": F96D, + "grid": F2C1, + "grid-large": F757, + "grid-off": F2C2, + "grill": FE86, + "grill-outline": F01B5, + "group": F2C3, + "guitar-acoustic": F770, + "guitar-electric": F2C4, + "guitar-pick": F2C5, + "guitar-pick-outline": F2C6, + "guy-fawkes-mask": F824, + "hackernews": F624, + "hail": FAC0, + "hair-dryer": F011A, + "hair-dryer-outline": F011B, + "halloween": FB7F, + "hamburger": F684, + "hammer": F8E9, + "hand": FA4E, + "hand-heart": F011C, + "hand-left": FE87, + "hand-okay": FA4F, + "hand-peace": FA50, + "hand-peace-variant": FA51, + "hand-pointing-down": FA52, + "hand-pointing-left": FA53, + "hand-pointing-right": F2C7, + "hand-pointing-up": FA54, + "hand-right": FE88, + "hand-saw": FE89, + "handball": FF70, + "handcuffs": F0169, + "handshake": F0243, + "hanger": F2C8, + "hard-hat": F96E, + "harddisk": F2CA, + "harddisk-plus": F006D, + "harddisk-remove": F006E, + "hat-fedora": FB80, + "hazard-lights": FC65, + "hdr": FD59, + "hdr-off": FD5A, + "headphones": F2CB, + "headphones-bluetooth": F96F, + "headphones-box": F2CC, + "headphones-off": F7CD, + "headphones-settings": F2CD, + "headset": F2CE, + "headset-dock": F2CF, + "headset-off": F2D0, + "heart": F2D1, + "heart-box": F2D2, + "heart-box-outline": F2D3, + "heart-broken": F2D4, + "heart-broken-outline": FCF0, + "heart-circle": F970, + "heart-circle-outline": F971, + "heart-flash": FF16, + "heart-half": F6DE, + "heart-half-full": F6DD, + "heart-half-outline": F6DF, + "heart-multiple": FA55, + "heart-multiple-outline": FA56, + "heart-off": F758, + "heart-outline": F2D5, + "heart-pulse": F5F6, + "helicopter": FAC1, + "help": F2D6, + "help-box": F78A, + "help-circle": F2D7, + "help-circle-outline": F625, + "help-network": F6F4, + "help-network-outline": FC66, + "help-rhombus": FB81, + "help-rhombus-outline": FB82, + "hexadecimal": F02D2, + "hexagon": F2D8, + "hexagon-multiple": F6E0, + "hexagon-multiple-outline": F011D, + "hexagon-outline": F2D9, + "hexagon-slice-1": FAC2, + "hexagon-slice-2": FAC3, + "hexagon-slice-3": FAC4, + "hexagon-slice-4": FAC5, + "hexagon-slice-5": FAC6, + "hexagon-slice-6": FAC7, + "hexagram": FAC8, + "hexagram-outline": FAC9, + "high-definition": F7CE, + "high-definition-box": F877, + "highway": F5F7, + "hiking": FD5B, + "hinduism": F972, + "history": F2DA, + "hockey-puck": F878, + "hockey-sticks": F879, + "hololens": F2DB, + "home": F2DC, + "home-account": F825, + "home-alert": F87A, + "home-analytics": FED7, + "home-assistant": F7CF, + "home-automation": F7D0, + "home-circle": F7D1, + "home-circle-outline": F006F, + "home-city": FCF1, + "home-city-outline": FCF2, + "home-currency-usd": F8AE, + "home-edit": F0184, + "home-edit-outline": F0185, + "home-export-outline": FFB8, + "home-flood": FF17, + "home-floor-0": FDAE, + "home-floor-1": FD5C, + "home-floor-2": FD5D, + "home-floor-3": FD5E, + "home-floor-a": FD5F, + "home-floor-b": FD60, + "home-floor-g": FD61, + "home-floor-l": FD62, + "home-floor-negative-1": FDAF, + "home-group": FDB0, + "home-heart": F826, + "home-import-outline": FFB9, + "home-lightbulb": F027C, + "home-lightbulb-outline": F027D, + "home-lock": F8EA, + "home-lock-open": F8EB, + "home-map-marker": F5F8, + "home-minus": F973, + "home-modern": F2DD, + "home-outline": F6A0, + "home-plus": F974, + "home-remove": F0272, + "home-roof": F0156, + "home-thermometer": FF71, + "home-thermometer-outline": FF72, + "home-variant": F2DE, + "home-variant-outline": FB83, + "hook": F6E1, + "hook-off": F6E2, + "hops": F2DF, + "horizontal-rotate-clockwise": F011E, + "horizontal-rotate-counterclockwise": F011F, + "horseshoe": FA57, + "hospital": F0017, + "hospital-box": F2E0, + "hospital-box-outline": F0018, + "hospital-building": F2E1, + "hospital-marker": F2E2, + "hot-tub": F827, + "hotel": F2E3, + "houzz": F2E4, + "houzz-box": F2E5, + "hubspot": FCF3, + "hulu": F828, + "human": F2E6, + "human-child": F2E7, + "human-female": F649, + "human-female-boy": FA58, + "human-female-female": FA59, + "human-female-girl": FA5A, + "human-greeting": F64A, + "human-handsdown": F64B, + "human-handsup": F64C, + "human-male": F64D, + "human-male-boy": FA5B, + "human-male-female": F2E8, + "human-male-girl": FA5C, + "human-male-height": FF18, + "human-male-height-variant": FF19, + "human-male-male": FA5D, + "human-pregnant": F5CF, + "humble-bundle": F743, + "hydro-power": F0310, + "ice-cream": F829, + "ice-pop": FF1A, + "id-card": FFE0, + "identifier": FF1B, + "iframe": FC67, + "iframe-array": F0120, + "iframe-array-outline": F0121, + "iframe-braces": F0122, + "iframe-braces-outline": F0123, + "iframe-outline": FC68, + "iframe-parentheses": F0124, + "iframe-parentheses-outline": F0125, + "iframe-variable": F0126, + "iframe-variable-outline": F0127, + "image": F2E9, + "image-album": F2EA, + "image-area": F2EB, + "image-area-close": F2EC, + "image-auto-adjust": FFE1, + "image-broken": F2ED, + "image-broken-variant": F2EE, + "image-edit": F020E, + "image-edit-outline": F020F, + "image-filter": F2EF, + "image-filter-black-white": F2F0, + "image-filter-center-focus": F2F1, + "image-filter-center-focus-strong": FF1C, + "image-filter-center-focus-strong-outline": FF1D, + "image-filter-center-focus-weak": F2F2, + "image-filter-drama": F2F3, + "image-filter-frames": F2F4, + "image-filter-hdr": F2F5, + "image-filter-none": F2F6, + "image-filter-tilt-shift": F2F7, + "image-filter-vintage": F2F8, + "image-frame": FE8A, + "image-move": F9F7, + "image-multiple": F2F9, + "image-off": F82A, + "image-off-outline": F01FC, + "image-outline": F975, + "image-plus": F87B, + "image-search": F976, + "image-search-outline": F977, + "image-size-select-actual": FC69, + "image-size-select-large": FC6A, + "image-size-select-small": FC6B, + "import": F2FA, + "inbox": F686, + "inbox-arrow-down": F2FB, + "inbox-arrow-down-outline": F029B, + "inbox-arrow-up": F3D1, + "inbox-arrow-up-outline": F029C, + "inbox-full": F029D, + "inbox-full-outline": F029E, + "inbox-multiple": F8AF, + "inbox-multiple-outline": FB84, + "inbox-outline": F029F, + "incognito": F5F9, + "infinity": F6E3, + "information": F2FC, + "information-outline": F2FD, + "information-variant": F64E, + "instagram": F2FE, + "instapaper": F2FF, + "instrument-triangle": F0070, + "internet-explorer": F300, + "invert-colors": F301, + "invert-colors-off": FE8B, + "iobroker": F0313, + "ip": FA5E, + "ip-network": FA5F, + "ip-network-outline": FC6C, + "ipod": FC6D, + "islam": F978, + "island": F0071, + "itunes": F676, + "iv-bag": F00E4, + "jabber": FDB1, + "jeepney": F302, + "jellyfish": FF1E, + "jellyfish-outline": FF1F, + "jira": F303, + "jquery": F87C, + "jsfiddle": F304, + "json": F626, + "judaism": F979, + "jump-rope": F032A, + "kabaddi": FD63, + "karate": F82B, + "keg": F305, + "kettle": F5FA, + "kettle-alert": F0342, + "kettle-alert-outline": F0343, + "kettle-off": F0346, + "kettle-off-outline": F0347, + "kettle-outline": FF73, + "kettle-steam": F0344, + "kettle-steam-outline": F0345, + "kettlebell": F032B, + "key": F306, + "key-arrow-right": F033D, + "key-change": F307, + "key-link": F01CA, + "key-minus": F308, + "key-outline": FDB2, + "key-plus": F309, + "key-remove": F30A, + "key-star": F01C9, + "key-variant": F30B, + "key-wireless": FFE2, + "keyboard": F30C, + "keyboard-backspace": F30D, + "keyboard-caps": F30E, + "keyboard-close": F30F, + "keyboard-esc": F02E2, + "keyboard-f1": F02D6, + "keyboard-f10": F02DF, + "keyboard-f11": F02E0, + "keyboard-f12": F02E1, + "keyboard-f2": F02D7, + "keyboard-f3": F02D8, + "keyboard-f4": F02D9, + "keyboard-f5": F02DA, + "keyboard-f6": F02DB, + "keyboard-f7": F02DC, + "keyboard-f8": F02DD, + "keyboard-f9": F02DE, + "keyboard-off": F310, + "keyboard-off-outline": FE8C, + "keyboard-outline": F97A, + "keyboard-return": F311, + "keyboard-settings": F9F8, + "keyboard-settings-outline": F9F9, + "keyboard-space": F0072, + "keyboard-tab": F312, + "keyboard-variant": F313, + "khanda": F0128, + "kickstarter": F744, + "knife": F9FA, + "knife-military": F9FB, + "kodi": F314, + "kotlin": F0244, + "kubernetes": F0129, + "label": F315, + "label-off": FACA, + "label-off-outline": FACB, + "label-outline": F316, + "label-percent": F0315, + "label-percent-outline": F0316, + "label-variant": FACC, + "label-variant-outline": FACD, + "ladybug": F82C, + "lambda": F627, + "lamp": F6B4, + "lan": F317, + "lan-check": F02D5, + "lan-connect": F318, + "lan-disconnect": F319, + "lan-pending": F31A, + "language-c": F671, + "language-cpp": F672, + "language-csharp": F31B, + "language-css3": F31C, + "language-fortran": F0245, + "language-go": F7D2, + "language-haskell": FC6E, + "language-html5": F31D, + "language-java": FB1C, + "language-javascript": F31E, + "language-lua": F8B0, + "language-php": F31F, + "language-python": F320, + "language-python-text": F321, + "language-r": F7D3, + "language-ruby-on-rails": FACE, + "language-swift": F6E4, + "language-typescript": F6E5, + "laptop": F322, + "laptop-chromebook": F323, + "laptop-mac": F324, + "laptop-off": F6E6, + "laptop-windows": F325, + "laravel": FACF, + "lasso": FF20, + "lastfm": F326, + "lastpass": F446, + "latitude": FF74, + "launch": F327, + "lava-lamp": F7D4, + "layers": F328, + "layers-minus": FE8D, + "layers-off": F329, + "layers-off-outline": F9FC, + "layers-outline": F9FD, + "layers-plus": FE30, + "layers-remove": FE31, + "layers-search": F0231, + "layers-search-outline": F0232, + "layers-triple": FF75, + "layers-triple-outline": FF76, + "lead-pencil": F64F, + "leaf": F32A, + "leaf-maple": FC6F, + "leaf-maple-off": F0305, + "leaf-off": F0304, + "leak": FDB3, + "leak-off": FDB4, + "led-off": F32B, + "led-on": F32C, + "led-outline": F32D, + "led-strip": F7D5, + "led-strip-variant": F0073, + "led-variant-off": F32E, + "led-variant-on": F32F, + "led-variant-outline": F330, + "leek": F01A8, + "less-than": F97B, + "less-than-or-equal": F97C, + "library": F331, + "library-books": F332, + "library-movie": FCF4, + "library-music": F333, + "library-music-outline": FF21, + "library-shelves": FB85, + "library-video": FCF5, + "license": FFE3, + "lifebuoy": F87D, + "light-switch": F97D, + "lightbulb": F335, + "lightbulb-cfl": F0233, + "lightbulb-cfl-off": F0234, + "lightbulb-cfl-spiral": F02A0, + "lightbulb-cfl-spiral-off": F02EE, + "lightbulb-group": F027E, + "lightbulb-group-off": F02F8, + "lightbulb-group-off-outline": F02F9, + "lightbulb-group-outline": F027F, + "lightbulb-multiple": F0280, + "lightbulb-multiple-off": F02FA, + "lightbulb-multiple-off-outline": F02FB, + "lightbulb-multiple-outline": F0281, + "lightbulb-off": FE32, + "lightbulb-off-outline": FE33, + "lightbulb-on": F6E7, + "lightbulb-on-outline": F6E8, + "lightbulb-outline": F336, + "lighthouse": F9FE, + "lighthouse-on": F9FF, + "link": F337, + "link-box": FCF6, + "link-box-outline": FCF7, + "link-box-variant": FCF8, + "link-box-variant-outline": FCF9, + "link-lock": F00E5, + "link-off": F338, + "link-plus": FC70, + "link-variant": F339, + "link-variant-minus": F012A, + "link-variant-off": F33A, + "link-variant-plus": F012B, + "link-variant-remove": F012C, + "linkedin": F33B, + "linkedin-box": F33C, + "linux": F33D, + "linux-mint": F8EC, + "litecoin": FA60, + "loading": F771, + "location-enter": FFE4, + "location-exit": FFE5, + "lock": F33E, + "lock-alert": F8ED, + "lock-clock": F97E, + "lock-open": F33F, + "lock-open-outline": F340, + "lock-open-variant": FFE6, + "lock-open-variant-outline": FFE7, + "lock-outline": F341, + "lock-pattern": F6E9, + "lock-plus": F5FB, + "lock-question": F8EE, + "lock-reset": F772, + "lock-smart": F8B1, + "locker": F7D6, + "locker-multiple": F7D7, + "login": F342, + "login-variant": F5FC, + "logout": F343, + "logout-variant": F5FD, + "longitude": FF77, + "looks": F344, + "loupe": F345, + "lumx": F346, + "lungs": F00AF, + "lyft": FB1D, + "magnet": F347, + "magnet-on": F348, + "magnify": F349, + "magnify-close": F97F, + "magnify-minus": F34A, + "magnify-minus-cursor": FA61, + "magnify-minus-outline": F6EB, + "magnify-plus": F34B, + "magnify-plus-cursor": FA62, + "magnify-plus-outline": F6EC, + "magnify-remove-cursor": F0237, + "magnify-remove-outline": F0238, + "magnify-scan": F02A1, + "mail": FED8, + "mail-ru": F34C, + "mailbox": F6ED, + "mailbox-open": FD64, + "mailbox-open-outline": FD65, + "mailbox-open-up": FD66, + "mailbox-open-up-outline": FD67, + "mailbox-outline": FD68, + "mailbox-up": FD69, + "mailbox-up-outline": FD6A, + "map": F34D, + "map-check": FED9, + "map-check-outline": FEDA, + "map-clock": FCFA, + "map-clock-outline": FCFB, + "map-legend": FA00, + "map-marker": F34E, + "map-marker-alert": FF22, + "map-marker-alert-outline": FF23, + "map-marker-check": FC71, + "map-marker-check-outline": F0326, + "map-marker-circle": F34F, + "map-marker-distance": F8EF, + "map-marker-down": F012D, + "map-marker-left": F0306, + "map-marker-left-outline": F0308, + "map-marker-minus": F650, + "map-marker-minus-outline": F0324, + "map-marker-multiple": F350, + "map-marker-multiple-outline": F02A2, + "map-marker-off": F351, + "map-marker-off-outline": F0328, + "map-marker-outline": F7D8, + "map-marker-path": FCFC, + "map-marker-plus": F651, + "map-marker-plus-outline": F0323, + "map-marker-question": FF24, + "map-marker-question-outline": FF25, + "map-marker-radius": F352, + "map-marker-radius-outline": F0327, + "map-marker-remove": FF26, + "map-marker-remove-outline": F0325, + "map-marker-remove-variant": FF27, + "map-marker-right": F0307, + "map-marker-right-outline": F0309, + "map-marker-up": F012E, + "map-minus": F980, + "map-outline": F981, + "map-plus": F982, + "map-search": F983, + "map-search-outline": F984, + "mapbox": FB86, + "margin": F353, + "markdown": F354, + "markdown-outline": FF78, + "marker": F652, + "marker-cancel": FDB5, + "marker-check": F355, + "mastodon": FAD0, + "mastodon-variant": FAD1, + "material-design": F985, + "material-ui": F357, + "math-compass": F358, + "math-cos": FC72, + "math-integral": FFE8, + "math-integral-box": FFE9, + "math-log": F00B0, + "math-norm": FFEA, + "math-norm-box": FFEB, + "math-sin": FC73, + "math-tan": FC74, + "matrix": F628, + "medal": F986, + "medical-bag": F6EE, + "meditation": F01A6, + "medium": F35A, + "meetup": FAD2, + "memory": F35B, + "menu": F35C, + "menu-down": F35D, + "menu-down-outline": F6B5, + "menu-left": F35E, + "menu-left-outline": FA01, + "menu-open": FB87, + "menu-right": F35F, + "menu-right-outline": FA02, + "menu-swap": FA63, + "menu-swap-outline": FA64, + "menu-up": F360, + "menu-up-outline": F6B6, + "merge": FF79, + "message": F361, + "message-alert": F362, + "message-alert-outline": FA03, + "message-arrow-left": F031D, + "message-arrow-left-outline": F031E, + "message-arrow-right": F031F, + "message-arrow-right-outline": F0320, + "message-bulleted": F6A1, + "message-bulleted-off": F6A2, + "message-draw": F363, + "message-image": F364, + "message-image-outline": F0197, + "message-lock": FFEC, + "message-lock-outline": F0198, + "message-minus": F0199, + "message-minus-outline": F019A, + "message-outline": F365, + "message-plus": F653, + "message-plus-outline": F00E6, + "message-processing": F366, + "message-processing-outline": F019B, + "message-reply": F367, + "message-reply-text": F368, + "message-settings": F6EF, + "message-settings-outline": F019C, + "message-settings-variant": F6F0, + "message-settings-variant-outline": F019D, + "message-text": F369, + "message-text-clock": F019E, + "message-text-clock-outline": F019F, + "message-text-lock": FFED, + "message-text-lock-outline": F01A0, + "message-text-outline": F36A, + "message-video": F36B, + "meteor": F629, + "metronome": F7D9, + "metronome-tick": F7DA, + "micro-sd": F7DB, + "microphone": F36C, + "microphone-minus": F8B2, + "microphone-off": F36D, + "microphone-outline": F36E, + "microphone-plus": F8B3, + "microphone-settings": F36F, + "microphone-variant": F370, + "microphone-variant-off": F371, + "microscope": F654, + "microsoft": F372, + "microsoft-dynamics": F987, + "microwave": FC75, + "middleware": FF7A, + "middleware-outline": FF7B, + "midi": F8F0, + "midi-port": F8F1, + "mine": FDB6, + "minecraft": F373, + "mini-sd": FA04, + "minidisc": FA05, + "minus": F374, + "minus-box": F375, + "minus-box-multiple": F016C, + "minus-box-multiple-outline": F016D, + "minus-box-outline": F6F1, + "minus-circle": F376, + "minus-circle-outline": F377, + "minus-network": F378, + "minus-network-outline": FC76, + "mirror": F0228, + "mixcloud": F62A, + "mixed-martial-arts": FD6B, + "mixed-reality": F87E, + "mixer": F7DC, + "molecule": FB88, + "monitor": F379, + "monitor-cellphone": F988, + "monitor-cellphone-star": F989, + "monitor-clean": F012F, + "monitor-dashboard": FA06, + "monitor-edit": F02F1, + "monitor-lock": FDB7, + "monitor-multiple": F37A, + "monitor-off": FD6C, + "monitor-screenshot": FE34, + "monitor-speaker": FF7C, + "monitor-speaker-off": FF7D, + "monitor-star": FDB8, + "moon-first-quarter": FF7E, + "moon-full": FF7F, + "moon-last-quarter": FF80, + "moon-new": FF81, + "moon-waning-crescent": FF82, + "moon-waning-gibbous": FF83, + "moon-waxing-crescent": FF84, + "moon-waxing-gibbous": FF85, + "moped": F00B1, + "more": F37B, + "mother-heart": F033F, + "mother-nurse": FCFD, + "motion-sensor": FD6D, + "motorbike": F37C, + "mouse": F37D, + "mouse-bluetooth": F98A, + "mouse-off": F37E, + "mouse-variant": F37F, + "mouse-variant-off": F380, + "move-resize": F655, + "move-resize-variant": F656, + "movie": F381, + "movie-edit": F014D, + "movie-edit-outline": F014E, + "movie-filter": F014F, + "movie-filter-outline": F0150, + "movie-open": FFEE, + "movie-open-outline": FFEF, + "movie-outline": FDB9, + "movie-roll": F7DD, + "movie-search": F01FD, + "movie-search-outline": F01FE, + "muffin": F98B, + "multiplication": F382, + "multiplication-box": F383, + "mushroom": F7DE, + "mushroom-outline": F7DF, + "music": F759, + "music-accidental-double-flat": FF86, + "music-accidental-double-sharp": FF87, + "music-accidental-flat": FF88, + "music-accidental-natural": FF89, + "music-accidental-sharp": FF8A, + "music-box": F384, + "music-box-outline": F385, + "music-circle": F386, + "music-circle-outline": FAD3, + "music-clef-alto": FF8B, + "music-clef-bass": FF8C, + "music-clef-treble": FF8D, + "music-note": F387, + "music-note-bluetooth": F5FE, + "music-note-bluetooth-off": F5FF, + "music-note-eighth": F388, + "music-note-eighth-dotted": FF8E, + "music-note-half": F389, + "music-note-half-dotted": FF8F, + "music-note-off": F38A, + "music-note-off-outline": FF90, + "music-note-outline": FF91, + "music-note-plus": FDBA, + "music-note-quarter": F38B, + "music-note-quarter-dotted": FF92, + "music-note-sixteenth": F38C, + "music-note-sixteenth-dotted": FF93, + "music-note-whole": F38D, + "music-note-whole-dotted": FF94, + "music-off": F75A, + "music-rest-eighth": FF95, + "music-rest-half": FF96, + "music-rest-quarter": FF97, + "music-rest-sixteenth": FF98, + "music-rest-whole": FF99, + "nail": FDBB, + "nas": F8F2, + "nativescript": F87F, + "nature": F38E, + "nature-people": F38F, + "navigation": F390, + "near-me": F5CD, + "necklace": FF28, + "needle": F391, + "netflix": F745, + "network": F6F2, + "network-off": FC77, + "network-off-outline": FC78, + "network-outline": FC79, + "network-router": F00B2, + "network-strength-1": F8F3, + "network-strength-1-alert": F8F4, + "network-strength-2": F8F5, + "network-strength-2-alert": F8F6, + "network-strength-3": F8F7, + "network-strength-3-alert": F8F8, + "network-strength-4": F8F9, + "network-strength-4-alert": F8FA, + "network-strength-off": F8FB, + "network-strength-off-outline": F8FC, + "network-strength-outline": F8FD, + "new-box": F394, + "newspaper": F395, + "newspaper-minus": FF29, + "newspaper-plus": FF2A, + "newspaper-variant": F0023, + "newspaper-variant-multiple": F0024, + "newspaper-variant-multiple-outline": F0025, + "newspaper-variant-outline": F0026, + "nfc": F396, + "nfc-off": FE35, + "nfc-search-variant": FE36, + "nfc-tap": F397, + "nfc-variant": F398, + "nfc-variant-off": FE37, + "ninja": F773, + "nintendo-switch": F7E0, + "nix": F0130, + "nodejs": F399, + "noodles": F01A9, + "not-equal": F98C, + "not-equal-variant": F98D, + "note": F39A, + "note-multiple": F6B7, + "note-multiple-outline": F6B8, + "note-outline": F39B, + "note-plus": F39C, + "note-plus-outline": F39D, + "note-text": F39E, + "note-text-outline": F0202, + "notebook": F82D, + "notebook-multiple": FE38, + "notebook-outline": FEDC, + "notification-clear-all": F39F, + "npm": F6F6, + "npm-variant": F98E, + "npm-variant-outline": F98F, + "nuke": F6A3, + "null": F7E1, + "numeric": F3A0, + "numeric-0": 0030, + "numeric-0-box": F3A1, + "numeric-0-box-multiple": FF2B, + "numeric-0-box-multiple-outline": F3A2, + "numeric-0-box-outline": F3A3, + "numeric-0-circle": FC7A, + "numeric-0-circle-outline": FC7B, + "numeric-1": 0031, + "numeric-1-box": F3A4, + "numeric-1-box-multiple": FF2C, + "numeric-1-box-multiple-outline": F3A5, + "numeric-1-box-outline": F3A6, + "numeric-1-circle": FC7C, + "numeric-1-circle-outline": FC7D, + "numeric-10": F000A, + "numeric-10-box": FF9A, + "numeric-10-box-multiple": F000B, + "numeric-10-box-multiple-outline": F000C, + "numeric-10-box-outline": FF9B, + "numeric-10-circle": F000D, + "numeric-10-circle-outline": F000E, + "numeric-2": 0032, + "numeric-2-box": F3A7, + "numeric-2-box-multiple": FF2D, + "numeric-2-box-multiple-outline": F3A8, + "numeric-2-box-outline": F3A9, + "numeric-2-circle": FC7E, + "numeric-2-circle-outline": FC7F, + "numeric-3": 0033, + "numeric-3-box": F3AA, + "numeric-3-box-multiple": FF2E, + "numeric-3-box-multiple-outline": F3AB, + "numeric-3-box-outline": F3AC, + "numeric-3-circle": FC80, + "numeric-3-circle-outline": FC81, + "numeric-4": 0034, + "numeric-4-box": F3AD, + "numeric-4-box-multiple": FF2F, + "numeric-4-box-multiple-outline": F3AE, + "numeric-4-box-outline": F3AF, + "numeric-4-circle": FC82, + "numeric-4-circle-outline": FC83, + "numeric-5": 0035, + "numeric-5-box": F3B0, + "numeric-5-box-multiple": FF30, + "numeric-5-box-multiple-outline": F3B1, + "numeric-5-box-outline": F3B2, + "numeric-5-circle": FC84, + "numeric-5-circle-outline": FC85, + "numeric-6": 0036, + "numeric-6-box": F3B3, + "numeric-6-box-multiple": FF31, + "numeric-6-box-multiple-outline": F3B4, + "numeric-6-box-outline": F3B5, + "numeric-6-circle": FC86, + "numeric-6-circle-outline": FC87, + "numeric-7": 0037, + "numeric-7-box": F3B6, + "numeric-7-box-multiple": FF32, + "numeric-7-box-multiple-outline": F3B7, + "numeric-7-box-outline": F3B8, + "numeric-7-circle": FC88, + "numeric-7-circle-outline": FC89, + "numeric-8": 0038, + "numeric-8-box": F3B9, + "numeric-8-box-multiple": FF33, + "numeric-8-box-multiple-outline": F3BA, + "numeric-8-box-outline": F3BB, + "numeric-8-circle": FC8A, + "numeric-8-circle-outline": FC8B, + "numeric-9": 0039, + "numeric-9-box": F3BC, + "numeric-9-box-multiple": FF34, + "numeric-9-box-multiple-outline": F3BD, + "numeric-9-box-outline": F3BE, + "numeric-9-circle": FC8C, + "numeric-9-circle-outline": FC8D, + "numeric-9-plus": F000F, + "numeric-9-plus-box": F3BF, + "numeric-9-plus-box-multiple": FF35, + "numeric-9-plus-box-multiple-outline": F3C0, + "numeric-9-plus-box-outline": F3C1, + "numeric-9-plus-circle": FC8E, + "numeric-9-plus-circle-outline": FC8F, + "numeric-negative-1": F0074, + "nut": F6F7, + "nutrition": F3C2, + "nuxt": F0131, + "oar": F67B, + "ocarina": FDBC, + "oci": F0314, + "ocr": F0165, + "octagon": F3C3, + "octagon-outline": F3C4, + "octagram": F6F8, + "octagram-outline": F774, + "odnoklassniki": F3C5, + "offer": F0246, + "office": F3C6, + "office-building": F990, + "oil": F3C7, + "oil-lamp": FF36, + "oil-level": F0075, + "oil-temperature": F0019, + "omega": F3C9, + "one-up": FB89, + "onedrive": F3CA, + "onenote": F746, + "onepassword": F880, + "opacity": F5CC, + "open-in-app": F3CB, + "open-in-new": F3CC, + "open-source-initiative": FB8A, + "openid": F3CD, + "opera": F3CE, + "orbit": F018, + "origin": FB2B, + "ornament": F3CF, + "ornament-variant": F3D0, + "outdoor-lamp": F0076, + "outlook": FCFE, + "overscan": F0027, + "owl": F3D2, + "pac-man": FB8B, + "package": F3D3, + "package-down": F3D4, + "package-up": F3D5, + "package-variant": F3D6, + "package-variant-closed": F3D7, + "page-first": F600, + "page-last": F601, + "page-layout-body": F6F9, + "page-layout-footer": F6FA, + "page-layout-header": F6FB, + "page-layout-header-footer": FF9C, + "page-layout-sidebar-left": F6FC, + "page-layout-sidebar-right": F6FD, + "page-next": FB8C, + "page-next-outline": FB8D, + "page-previous": FB8E, + "page-previous-outline": FB8F, + "palette": F3D8, + "palette-advanced": F3D9, + "palette-outline": FE6C, + "palette-swatch": F8B4, + "palm-tree": F0077, + "pan": FB90, + "pan-bottom-left": FB91, + "pan-bottom-right": FB92, + "pan-down": FB93, + "pan-horizontal": FB94, + "pan-left": FB95, + "pan-right": FB96, + "pan-top-left": FB97, + "pan-top-right": FB98, + "pan-up": FB99, + "pan-vertical": FB9A, + "panda": F3DA, + "pandora": F3DB, + "panorama": F3DC, + "panorama-fisheye": F3DD, + "panorama-horizontal": F3DE, + "panorama-vertical": F3DF, + "panorama-wide-angle": F3E0, + "paper-cut-vertical": F3E1, + "paper-roll": F0182, + "paper-roll-outline": F0183, + "paperclip": F3E2, + "parachute": FC90, + "parachute-outline": FC91, + "parking": F3E3, + "party-popper": F0078, + "passport": F7E2, + "passport-biometric": FDBD, + "pasta": F018B, + "patio-heater": FF9D, + "patreon": F881, + "pause": F3E4, + "pause-circle": F3E5, + "pause-circle-outline": F3E6, + "pause-octagon": F3E7, + "pause-octagon-outline": F3E8, + "paw": F3E9, + "paw-off": F657, + "paypal": F882, + "pdf-box": FE39, + "peace": F883, + "peanut": F001E, + "peanut-off": F001F, + "peanut-off-outline": F0021, + "peanut-outline": F0020, + "pen": F3EA, + "pen-lock": FDBE, + "pen-minus": FDBF, + "pen-off": FDC0, + "pen-plus": FDC1, + "pen-remove": FDC2, + "pencil": F3EB, + "pencil-box": F3EC, + "pencil-box-multiple": F016F, + "pencil-box-multiple-outline": F0170, + "pencil-box-outline": F3ED, + "pencil-circle": F6FE, + "pencil-circle-outline": F775, + "pencil-lock": F3EE, + "pencil-lock-outline": FDC3, + "pencil-minus": FDC4, + "pencil-minus-outline": FDC5, + "pencil-off": F3EF, + "pencil-off-outline": FDC6, + "pencil-outline": FC92, + "pencil-plus": FDC7, + "pencil-plus-outline": FDC8, + "pencil-remove": FDC9, + "pencil-remove-outline": FDCA, + "penguin": FEDD, + "pentagon": F6FF, + "pentagon-outline": F700, + "percent": F3F0, + "percent-outline": F02A3, + "periodic-table": F8B5, + "periodic-table-co": F0329, + "periodic-table-co2": F7E3, + "periscope": F747, + "perspective-less": FCFF, + "perspective-more": FD00, + "pharmacy": F3F1, + "phone": F3F2, + "phone-alert": FF37, + "phone-alert-outline": F01B9, + "phone-bluetooth": F3F3, + "phone-bluetooth-outline": F01BA, + "phone-cancel": F00E7, + "phone-cancel-outline": F01BB, + "phone-check": F01D4, + "phone-check-outline": F01D5, + "phone-classic": F602, + "phone-classic-off": F02A4, + "phone-forward": F3F4, + "phone-forward-outline": F01BC, + "phone-hangup": F3F5, + "phone-hangup-outline": F01BD, + "phone-in-talk": F3F6, + "phone-in-talk-outline": F01AD, + "phone-incoming": F3F7, + "phone-incoming-outline": F01BE, + "phone-lock": F3F8, + "phone-lock-outline": F01BF, + "phone-log": F3F9, + "phone-log-outline": F01C0, + "phone-message": F01C1, + "phone-message-outline": F01C2, + "phone-minus": F658, + "phone-minus-outline": F01C3, + "phone-missed": F3FA, + "phone-missed-outline": F01D0, + "phone-off": FDCB, + "phone-off-outline": F01D1, + "phone-outgoing": F3FB, + "phone-outgoing-outline": F01C4, + "phone-outline": FDCC, + "phone-paused": F3FC, + "phone-paused-outline": F01C5, + "phone-plus": F659, + "phone-plus-outline": F01C6, + "phone-return": F82E, + "phone-return-outline": F01C7, + "phone-ring": F01D6, + "phone-ring-outline": F01D7, + "phone-rotate-landscape": F884, + "phone-rotate-portrait": F885, + "phone-settings": F3FD, + "phone-settings-outline": F01C8, + "phone-voip": F3FE, + "pi": F3FF, + "pi-box": F400, + "pi-hole": FDCD, + "piano": F67C, + "pickaxe": F8B6, + "picture-in-picture-bottom-right": FE3A, + "picture-in-picture-bottom-right-outline": FE3B, + "picture-in-picture-top-right": FE3C, + "picture-in-picture-top-right-outline": FE3D, + "pier": F886, + "pier-crane": F887, + "pig": F401, + "pig-variant": F0028, + "piggy-bank": F0029, + "pill": F402, + "pillar": F701, + "pin": F403, + "pin-off": F404, + "pin-off-outline": F92F, + "pin-outline": F930, + "pine-tree": F405, + "pine-tree-box": F406, + "pinterest": F407, + "pinterest-box": F408, + "pinwheel": FAD4, + "pinwheel-outline": FAD5, + "pipe": F7E4, + "pipe-disconnected": F7E5, + "pipe-leak": F888, + "pirate": FA07, + "pistol": F702, + "piston": F889, + "pizza": F409, + "play": F40A, + "play-box": F02A5, + "play-box-outline": F40B, + "play-circle": F40C, + "play-circle-outline": F40D, + "play-network": F88A, + "play-network-outline": FC93, + "play-outline": FF38, + "play-pause": F40E, + "play-protected-content": F40F, + "play-speed": F8FE, + "playlist-check": F5C7, + "playlist-edit": F8FF, + "playlist-minus": F410, + "playlist-music": FC94, + "playlist-music-outline": FC95, + "playlist-play": F411, + "playlist-plus": F412, + "playlist-remove": F413, + "playlist-star": FDCE, + "playstation": F414, + "plex": F6B9, + "plus": F415, + "plus-box": F416, + "plus-box-multiple": F334, + "plus-box-multiple-outline": F016E, + "plus-box-outline": F703, + "plus-circle": F417, + "plus-circle-multiple-outline": F418, + "plus-circle-outline": F419, + "plus-minus": F991, + "plus-minus-box": F992, + "plus-network": F41A, + "plus-network-outline": FC96, + "plus-one": F41B, + "plus-outline": F704, + "plus-thick": F0217, + "pocket": F41C, + "podcast": F993, + "podium": FD01, + "podium-bronze": FD02, + "podium-gold": FD03, + "podium-silver": FD04, + "point-of-sale": FD6E, + "pokeball": F41D, + "pokemon-go": FA08, + "poker-chip": F82F, + "polaroid": F41E, + "police-badge": F0192, + "police-badge-outline": F0193, + "poll": F41F, + "poll-box": F420, + "poll-box-outline": F02A6, + "polymer": F421, + "pool": F606, + "popcorn": F422, + "post": F002A, + "post-outline": F002B, + "postage-stamp": FC97, + "pot": F65A, + "pot-mix": F65B, + "pound": F423, + "pound-box": F424, + "pound-box-outline": F01AA, + "power": F425, + "power-cycle": F900, + "power-off": F901, + "power-on": F902, + "power-plug": F6A4, + "power-plug-off": F6A5, + "power-settings": F426, + "power-sleep": F903, + "power-socket": F427, + "power-socket-au": F904, + "power-socket-de": F0132, + "power-socket-eu": F7E6, + "power-socket-fr": F0133, + "power-socket-jp": F0134, + "power-socket-uk": F7E7, + "power-socket-us": F7E8, + "power-standby": F905, + "powershell": FA09, + "prescription": F705, + "presentation": F428, + "presentation-play": F429, + "printer": F42A, + "printer-3d": F42B, + "printer-3d-nozzle": FE3E, + "printer-3d-nozzle-alert": F01EB, + "printer-3d-nozzle-alert-outline": F01EC, + "printer-3d-nozzle-outline": FE3F, + "printer-alert": F42C, + "printer-check": F0171, + "printer-off": FE40, + "printer-pos": F0079, + "printer-settings": F706, + "printer-wireless": FA0A, + "priority-high": F603, + "priority-low": F604, + "professional-hexagon": F42D, + "progress-alert": FC98, + "progress-check": F994, + "progress-clock": F995, + "progress-close": F0135, + "progress-download": F996, + "progress-upload": F997, + "progress-wrench": FC99, + "projector": F42E, + "projector-screen": F42F, + "protocol": FFF9, + "publish": F6A6, + "pulse": F430, + "pumpkin": FB9B, + "purse": FF39, + "purse-outline": FF3A, + "puzzle": F431, + "puzzle-outline": FA65, + "qi": F998, + "qqchat": F605, + "qrcode": F432, + "qrcode-edit": F8B7, + "qrcode-minus": F01B7, + "qrcode-plus": F01B6, + "qrcode-remove": F01B8, + "qrcode-scan": F433, + "quadcopter": F434, + "quality-high": F435, + "quality-low": FA0B, + "quality-medium": FA0C, + "quicktime": F436, + "quora": FD05, + "rabbit": F906, + "racing-helmet": FD6F, + "racquetball": FD70, + "radar": F437, + "radiator": F438, + "radiator-disabled": FAD6, + "radiator-off": FAD7, + "radio": F439, + "radio-am": FC9A, + "radio-fm": FC9B, + "radio-handheld": F43A, + "radio-off": F0247, + "radio-tower": F43B, + "radioactive": F43C, + "radioactive-off": FEDE, + "radiobox-blank": F43D, + "radiobox-marked": F43E, + "radius": FC9C, + "radius-outline": FC9D, + "railroad-light": FF3B, + "raspberry-pi": F43F, + "ray-end": F440, + "ray-end-arrow": F441, + "ray-start": F442, + "ray-start-arrow": F443, + "ray-start-end": F444, + "ray-vertex": F445, + "react": F707, + "read": F447, + "receipt": F449, + "record": F44A, + "record-circle": FEDF, + "record-circle-outline": FEE0, + "record-player": F999, + "record-rec": F44B, + "rectangle": FE41, + "rectangle-outline": FE42, + "recycle": F44C, + "reddit": F44D, + "redhat": F0146, + "redo": F44E, + "redo-variant": F44F, + "reflect-horizontal": FA0D, + "reflect-vertical": FA0E, + "refresh": F450, + "regex": F451, + "registered-trademark": FA66, + "relative-scale": F452, + "reload": F453, + "reload-alert": F0136, + "reminder": F88B, + "remote": F454, + "remote-desktop": F8B8, + "remote-off": FEE1, + "remote-tv": FEE2, + "remote-tv-off": FEE3, + "rename-box": F455, + "reorder-horizontal": F687, + "reorder-vertical": F688, + "repeat": F456, + "repeat-off": F457, + "repeat-once": F458, + "replay": F459, + "reply": F45A, + "reply-all": F45B, + "reply-all-outline": FF3C, + "reply-circle": F01D9, + "reply-outline": FF3D, + "reproduction": F45C, + "resistor": FB1F, + "resistor-nodes": FB20, + "resize": FA67, + "resize-bottom-right": F45D, + "responsive": F45E, + "restart": F708, + "restart-alert": F0137, + "restart-off": FD71, + "restore": F99A, + "restore-alert": F0138, + "rewind": F45F, + "rewind-10": FD06, + "rewind-30": FD72, + "rewind-5": F0224, + "rewind-outline": F709, + "rhombus": F70A, + "rhombus-medium": FA0F, + "rhombus-outline": F70B, + "rhombus-split": FA10, + "ribbon": F460, + "rice": F7E9, + "ring": F7EA, + "rivet": FE43, + "road": F461, + "road-variant": F462, + "robber": F007A, + "robot": F6A8, + "robot-industrial": FB21, + "robot-mower": F0222, + "robot-mower-outline": F021E, + "robot-vacuum": F70C, + "robot-vacuum-variant": F907, + "rocket": F463, + "roller-skate": FD07, + "rollerblade": FD08, + "rollupjs": FB9C, + "roman-numeral-1": F00B3, + "roman-numeral-10": F00BC, + "roman-numeral-2": F00B4, + "roman-numeral-3": F00B5, + "roman-numeral-4": F00B6, + "roman-numeral-5": F00B7, + "roman-numeral-6": F00B8, + "roman-numeral-7": F00B9, + "roman-numeral-8": F00BA, + "roman-numeral-9": F00BB, + "room-service": F88C, + "room-service-outline": FD73, + "rotate-3d": FEE4, + "rotate-3d-variant": F464, + "rotate-left": F465, + "rotate-left-variant": F466, + "rotate-orbit": FD74, + "rotate-right": F467, + "rotate-right-variant": F468, + "rounded-corner": F607, + "router": F020D, + "router-wireless": F469, + "router-wireless-settings": FA68, + "routes": F46A, + "routes-clock": F007B, + "rowing": F608, + "rss": F46B, + "rss-box": F46C, + "rss-off": FF3E, + "ruby": FD09, + "rugby": FD75, + "ruler": F46D, + "ruler-square": FC9E, + "ruler-square-compass": FEDB, + "run": F70D, + "run-fast": F46E, + "rv-truck": F01FF, + "sack": FD0A, + "sack-percent": FD0B, + "safe": FA69, + "safe-square": F02A7, + "safe-square-outline": F02A8, + "safety-goggles": FD0C, + "sailing": FEE5, + "sale": F46F, + "salesforce": F88D, + "sass": F7EB, + "satellite": F470, + "satellite-uplink": F908, + "satellite-variant": F471, + "sausage": F8B9, + "saw-blade": FE44, + "saxophone": F609, + "scale": F472, + "scale-balance": F5D1, + "scale-bathroom": F473, + "scale-off": F007C, + "scanner": F6AA, + "scanner-off": F909, + "scatter-plot": FEE6, + "scatter-plot-outline": FEE7, + "school": F474, + "school-outline": F01AB, + "scissors-cutting": FA6A, + "scooter": F0214, + "scoreboard": F02A9, + "scoreboard-outline": F02AA, + "screen-rotation": F475, + "screen-rotation-lock": F476, + "screw-flat-top": FDCF, + "screw-lag": FE54, + "screw-machine-flat-top": FE55, + "screw-machine-round-top": FE56, + "screw-round-top": FE57, + "screwdriver": F477, + "script": FB9D, + "script-outline": F478, + "script-text": FB9E, + "script-text-outline": FB9F, + "sd": F479, + "seal": F47A, + "seal-variant": FFFA, + "search-web": F70E, + "seat": FC9F, + "seat-flat": F47B, + "seat-flat-angled": F47C, + "seat-individual-suite": F47D, + "seat-legroom-extra": F47E, + "seat-legroom-normal": F47F, + "seat-legroom-reduced": F480, + "seat-outline": FCA0, + "seat-passenger": F0274, + "seat-recline-extra": F481, + "seat-recline-normal": F482, + "seatbelt": FCA1, + "security": F483, + "security-network": F484, + "seed": FE45, + "seed-outline": FE46, + "segment": FEE8, + "select": F485, + "select-all": F486, + "select-color": FD0D, + "select-compare": FAD8, + "select-drag": FA6B, + "select-group": FF9F, + "select-inverse": F487, + "select-marker": F02AB, + "select-multiple": F02AC, + "select-multiple-marker": F02AD, + "select-off": F488, + "select-place": FFFB, + "select-search": F022F, + "selection": F489, + "selection-drag": FA6C, + "selection-ellipse": FD0E, + "selection-ellipse-arrow-inside": FF3F, + "selection-marker": F02AE, + "selection-multiple-marker": F02AF, + "selection-mutliple": F02B0, + "selection-off": F776, + "selection-search": F0230, + "semantic-web": F0341, + "send": F48A, + "send-check": F018C, + "send-check-outline": F018D, + "send-circle": FE58, + "send-circle-outline": FE59, + "send-clock": F018E, + "send-clock-outline": F018F, + "send-lock": F7EC, + "send-lock-outline": F0191, + "send-outline": F0190, + "serial-port": F65C, + "server": F48B, + "server-minus": F48C, + "server-network": F48D, + "server-network-off": F48E, + "server-off": F48F, + "server-plus": F490, + "server-remove": F491, + "server-security": F492, + "set-all": F777, + "set-center": F778, + "set-center-right": F779, + "set-left": F77A, + "set-left-center": F77B, + "set-left-right": F77C, + "set-none": F77D, + "set-right": F77E, + "set-top-box": F99E, + "settings": F493, + "settings-box": F494, + "settings-helper": FA6D, + "settings-outline": F8BA, + "settings-transfer": F007D, + "settings-transfer-outline": F007E, + "shaker": F0139, + "shaker-outline": F013A, + "shape": F830, + "shape-circle-plus": F65D, + "shape-outline": F831, + "shape-oval-plus": F0225, + "shape-plus": F495, + "shape-polygon-plus": F65E, + "shape-rectangle-plus": F65F, + "shape-square-plus": F660, + "share": F496, + "share-all": F021F, + "share-all-outline": F0220, + "share-circle": F01D8, + "share-off": FF40, + "share-off-outline": FF41, + "share-outline": F931, + "share-variant": F497, + "sheep": FCA2, + "shield": F498, + "shield-account": F88E, + "shield-account-outline": FA11, + "shield-airplane": F6BA, + "shield-airplane-outline": FCA3, + "shield-alert": FEE9, + "shield-alert-outline": FEEA, + "shield-car": FFA0, + "shield-check": F565, + "shield-check-outline": FCA4, + "shield-cross": FCA5, + "shield-cross-outline": FCA6, + "shield-edit": F01CB, + "shield-edit-outline": F01CC, + "shield-half-full": F77F, + "shield-home": F689, + "shield-home-outline": FCA7, + "shield-key": FBA0, + "shield-key-outline": FBA1, + "shield-link-variant": FD0F, + "shield-link-variant-outline": FD10, + "shield-lock": F99C, + "shield-lock-outline": FCA8, + "shield-off": F99D, + "shield-off-outline": F99B, + "shield-outline": F499, + "shield-plus": FAD9, + "shield-plus-outline": FADA, + "shield-refresh": F01CD, + "shield-refresh-outline": F01CE, + "shield-remove": FADB, + "shield-remove-outline": FADC, + "shield-search": FD76, + "shield-star": F0166, + "shield-star-outline": F0167, + "shield-sun": F007F, + "shield-sun-outline": F0080, + "ship-wheel": F832, + "shoe-formal": FB22, + "shoe-heel": FB23, + "shoe-print": FE5A, + "shopify": FADD, + "shopping": F49A, + "shopping-music": F49B, + "shopping-outline": F0200, + "shopping-search": FFA1, + "shovel": F70F, + "shovel-off": F710, + "shower": F99F, + "shower-head": F9A0, + "shredder": F49C, + "shuffle": F49D, + "shuffle-disabled": F49E, + "shuffle-variant": F49F, + "sigma": F4A0, + "sigma-lower": F62B, + "sign-caution": F4A1, + "sign-direction": F780, + "sign-direction-minus": F0022, + "sign-direction-plus": FFFD, + "sign-direction-remove": FFFE, + "sign-real-estate": F0143, + "sign-text": F781, + "signal": F4A2, + "signal-2g": F711, + "signal-3g": F712, + "signal-4g": F713, + "signal-5g": FA6E, + "signal-cellular-1": F8BB, + "signal-cellular-2": F8BC, + "signal-cellular-3": F8BD, + "signal-cellular-outline": F8BE, + "signal-distance-variant": FE47, + "signal-hspa": F714, + "signal-hspa-plus": F715, + "signal-off": F782, + "signal-variant": F60A, + "signature": FE5B, + "signature-freehand": FE5C, + "signature-image": FE5D, + "signature-text": FE5E, + "silo": FB24, + "silverware": F4A3, + "silverware-clean": FFFF, + "silverware-fork": F4A4, + "silverware-fork-knife": FA6F, + "silverware-spoon": F4A5, + "silverware-variant": F4A6, + "sim": F4A7, + "sim-alert": F4A8, + "sim-off": F4A9, + "simple-icons": F0348, + "sina-weibo": FADE, + "sitemap": F4AA, + "skate": FD11, + "skew-less": FD12, + "skew-more": FD13, + "ski": F032F, + "ski-cross-country": F0330, + "ski-water": F0331, + "skip-backward": F4AB, + "skip-backward-outline": FF42, + "skip-forward": F4AC, + "skip-forward-outline": FF43, + "skip-next": F4AD, + "skip-next-circle": F661, + "skip-next-circle-outline": F662, + "skip-next-outline": FF44, + "skip-previous": F4AE, + "skip-previous-circle": F663, + "skip-previous-circle-outline": F664, + "skip-previous-outline": FF45, + "skull": F68B, + "skull-crossbones": FBA2, + "skull-crossbones-outline": FBA3, + "skull-outline": FBA4, + "skype": F4AF, + "skype-business": F4B0, + "slack": F4B1, + "slackware": F90A, + "slash-forward": F0000, + "slash-forward-box": F0001, + "sleep": F4B2, + "sleep-off": F4B3, + "slope-downhill": FE5F, + "slope-uphill": FE60, + "slot-machine": F013F, + "slot-machine-outline": F0140, + "smart-card": F00E8, + "smart-card-outline": F00E9, + "smart-card-reader": F00EA, + "smart-card-reader-outline": F00EB, + "smog": FA70, + "smoke-detector": F392, + "smoking": F4B4, + "smoking-off": F4B5, + "snapchat": F4B6, + "snowboard": F0332, + "snowflake": F716, + "snowflake-alert": FF46, + "snowflake-melt": F02F6, + "snowflake-variant": FF47, + "snowman": F4B7, + "soccer": F4B8, + "soccer-field": F833, + "sofa": F4B9, + "solar-panel": FD77, + "solar-panel-large": FD78, + "solar-power": FA71, + "soldering-iron": F00BD, + "solid": F68C, + "sort": F4BA, + "sort-alphabetical": F4BB, + "sort-alphabetical-ascending": F0173, + "sort-alphabetical-descending": F0174, + "sort-ascending": F4BC, + "sort-descending": F4BD, + "sort-numeric": F4BE, + "sort-variant": F4BF, + "sort-variant-lock": FCA9, + "sort-variant-lock-open": FCAA, + "sort-variant-remove": F0172, + "soundcloud": F4C0, + "source-branch": F62C, + "source-commit": F717, + "source-commit-end": F718, + "source-commit-end-local": F719, + "source-commit-local": F71A, + "source-commit-next-local": F71B, + "source-commit-start": F71C, + "source-commit-start-next-local": F71D, + "source-fork": F4C1, + "source-merge": F62D, + "source-pull": F4C2, + "source-repository": FCAB, + "source-repository-multiple": FCAC, + "soy-sauce": F7ED, + "spa": FCAD, + "spa-outline": FCAE, + "space-invaders": FBA5, + "spade": FE48, + "speaker": F4C3, + "speaker-bluetooth": F9A1, + "speaker-multiple": FD14, + "speaker-off": F4C4, + "speaker-wireless": F71E, + "speedometer": F4C5, + "speedometer-medium": FFA2, + "speedometer-slow": FFA3, + "spellcheck": F4C6, + "spider": F0215, + "spider-thread": F0216, + "spider-web": FBA6, + "spotify": F4C7, + "spotlight": F4C8, + "spotlight-beam": F4C9, + "spray": F665, + "spray-bottle": FADF, + "sprinkler": F0081, + "sprinkler-variant": F0082, + "sprout": FE49, + "sprout-outline": FE4A, + "square": F763, + "square-edit-outline": F90B, + "square-inc": F4CA, + "square-inc-cash": F4CB, + "square-medium": FA12, + "square-medium-outline": FA13, + "square-off": F0319, + "square-off-outline": F031A, + "square-outline": F762, + "square-root": F783, + "square-root-box": F9A2, + "square-small": FA14, + "squeegee": FAE0, + "ssh": F8BF, + "stack-exchange": F60B, + "stack-overflow": F4CC, + "stackpath": F359, + "stadium": F001A, + "stadium-variant": F71F, + "stairs": F4CD, + "stairs-down": F02E9, + "stairs-up": F02E8, + "stamper": FD15, + "standard-definition": F7EE, + "star": F4CE, + "star-box": FA72, + "star-box-multiple": F02B1, + "star-box-multiple-outline": F02B2, + "star-box-outline": FA73, + "star-circle": F4CF, + "star-circle-outline": F9A3, + "star-face": F9A4, + "star-four-points": FAE1, + "star-four-points-outline": FAE2, + "star-half": F4D0, + "star-off": F4D1, + "star-outline": F4D2, + "star-three-points": FAE3, + "star-three-points-outline": FAE4, + "state-machine": F021A, + "steam": F4D3, + "steam-box": F90C, + "steering": F4D4, + "steering-off": F90D, + "step-backward": F4D5, + "step-backward-2": F4D6, + "step-forward": F4D7, + "step-forward-2": F4D8, + "stethoscope": F4D9, + "sticker": F5D0, + "sticker-emoji": F784, + "stocking": F4DA, + "stomach": F00BE, + "stop": F4DB, + "stop-circle": F666, + "stop-circle-outline": F667, + "store": F4DC, + "store-24-hour": F4DD, + "storefront": F00EC, + "stove": F4DE, + "strategy": F0201, + "strava": FB25, + "stretch-to-page": FF48, + "stretch-to-page-outline": FF49, + "string-lights": F02E5, + "string-lights-off": F02E6, + "subdirectory-arrow-left": F60C, + "subdirectory-arrow-right": F60D, + "subtitles": FA15, + "subtitles-outline": FA16, + "subway": F6AB, + "subway-alert-variant": FD79, + "subway-variant": F4DF, + "summit": F785, + "sunglasses": F4E0, + "surround-sound": F5C5, + "surround-sound-2-0": F7EF, + "surround-sound-3-1": F7F0, + "surround-sound-5-1": F7F1, + "surround-sound-7-1": F7F2, + "svg": F720, + "swap-horizontal": F4E1, + "swap-horizontal-bold": FBA9, + "swap-horizontal-circle": F0002, + "swap-horizontal-circle-outline": F0003, + "swap-horizontal-variant": F8C0, + "swap-vertical": F4E2, + "swap-vertical-bold": FBAA, + "swap-vertical-circle": F0004, + "swap-vertical-circle-outline": F0005, + "swap-vertical-variant": F8C1, + "swim": F4E3, + "switch": F4E4, + "sword": F4E5, + "sword-cross": F786, + "symfony": FAE5, + "sync": F4E6, + "sync-alert": F4E7, + "sync-off": F4E8, + "tab": F4E9, + "tab-minus": FB26, + "tab-plus": F75B, + "tab-remove": FB27, + "tab-unselected": F4EA, + "table": F4EB, + "table-border": FA17, + "table-chair": F0083, + "table-column": F834, + "table-column-plus-after": F4EC, + "table-column-plus-before": F4ED, + "table-column-remove": F4EE, + "table-column-width": F4EF, + "table-edit": F4F0, + "table-eye": F00BF, + "table-headers-eye": F0248, + "table-headers-eye-off": F0249, + "table-large": F4F1, + "table-large-plus": FFA4, + "table-large-remove": FFA5, + "table-merge-cells": F9A5, + "table-of-contents": F835, + "table-plus": FA74, + "table-remove": FA75, + "table-row": F836, + "table-row-height": F4F2, + "table-row-plus-after": F4F3, + "table-row-plus-before": F4F4, + "table-row-remove": F4F5, + "table-search": F90E, + "table-settings": F837, + "table-tennis": FE4B, + "tablet": F4F6, + "tablet-android": F4F7, + "tablet-cellphone": F9A6, + "tablet-dashboard": FEEB, + "tablet-ipad": F4F8, + "taco": F761, + "tag": F4F9, + "tag-faces": F4FA, + "tag-heart": F68A, + "tag-heart-outline": FBAB, + "tag-minus": F90F, + "tag-minus-outline": F024A, + "tag-multiple": F4FB, + "tag-multiple-outline": F0322, + "tag-off": F024B, + "tag-off-outline": F024C, + "tag-outline": F4FC, + "tag-plus": F721, + "tag-plus-outline": F024D, + "tag-remove": F722, + "tag-remove-outline": F024E, + "tag-text": F024F, + "tag-text-outline": F4FD, + "tank": FD16, + "tanker-truck": F0006, + "tape-measure": FB28, + "target": F4FE, + "target-account": FBAC, + "target-variant": FA76, + "taxi": F4FF, + "tea": FD7A, + "tea-outline": FD7B, + "teach": F88F, + "teamviewer": F500, + "telegram": F501, + "telescope": FB29, + "television": F502, + "television-box": F838, + "television-classic": F7F3, + "television-classic-off": F839, + "television-clean": F013B, + "television-guide": F503, + "television-off": F83A, + "television-pause": FFA6, + "television-play": FEEC, + "television-stop": FFA7, + "temperature-celsius": F504, + "temperature-fahrenheit": F505, + "temperature-kelvin": F506, + "tennis": FD7C, + "tennis-ball": F507, + "tent": F508, + "terraform": F0084, + "terrain": F509, + "test-tube": F668, + "test-tube-empty": F910, + "test-tube-off": F911, + "text": F9A7, + "text-recognition": F0168, + "text-shadow": F669, + "text-short": F9A8, + "text-subject": F9A9, + "text-to-speech": F50A, + "text-to-speech-off": F50B, + "textarea": F00C0, + "textbox": F60E, + "textbox-password": F7F4, + "texture": F50C, + "texture-box": F0007, + "theater": F50D, + "theme-light-dark": F50E, + "thermometer": F50F, + "thermometer-alert": FE61, + "thermometer-chevron-down": FE62, + "thermometer-chevron-up": FE63, + "thermometer-high": F00ED, + "thermometer-lines": F510, + "thermometer-low": F00EE, + "thermometer-minus": FE64, + "thermometer-plus": FE65, + "thermostat": F393, + "thermostat-box": F890, + "thought-bubble": F7F5, + "thought-bubble-outline": F7F6, + "thumb-down": F511, + "thumb-down-outline": F512, + "thumb-up": F513, + "thumb-up-outline": F514, + "thumbs-up-down": F515, + "ticket": F516, + "ticket-account": F517, + "ticket-confirmation": F518, + "ticket-outline": F912, + "ticket-percent": F723, + "tie": F519, + "tilde": F724, + "timelapse": F51A, + "timeline": FBAD, + "timeline-alert": FFB2, + "timeline-alert-outline": FFB5, + "timeline-clock": F0226, + "timeline-clock-outline": F0227, + "timeline-help": FFB6, + "timeline-help-outline": FFB7, + "timeline-outline": FBAE, + "timeline-plus": FFB3, + "timeline-plus-outline": FFB4, + "timeline-text": FBAF, + "timeline-text-outline": FBB0, + "timer": F51B, + "timer-10": F51C, + "timer-3": F51D, + "timer-off": F51E, + "timer-sand": F51F, + "timer-sand-empty": F6AC, + "timer-sand-full": F78B, + "timetable": F520, + "toaster": F0085, + "toaster-off": F01E2, + "toaster-oven": FCAF, + "toggle-switch": F521, + "toggle-switch-off": F522, + "toggle-switch-off-outline": FA18, + "toggle-switch-outline": FA19, + "toilet": F9AA, + "toolbox": F9AB, + "toolbox-outline": F9AC, + "tools": F0086, + "tooltip": F523, + "tooltip-account": F00C, + "tooltip-edit": F524, + "tooltip-edit-outline": F02F0, + "tooltip-image": F525, + "tooltip-image-outline": FBB1, + "tooltip-outline": F526, + "tooltip-plus": FBB2, + "tooltip-plus-outline": F527, + "tooltip-text": F528, + "tooltip-text-outline": FBB3, + "tooth": F8C2, + "tooth-outline": F529, + "toothbrush": F0154, + "toothbrush-electric": F0157, + "toothbrush-paste": F0155, + "tor": F52A, + "tortoise": FD17, + "toslink": F02E3, + "tournament": F9AD, + "tower-beach": F680, + "tower-fire": F681, + "towing": F83B, + "toy-brick": F02B3, + "toy-brick-marker": F02B4, + "toy-brick-marker-outline": F02B5, + "toy-brick-minus": F02B6, + "toy-brick-minus-outline": F02B7, + "toy-brick-outline": F02B8, + "toy-brick-plus": F02B9, + "toy-brick-plus-outline": F02BA, + "toy-brick-remove": F02BB, + "toy-brick-remove-outline": F02BC, + "toy-brick-search": F02BD, + "toy-brick-search-outline": F02BE, + "track-light": F913, + "trackpad": F7F7, + "trackpad-lock": F932, + "tractor": F891, + "trademark": FA77, + "traffic-light": F52B, + "train": F52C, + "train-car": FBB4, + "train-variant": F8C3, + "tram": F52D, + "tram-side": F0008, + "transcribe": F52E, + "transcribe-close": F52F, + "transfer": F0087, + "transfer-down": FD7D, + "transfer-left": FD7E, + "transfer-right": F530, + "transfer-up": FD7F, + "transit-connection": FD18, + "transit-connection-variant": FD19, + "transit-detour": FFA8, + "transit-transfer": F6AD, + "transition": F914, + "transition-masked": F915, + "translate": F5CA, + "translate-off": FE66, + "transmission-tower": FD1A, + "trash-can": FA78, + "trash-can-outline": FA79, + "tray": F02BF, + "tray-alert": F02C0, + "tray-full": F02C1, + "tray-minus": F02C2, + "tray-plus": F02C3, + "tray-remove": F02C4, + "treasure-chest": F725, + "tree": F531, + "tree-outline": FE4C, + "trello": F532, + "trending-down": F533, + "trending-neutral": F534, + "trending-up": F535, + "triangle": F536, + "triangle-outline": F537, + "triforce": FBB5, + "trophy": F538, + "trophy-award": F539, + "trophy-broken": FD80, + "trophy-outline": F53A, + "trophy-variant": F53B, + "trophy-variant-outline": F53C, + "truck": F53D, + "truck-check": FCB0, + "truck-check-outline": F02C5, + "truck-delivery": F53E, + "truck-delivery-outline": F02C6, + "truck-fast": F787, + "truck-fast-outline": F02C7, + "truck-outline": F02C8, + "truck-trailer": F726, + "trumpet": F00C1, + "tshirt-crew": FA7A, + "tshirt-crew-outline": F53F, + "tshirt-v": FA7B, + "tshirt-v-outline": F540, + "tumble-dryer": F916, + "tumble-dryer-alert": F01E5, + "tumble-dryer-off": F01E6, + "tumblr": F541, + "tumblr-box": F917, + "tumblr-reblog": F542, + "tune": F62E, + "tune-vertical": F66A, + "turnstile": FCB1, + "turnstile-outline": FCB2, + "turtle": FCB3, + "twitch": F543, + "twitter": F544, + "twitter-box": F545, + "twitter-circle": F546, + "twitter-retweet": F547, + "two-factor-authentication": F9AE, + "typewriter": FF4A, + "uber": F748, + "ubisoft": FBB6, + "ubuntu": F548, + "ufo": F00EF, + "ufo-outline": F00F0, + "ultra-high-definition": F7F8, + "umbraco": F549, + "umbrella": F54A, + "umbrella-closed": F9AF, + "umbrella-outline": F54B, + "undo": F54C, + "undo-variant": F54D, + "unfold-less-horizontal": F54E, + "unfold-less-vertical": F75F, + "unfold-more-horizontal": F54F, + "unfold-more-vertical": F760, + "ungroup": F550, + "unicode": FEED, + "unity": F6AE, + "unreal": F9B0, + "untappd": F551, + "update": F6AF, + "upload": F552, + "upload-multiple": F83C, + "upload-network": F6F5, + "upload-network-outline": FCB4, + "upload-off": F00F1, + "upload-off-outline": F00F2, + "upload-outline": FE67, + "usb": F553, + "usb-flash-drive": F02C9, + "usb-flash-drive-outline": F02CA, + "usb-port": F021B, + "valve": F0088, + "valve-closed": F0089, + "valve-open": F008A, + "van-passenger": F7F9, + "van-utility": F7FA, + "vanish": F7FB, + "vanity-light": F020C, + "variable": FAE6, + "variable-box": F013C, + "vector-arrange-above": F554, + "vector-arrange-below": F555, + "vector-bezier": FAE7, + "vector-circle": F556, + "vector-circle-variant": F557, + "vector-combine": F558, + "vector-curve": F559, + "vector-difference": F55A, + "vector-difference-ab": F55B, + "vector-difference-ba": F55C, + "vector-ellipse": F892, + "vector-intersection": F55D, + "vector-line": F55E, + "vector-link": F0009, + "vector-point": F55F, + "vector-polygon": F560, + "vector-polyline": F561, + "vector-polyline-edit": F0250, + "vector-polyline-minus": F0251, + "vector-polyline-plus": F0252, + "vector-polyline-remove": F0253, + "vector-radius": F749, + "vector-rectangle": F5C6, + "vector-selection": F562, + "vector-square": F001, + "vector-triangle": F563, + "vector-union": F564, + "venmo": F578, + "vhs": FA1A, + "vibrate": F566, + "vibrate-off": FCB5, + "video": F567, + "video-3d": F7FC, + "video-3d-variant": FEEE, + "video-4k-box": F83D, + "video-account": F918, + "video-check": F008B, + "video-check-outline": F008C, + "video-image": F919, + "video-input-antenna": F83E, + "video-input-component": F83F, + "video-input-hdmi": F840, + "video-input-scart": FFA9, + "video-input-svideo": F841, + "video-minus": F9B1, + "video-off": F568, + "video-off-outline": FBB7, + "video-outline": FBB8, + "video-plus": F9B2, + "video-stabilization": F91A, + "video-switch": F569, + "video-vintage": FA1B, + "video-wireless": FEEF, + "video-wireless-outline": FEF0, + "view-agenda": F56A, + "view-agenda-outline": F0203, + "view-array": F56B, + "view-carousel": F56C, + "view-column": F56D, + "view-comfy": FE4D, + "view-compact": FE4E, + "view-compact-outline": FE4F, + "view-dashboard": F56E, + "view-dashboard-outline": FA1C, + "view-dashboard-variant": F842, + "view-day": F56F, + "view-grid": F570, + "view-grid-outline": F0204, + "view-grid-plus": FFAA, + "view-grid-plus-outline": F0205, + "view-headline": F571, + "view-list": F572, + "view-module": F573, + "view-parallel": F727, + "view-quilt": F574, + "view-sequential": F728, + "view-split-horizontal": FBA7, + "view-split-vertical": FBA8, + "view-stream": F575, + "view-week": F576, + "vimeo": F577, + "violin": F60F, + "virtual-reality": F893, + "visual-studio": F610, + "visual-studio-code": FA1D, + "vk": F579, + "vk-box": F57A, + "vk-circle": F57B, + "vlc": F57C, + "voice": F5CB, + "voice-off": FEF1, + "voicemail": F57D, + "volleyball": F9B3, + "volume-high": F57E, + "volume-low": F57F, + "volume-medium": F580, + "volume-minus": F75D, + "volume-mute": F75E, + "volume-off": F581, + "volume-plus": F75C, + "volume-source": F014B, + "volume-variant-off": FE68, + "volume-vibrate": F014C, + "vote": FA1E, + "vote-outline": FA1F, + "vpn": F582, + "vuejs": F843, + "vuetify": FE50, + "walk": F583, + "wall": F7FD, + "wall-sconce": F91B, + "wall-sconce-flat": F91C, + "wall-sconce-variant": F91D, + "wallet": F584, + "wallet-giftcard": F585, + "wallet-membership": F586, + "wallet-outline": FBB9, + "wallet-plus": FFAB, + "wallet-plus-outline": FFAC, + "wallet-travel": F587, + "wallpaper": FE69, + "wan": F588, + "wardrobe": FFAD, + "wardrobe-outline": FFAE, + "warehouse": FFBB, + "washing-machine": F729, + "washing-machine-alert": F01E7, + "washing-machine-off": F01E8, + "watch": F589, + "watch-export": F58A, + "watch-export-variant": F894, + "watch-import": F58B, + "watch-import-variant": F895, + "watch-variant": F896, + "watch-vibrate": F6B0, + "watch-vibrate-off": FCB6, + "water": F58C, + "water-boiler": FFAF, + "water-boiler-alert": F01DE, + "water-boiler-off": F01DF, + "water-off": F58D, + "water-outline": FE6A, + "water-percent": F58E, + "water-polo": F02CB, + "water-pump": F58F, + "water-pump-off": FFB0, + "water-well": F008D, + "water-well-outline": F008E, + "watermark": F612, + "wave": FF4B, + "waves": F78C, + "waze": FBBA, + "weather-cloudy": F590, + "weather-cloudy-alert": FF4C, + "weather-cloudy-arrow-right": FE51, + "weather-fog": F591, + "weather-hail": F592, + "weather-hazy": FF4D, + "weather-hurricane": F897, + "weather-lightning": F593, + "weather-lightning-rainy": F67D, + "weather-night": F594, + "weather-night-partly-cloudy": FF4E, + "weather-partly-cloudy": F595, + "weather-partly-lightning": FF4F, + "weather-partly-rainy": FF50, + "weather-partly-snowy": FF51, + "weather-partly-snowy-rainy": FF52, + "weather-pouring": F596, + "weather-rainy": F597, + "weather-snowy": F598, + "weather-snowy-heavy": FF53, + "weather-snowy-rainy": F67E, + "weather-sunny": F599, + "weather-sunny-alert": FF54, + "weather-sunset": F59A, + "weather-sunset-down": F59B, + "weather-sunset-up": F59C, + "weather-tornado": FF55, + "weather-windy": F59D, + "weather-windy-variant": F59E, + "web": F59F, + "web-box": FFB1, + "web-clock": F0275, + "webcam": F5A0, + "webhook": F62F, + "webpack": F72A, + "webrtc": F0273, + "wechat": F611, + "weight": F5A1, + "weight-gram": FD1B, + "weight-kilogram": F5A2, + "weight-lifter": F0188, + "weight-pound": F9B4, + "whatsapp": F5A3, + "wheelchair-accessibility": F5A4, + "whistle": F9B5, + "whistle-outline": F02E7, + "white-balance-auto": F5A5, + "white-balance-incandescent": F5A6, + "white-balance-iridescent": F5A7, + "white-balance-sunny": F5A8, + "widgets": F72B, + "wifi": F5A9, + "wifi-off": F5AA, + "wifi-star": FE6B, + "wifi-strength-1": F91E, + "wifi-strength-1-alert": F91F, + "wifi-strength-1-lock": F920, + "wifi-strength-2": F921, + "wifi-strength-2-alert": F922, + "wifi-strength-2-lock": F923, + "wifi-strength-3": F924, + "wifi-strength-3-alert": F925, + "wifi-strength-3-lock": F926, + "wifi-strength-4": F927, + "wifi-strength-4-alert": F928, + "wifi-strength-4-lock": F929, + "wifi-strength-alert-outline": F92A, + "wifi-strength-lock-outline": F92B, + "wifi-strength-off": F92C, + "wifi-strength-off-outline": F92D, + "wifi-strength-outline": F92E, + "wii": F5AB, + "wiiu": F72C, + "wikipedia": F5AC, + "wind-turbine": FD81, + "window-close": F5AD, + "window-closed": F5AE, + "window-closed-variant": F0206, + "window-maximize": F5AF, + "window-minimize": F5B0, + "window-open": F5B1, + "window-open-variant": F0207, + "window-restore": F5B2, + "window-shutter": F0147, + "window-shutter-alert": F0148, + "window-shutter-open": F0149, + "windows": F5B3, + "windows-classic": FA20, + "wiper": FAE8, + "wiper-wash": FD82, + "wordpress": F5B4, + "worker": F5B5, + "wrap": F5B6, + "wrap-disabled": FBBB, + "wrench": F5B7, + "wrench-outline": FBBC, + "wunderlist": F5B8, + "xamarin": F844, + "xamarin-outline": F845, + "xaml": F673, + "xbox": F5B9, + "xbox-controller": F5BA, + "xbox-controller-battery-alert": F74A, + "xbox-controller-battery-charging": FA21, + "xbox-controller-battery-empty": F74B, + "xbox-controller-battery-full": F74C, + "xbox-controller-battery-low": F74D, + "xbox-controller-battery-medium": F74E, + "xbox-controller-battery-unknown": F74F, + "xbox-controller-menu": FE52, + "xbox-controller-off": F5BB, + "xbox-controller-view": FE53, + "xda": F5BC, + "xing": F5BD, + "xing-box": F5BE, + "xing-circle": F5BF, + "xml": F5C0, + "xmpp": F7FE, + "yahoo": FB2A, + "yammer": F788, + "yeast": F5C1, + "yelp": F5C2, + "yin-yang": F67F, + "yoga": F01A7, + "youtube": F5C3, + "youtube-creator-studio": F846, + "youtube-gaming": F847, + "youtube-subscription": FD1C, + "youtube-tv": F448, + "z-wave": FAE9, + "zend": FAEA, + "zigbee": FD1D, + "zip-box": F5C4, + "zip-box-outline": F001B, + "zip-disk": FA22, + "zodiac-aquarius": FA7C, + "zodiac-aries": FA7D, + "zodiac-cancer": FA7E, + "zodiac-capricorn": FA7F, + "zodiac-gemini": FA80, + "zodiac-leo": FA81, + "zodiac-libra": FA82, + "zodiac-pisces": FA83, + "zodiac-sagittarius": FA84, + "zodiac-scorpio": FA85, + "zodiac-taurus": FA86, + "zodiac-virgo": FA87 +); \ No newline at end of file diff --git a/themes/helm/assets/sass/materialdesignicons/materialdesignicons.scss b/themes/helm/assets/sass/materialdesignicons/materialdesignicons.scss new file mode 100644 index 0000000000..235314591c --- /dev/null +++ b/themes/helm/assets/sass/materialdesignicons/materialdesignicons.scss @@ -0,0 +1,8 @@ +/* MaterialDesignIcons.com */ +@import "variables"; +@import "functions"; +@import "path"; +@import "core"; +@import "icons"; +@import "extras"; +@import "animated"; \ No newline at end of file diff --git a/themes/helm/assets/sass/styles.scss b/themes/helm/assets/sass/styles.scss new file mode 100755 index 0000000000..70d34816aa --- /dev/null +++ b/themes/helm/assets/sass/styles.scss @@ -0,0 +1,26 @@ +/* == +Helm +*/ + +// load vendor libraries +@import "./materialdesignicons/materialdesignicons.scss"; +@import "./bulma/bulma.sass"; + +// load helm styles +@import "helm-mixins.scss"; +@import "helm-layout.scss"; +@import "helm-buttons.scss"; +@import "helm-typography.scss"; + +// load main helm.sh page +@import "helm-boat.scss"; +@import "helm-home.scss"; +@import "helm-blog.scss"; + +// load documentation styles +@import "docs-sidebar.scss"; +@import "docs-topbar.scss"; +@import "docs-footer.scss"; +@import "docs-content.scss"; +@import "docs-responsive.scss"; +@import "docs-404.scss"; diff --git a/themes/helm/layouts/404.html b/themes/helm/layouts/404.html new file mode 100755 index 0000000000..a01fbd5777 --- /dev/null +++ b/themes/helm/layouts/404.html @@ -0,0 +1,34 @@ +{{ define "title" }} +Helm +{{ end }} + +{{ define "main" }} +{{ $home := site.BaseURL }} + +

    +
    + {{ partial "banner.html" . }} + {{ partial "nav.html" . }} + {{ partial "nav-fixed.html" . }} +
    + +
    +
    + +

    + {{ T "404_title" | markdownify }} +

    +

    + {{ T "404_subtitle" | markdownify }} +

    +
    + + {{ partial "boat.html" . }} +
    +
    + +{{ partial "footer-links.html" . }} + +{{ end }} +{{ define "footer" }} +{{ end }} diff --git a/themes/helm/layouts/_default/_markup/render-link.html b/themes/helm/layouts/_default/_markup/render-link.html new file mode 100644 index 0000000000..5c75e8f569 --- /dev/null +++ b/themes/helm/layouts/_default/_markup/render-link.html @@ -0,0 +1,10 @@ +{{ $link := .Destination }} +{{ $isRemote := strings.HasPrefix $link "http" }} +{{- if not $isRemote -}} +{{ $url := urls.Parse .Destination }} +{{- if $url.Path -}} +{{ $fragment := "" }} +{{- with $url.Fragment }}{{ $fragment = printf "#%s" . }}{{ end -}} +{{- with .Page.GetPage $url.Path }}{{ $link = printf "%s%s" .RelPermalink $fragment }}{{ end }}{{ end -}} +{{- end -}} +
    {{- .Text | safeHTML -}} \ No newline at end of file diff --git a/themes/helm/layouts/_default/baseof.html b/themes/helm/layouts/_default/baseof.html new file mode 100644 index 0000000000..a2bbc56c75 --- /dev/null +++ b/themes/helm/layouts/_default/baseof.html @@ -0,0 +1,31 @@ +{{ $langCode := site.LanguageCode | default "en-us" }} +{{ $isHome := .IsHome }} +{{ $lang := .Lang }} +{{ $home := site.BaseURL }} + + + + + {{ block "title" . }} + Helm | {{ .Title }} + {{ end }} + + + {{ partial "header.html" . }} + + + {{ if $isHome }} + + {{ else }} + + {{ end }} + {{ block "main" . }} + {{ end }} + + {{ block "footer" . }} + {{ end }} + + {{ partial "js.html" . }} + {{ partial "google-analytics.html" . }} + + diff --git a/themes/helm/layouts/_default/section-link.html b/themes/helm/layouts/_default/section-link.html new file mode 100644 index 0000000000..307adbc8bf --- /dev/null +++ b/themes/helm/layouts/_default/section-link.html @@ -0,0 +1,19 @@ +
  • diff --git a/themes/helm/layouts/blog/list.html b/themes/helm/layouts/blog/list.html new file mode 100755 index 0000000000..15e954d805 --- /dev/null +++ b/themes/helm/layouts/blog/list.html @@ -0,0 +1,51 @@ +{{ define "title" }} +Helm | Blog +{{ end }} + +{{ define "main" }} +
    +
    + {{ partial "banner.html" . }} + {{ partial "nav.html" . }} + {{ partial "nav-fixed.html" . }} +
    + +
    +
    +
    + {{ .Content }} + + {{ range (.Paginate .Pages).Pages }} +
    +
    +

    {{ .Title }}

    +

    {{ .Date.Format "Mon, Jan 2, 2006" }}

    +
    + +

    + {{ .Summary }} + {{ if .Truncated }} + Read More… + {{ end }} +

    +
    + {{ end }} + + +
    +
    +
    + + {{ partial "footer-links.html" . }} +
    + +{{ end }} diff --git a/themes/helm/layouts/blog/single.html b/themes/helm/layouts/blog/single.html new file mode 100755 index 0000000000..753f53f52a --- /dev/null +++ b/themes/helm/layouts/blog/single.html @@ -0,0 +1,38 @@ +{{ define "main" }} +
    +
    + {{ partial "banner.html" . }} + {{ partial "nav.html" . }} + {{ partial "nav-fixed.html" . }} +
    + +
    +
    + + +
    + + Subscribe to RSS feed + + + + + +
    +
    +
    + + {{ partial "footer-links.html" . }} +
    + +{{ end }} diff --git a/themes/helm/layouts/code/single.html b/themes/helm/layouts/code/single.html new file mode 100644 index 0000000000..7dc44783f8 --- /dev/null +++ b/themes/helm/layouts/code/single.html @@ -0,0 +1,15 @@ + + + + + + + + + + + + Nothing to see here; move along. + + + diff --git a/themes/helm/layouts/docs/helm/list.html b/themes/helm/layouts/docs/helm/list.html new file mode 100644 index 0000000000..252b62f67d --- /dev/null +++ b/themes/helm/layouts/docs/helm/list.html @@ -0,0 +1,73 @@ +{{ define "title" }} +Helm | Docs +{{ end }} + +{{ define "main" }} +{{ $isDocsRoot := eq .CurrentSection .FirstSection }} +
    + + {{ partial "sidebar.html" . }} + +
    + + + +
    +
     
    +
    + {{ .Content }} + + + +
    +
     
    +
    +
    +
    + + +{{ partial "footer-links.html" . }} + +{{ end }} diff --git a/themes/helm/layouts/docs/list.html b/themes/helm/layouts/docs/list.html new file mode 100755 index 0000000000..d066dc41ef --- /dev/null +++ b/themes/helm/layouts/docs/list.html @@ -0,0 +1,68 @@ +{{ define "title" }} +Helm | Docs +{{ end }} + +{{ define "main" }} +{{ $isDocsRoot := eq .CurrentSection .FirstSection }} + +
    +
    + {{ partial "banner.html" . }} + {{ partial "nav.html" . }} + {{ partial "nav-fixed.html" . }} +
    + +
    + + +
    + +
    +
    +
    + +{{ partial "footer-links.html" . }} +{{ end }} diff --git a/themes/helm/layouts/docs/single.html b/themes/helm/layouts/docs/single.html new file mode 100644 index 0000000000..19264c3979 --- /dev/null +++ b/themes/helm/layouts/docs/single.html @@ -0,0 +1,50 @@ +{{ define "title" }} +Helm | {{ .Title }} +{{ end }} + +{{ define "main" }} + +
    +
    + {{ partial "banner.html" . }} + {{ partial "nav.html" . }} + {{ partial "nav-fixed.html" . }} +
    + +
    + + +
    + +
    +
    +
    + +{{ partial "footer-links.html" . }} +{{ end }} diff --git a/themes/helm/layouts/index.html b/themes/helm/layouts/index.html new file mode 100755 index 0000000000..36c9b9fbfa --- /dev/null +++ b/themes/helm/layouts/index.html @@ -0,0 +1,231 @@ +{{ define "title" }} +Helm +{{ end }} + +{{ define "main" }} +{{ $home := site.BaseURL }} +{{ $nextversion := site.Params.nextversion }} + +
    +
    + {{ partial "banner.html" . }} + {{ partial "nav.html" . }} + {{ partial "nav-fixed.html" . }} +
    + +
    +
    + +

    + {{ T "main_title" | markdownify }} +

    +

    + {{ T "main_subtitle" | markdownify }} +

    +
    + + {{ partial "boat.html" . }} +
    + +
    +
    +
    + Helm +

    {{ T "main_what_is_helm_title" | markdownify }}

    +
    +
    + +
    + +
    +
    + {{ T "main_what_is_helm_description" | markdownify }} +
    +
    +
    +
    +
    +

    + {{ T "feature_01_title" }} +

    +

    + {{ T "feature_01_desc" | markdownify }} +

    +
    +
    +

    + {{ T "feature_02_title" }} +

    +

    + {{ T "feature_02_desc" | markdownify }} +

    +
    +
    +

    + {{ T "feature_03_title" }} +

    +

    + {{ T "feature_03_desc" | markdownify }} +

    +
    +
    +

    + {{ T "feature_04_title" }} +

    +

    + {{ T "feature_04_desc" | markdownify }} +

    +
    +
    +
    +
    + +
    +
    +

    {{ T "get_helm_title" }}

    +

    {{ T "get_helm_desc" | markdownify }}

    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + +

    {{ T "get_helm_next" | markdownify }}

    +
    + +
    +

    {{ T "get_charts_title" }}

    + +

    {{ T "get_charts_desc" | markdownify }}

    + +
    +

    Artifact Hub

    +
    +
    +
    + +
    + +
    +
    + +
    +

    {{ T "community_title" }}

    +

    {{ T "community_desc" }}

    + +
    + +
    +
    +

    {{ T "community_next_release" }}

    +
    +
    + {{ T "community_next_release_version" | markdownify }} {{ $nextversion.version }} +
    + {{ T "community_next_release_date" | markdownify }} {{ $nextversion.date }} +
    +
    + {{ T "community_release_calendar" | markdownify }} +
    +
    +
    + +
    +

    {{ T "community_events_title" }}

    +
    +
    {{ T "community_upcoming_events_title" }}
    +
    {{ T "community_upcoming_events_desc" | markdownify }}
    +
    {{ T "community_past_events_title" }}
    +
    {{ T "community_past_event_01" | markdownify }}
    +
    {{ T "community_past_event_02" | markdownify }}
    +
    {{ T "community_past_event_03" | markdownify }}
    +
    +
    + +
    +

    {{ T "community_sig_title" }}

    +

    + {{ T "community_sig_subtitle" }} +

    + {{ T "community_sig_desc" | markdownify }} +
    +
    + +
    +
    +

    {{ T "community_standup_title" }}

    +

    + {{ T "community_standup_time" }} +

    +

    {{ T "community_standup_desc" | markdownify }}

    +
    + +
    +

    {{ T "community_slack_title" }}

    +
    +
    {{ T "community_slack_group_01_title" }}
    +
    {{ T "community_slack_group_01_desc" }}
    + +
    {{ T "community_slack_group_02_title" }}
    +
    {{ T "community_slack_group_02_desc" }}
    + +
    {{ T "community_slack_group_03_title" }}
    +
    {{ T "community_slack_group_03_desc" }}
    +
    + +

    + {{ T "community_slack_join" | markdownify }} +

    +
    +
    + +
    +
    +

    {{ T "community_contrib_title" }}

    +

    + {{ T "community_contrib_subtitle" }} +

    + {{ T "community_contrib_desc" | markdownify }} +
    +
    +
    +
    + + {{ partial "footer.html" . }} +
    + +{{ partial "footer-links.html" . }} + +{{ end }} diff --git a/themes/helm/layouts/partials/banner.html b/themes/helm/layouts/partials/banner.html new file mode 100644 index 0000000000..a61deab72b --- /dev/null +++ b/themes/helm/layouts/partials/banner.html @@ -0,0 +1,14 @@ +{{- $banner := T "banner_1" }} +{{- if $banner -}} + +{{- end -}} diff --git a/themes/helm/layouts/partials/boat.html b/themes/helm/layouts/partials/boat.html new file mode 100644 index 0000000000..5418687489 --- /dev/null +++ b/themes/helm/layouts/partials/boat.html @@ -0,0 +1,15 @@ +
    + boat +
    + + + + + + + + + +
    +
    \ No newline at end of file diff --git a/themes/helm/layouts/partials/cncf.html b/themes/helm/layouts/partials/cncf.html new file mode 100755 index 0000000000..8d3af867d3 --- /dev/null +++ b/themes/helm/layouts/partials/cncf.html @@ -0,0 +1,8 @@ + diff --git a/themes/helm/layouts/partials/css.html b/themes/helm/layouts/partials/css.html new file mode 100644 index 0000000000..8d06f769e7 --- /dev/null +++ b/themes/helm/layouts/partials/css.html @@ -0,0 +1,20 @@ +{{ $serverMode := site.IsServer }} +{{ $isDoc := eq .Section "docs" }} +{{ $sass := "sass/styles.scss" }} +{{ $includes := (slice "node_modules") }} +{{ $cssOut := "css/style.css" }} +{{ $cssDevOpts := (dict "includePaths" $includes "targetPath" $cssOut "enableSourceMap" true) }} +{{ $cssProdOpts := (dict "includePaths" $includes "targetPath" $cssOut "outputStyle" "compressed") }} +{{ $cssOpts := cond $serverMode $cssDevOpts $cssProdOpts }} +{{ $css := resources.Get $sass | resources.ExecuteAsTemplate $sass . | toCSS $cssOpts }} + +{{ if $serverMode }} + +{{ else }} +{{ $prodCss := $css | postCSS | fingerprint }} + +{{ end }} + +{{ if $isDoc }} + +{{ end }} diff --git a/themes/helm/layouts/partials/footer-links.html b/themes/helm/layouts/partials/footer-links.html new file mode 100644 index 0000000000..03602212b5 --- /dev/null +++ b/themes/helm/layouts/partials/footer-links.html @@ -0,0 +1,63 @@ +{{ $title := site.Title }} +{{ $year := now.Year }} + diff --git a/themes/helm/layouts/partials/footer-social.html b/themes/helm/layouts/partials/footer-social.html new file mode 100644 index 0000000000..397f7bd686 --- /dev/null +++ b/themes/helm/layouts/partials/footer-social.html @@ -0,0 +1,6 @@ + diff --git a/themes/helm/layouts/partials/footer.html b/themes/helm/layouts/partials/footer.html new file mode 100755 index 0000000000..adb16bb33b --- /dev/null +++ b/themes/helm/layouts/partials/footer.html @@ -0,0 +1,43 @@ +
    +
    +
    + + +
    +

    {{ T "footer_support_title" }}

    +
    + +
    + +
    + Bitnami + + Blood Orange + + codecentric AG + + Codefresh + + Google + + IBM + + Microsoft + + Montreal + + Samsung SDS + + SUSE + + Ticketmaster + + Weaveworks + +
    +
    + +

    {{ T "footer_support_subtitle" | markdownify }}

    +
    +
    +
    diff --git a/themes/helm/layouts/partials/google-analytics.html b/themes/helm/layouts/partials/google-analytics.html new file mode 100644 index 0000000000..e7de1f3417 --- /dev/null +++ b/themes/helm/layouts/partials/google-analytics.html @@ -0,0 +1,9 @@ +{{ $id := site.Params.googleAnalyticsId }} + diff --git a/themes/helm/layouts/partials/header.html b/themes/helm/layouts/partials/header.html new file mode 100755 index 0000000000..1d9c847ee3 --- /dev/null +++ b/themes/helm/layouts/partials/header.html @@ -0,0 +1,7 @@ +{{ partial "meta.html" . }} + +{{ partial "css.html" . }} + +{{ with .OutputFormats.Get "rss" }} +{{ printf `` .Rel .MediaType.Type .Permalink site.Title | safeHTML }} +{{ end }} diff --git a/themes/helm/layouts/partials/js.html b/themes/helm/layouts/partials/js.html new file mode 100755 index 0000000000..686ce7827f --- /dev/null +++ b/themes/helm/layouts/partials/js.html @@ -0,0 +1,30 @@ +{{ $jquery := resources.Get "js/jquery.js" | resources.Minify | fingerprint }} +{{ $serverMode := site.IsServer }} +{{ $jsOut := "js/bundle.js" }} +{{ $isDoc := eq .Section "docs" }} +{{ $jsFiles := site.Params.jsFiles }} +{{ $jsAll := (slice) }} +{{ range $jsFiles }} +{{ $path := printf "js/%s.js" . }} +{{ $js := resources.Get $path }} +{{ $jsAll = $jsAll | append $js }} +{{ end }} +{{ $jsBundle := $jsAll | resources.Concat $jsOut | resources.Minify }} + + + +{{ if $serverMode }} + +{{ else }} +{{ $prodJsBundle := $jsBundle | fingerprint }} + +{{ end }} + +{{ if $isDoc }} + +{{ end }} diff --git a/themes/helm/layouts/partials/meta.html b/themes/helm/layouts/partials/meta.html new file mode 100644 index 0000000000..41eb04ab88 --- /dev/null +++ b/themes/helm/layouts/partials/meta.html @@ -0,0 +1,30 @@ +{{ $isHome := .IsHome }} +{{ $desc := .Param "description" }} +{{ $title := .Title }} +{{ $url := .Permalink }} +{{ $img := "img/favicon-152.png" | absURL }} +{{ $og_img := "img/og-image.png" | absURL }} +{{ $icon := "img/apple-touch-icon-precomposed.png" | relURL }} +{{ $gsv := site.Params.googleSiteVerification }} + + + + +{{ with $desc }} + +{{ end }} + + + + + + +{{ if .Params.twittertype }}{{ else }}{{ end }} +{{ if .Params.twitterimage }}{{ else }}{{ end }} + + + + + + + diff --git a/themes/helm/layouts/partials/nav-fixed.html b/themes/helm/layouts/partials/nav-fixed.html new file mode 100644 index 0000000000..5f37659067 --- /dev/null +++ b/themes/helm/layouts/partials/nav-fixed.html @@ -0,0 +1,40 @@ +{{ $versions := site.Params.versions }} +{{ $primary := index (where $versions ".primary" true) 0 }} +{{ $menu := site.Menus.main }} + + diff --git a/themes/helm/layouts/partials/nav-i18n.html b/themes/helm/layouts/partials/nav-i18n.html new file mode 100644 index 0000000000..c06ff1266d --- /dev/null +++ b/themes/helm/layouts/partials/nav-i18n.html @@ -0,0 +1,34 @@ +{{ $versions := site.Params.versions }} +{{ $primary := index (where $versions ".primary" true) 0 }} +{{ $menu := site.Menus.main }} + + +{{ if .Site.IsMultiLingual }} + + {{ else }} +{{ end }} diff --git a/themes/helm/layouts/partials/nav-logo.html b/themes/helm/layouts/partials/nav-logo.html new file mode 100755 index 0000000000..9f93929d61 --- /dev/null +++ b/themes/helm/layouts/partials/nav-logo.html @@ -0,0 +1,27 @@ +Helm + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/helm/layouts/partials/nav-versioning.html b/themes/helm/layouts/partials/nav-versioning.html new file mode 100644 index 0000000000..a31f5a6da5 --- /dev/null +++ b/themes/helm/layouts/partials/nav-versioning.html @@ -0,0 +1,22 @@ +{{ $versions := site.Params.versions }} +{{ $primary := index (where $versions ".primary" true) 0 }} +{{ $menu := site.Menus.main }} + + + diff --git a/themes/helm/layouts/partials/nav.html b/themes/helm/layouts/partials/nav.html new file mode 100755 index 0000000000..1312ffb310 --- /dev/null +++ b/themes/helm/layouts/partials/nav.html @@ -0,0 +1,47 @@ +{{ $versions := site.Params.versions }} +{{ $primary := index (where $versions ".primary" true) 0 }} +{{ $menu := site.Menus.main }} + + diff --git a/themes/helm/layouts/partials/offcanvas.html b/themes/helm/layouts/partials/offcanvas.html new file mode 100755 index 0000000000..d50fd37af2 --- /dev/null +++ b/themes/helm/layouts/partials/offcanvas.html @@ -0,0 +1,36 @@ +{{ $docsHome := .FirstSection }} +{{ $docsSections := where site.Sections "Section" "docs" }} + diff --git a/themes/helm/layouts/partials/sidebar.html b/themes/helm/layouts/partials/sidebar.html new file mode 100755 index 0000000000..0ad8792c2b --- /dev/null +++ b/themes/helm/layouts/partials/sidebar.html @@ -0,0 +1,48 @@ +{{ $docsHome := .FirstSection }} + + + + + + + + + \ No newline at end of file diff --git a/themes/helm/static/fonts/materialdesignicons-webfont.eot b/themes/helm/static/fonts/materialdesignicons-webfont.eot new file mode 100644 index 0000000000..df738479c9 Binary files /dev/null and b/themes/helm/static/fonts/materialdesignicons-webfont.eot differ diff --git a/themes/helm/static/fonts/materialdesignicons-webfont.ttf b/themes/helm/static/fonts/materialdesignicons-webfont.ttf new file mode 100644 index 0000000000..d010b36317 Binary files /dev/null and b/themes/helm/static/fonts/materialdesignicons-webfont.ttf differ diff --git a/themes/helm/static/fonts/materialdesignicons-webfont.woff b/themes/helm/static/fonts/materialdesignicons-webfont.woff new file mode 100644 index 0000000000..95ff156b05 Binary files /dev/null and b/themes/helm/static/fonts/materialdesignicons-webfont.woff differ diff --git a/themes/helm/static/fonts/materialdesignicons-webfont.woff2 b/themes/helm/static/fonts/materialdesignicons-webfont.woff2 new file mode 100644 index 0000000000..1ba061e879 Binary files /dev/null and b/themes/helm/static/fonts/materialdesignicons-webfont.woff2 differ diff --git a/themes/helm/static/fonts/publicsans-medium-webfont.woff b/themes/helm/static/fonts/publicsans-medium-webfont.woff new file mode 100755 index 0000000000..02cfdda13a Binary files /dev/null and b/themes/helm/static/fonts/publicsans-medium-webfont.woff differ diff --git a/themes/helm/static/fonts/publicsans-medium-webfont.woff2 b/themes/helm/static/fonts/publicsans-medium-webfont.woff2 new file mode 100755 index 0000000000..fcf66d8358 Binary files /dev/null and b/themes/helm/static/fonts/publicsans-medium-webfont.woff2 differ diff --git a/themes/helm/static/fonts/publicsans-regular-webfont.woff b/themes/helm/static/fonts/publicsans-regular-webfont.woff new file mode 100755 index 0000000000..8303690668 Binary files /dev/null and b/themes/helm/static/fonts/publicsans-regular-webfont.woff differ diff --git a/themes/helm/static/fonts/publicsans-regular-webfont.woff2 b/themes/helm/static/fonts/publicsans-regular-webfont.woff2 new file mode 100755 index 0000000000..fd53cd1238 Binary files /dev/null and b/themes/helm/static/fonts/publicsans-regular-webfont.woff2 differ diff --git a/themes/helm/static/fonts/spacemono-bold-webfont.woff b/themes/helm/static/fonts/spacemono-bold-webfont.woff new file mode 100755 index 0000000000..36a6577e5d Binary files /dev/null and b/themes/helm/static/fonts/spacemono-bold-webfont.woff differ diff --git a/themes/helm/static/fonts/spacemono-bold-webfont.woff2 b/themes/helm/static/fonts/spacemono-bold-webfont.woff2 new file mode 100755 index 0000000000..1742f748d0 Binary files /dev/null and b/themes/helm/static/fonts/spacemono-bold-webfont.woff2 differ diff --git a/themes/helm/static/fonts/spacemono-regular-webfont.woff b/themes/helm/static/fonts/spacemono-regular-webfont.woff new file mode 100755 index 0000000000..576447d4c9 Binary files /dev/null and b/themes/helm/static/fonts/spacemono-regular-webfont.woff differ diff --git a/themes/helm/static/fonts/spacemono-regular-webfont.woff2 b/themes/helm/static/fonts/spacemono-regular-webfont.woff2 new file mode 100755 index 0000000000..8e9a7f8f59 Binary files /dev/null and b/themes/helm/static/fonts/spacemono-regular-webfont.woff2 differ diff --git a/docs.helm.sh/rootfs/public/src/img/apple-touch-icon-precomposed.png b/themes/helm/static/img/apple-touch-icon-precomposed.png old mode 100644 new mode 100755 similarity index 100% rename from docs.helm.sh/rootfs/public/src/img/apple-touch-icon-precomposed.png rename to themes/helm/static/img/apple-touch-icon-precomposed.png diff --git a/docs.helm.sh/rootfs/public/src/img/apple-touch-icon.png b/themes/helm/static/img/apple-touch-icon.png old mode 100644 new mode 100755 similarity index 100% rename from docs.helm.sh/rootfs/public/src/img/apple-touch-icon.png rename to themes/helm/static/img/apple-touch-icon.png diff --git a/themes/helm/static/img/artifact-hub.jpg b/themes/helm/static/img/artifact-hub.jpg new file mode 100644 index 0000000000..ddd253df5c Binary files /dev/null and b/themes/helm/static/img/artifact-hub.jpg differ diff --git a/docs.helm.sh/rootfs/public/src/img/bitnami.png b/themes/helm/static/img/bitnami.png old mode 100644 new mode 100755 similarity index 100% rename from docs.helm.sh/rootfs/public/src/img/bitnami.png rename to themes/helm/static/img/bitnami.png diff --git a/themes/helm/static/img/blog/helm-hub.png b/themes/helm/static/img/blog/helm-hub.png new file mode 100755 index 0000000000..c114d7945b Binary files /dev/null and b/themes/helm/static/img/blog/helm-hub.png differ diff --git a/themes/helm/static/img/boat.gif b/themes/helm/static/img/boat.gif new file mode 100644 index 0000000000..326af02870 Binary files /dev/null and b/themes/helm/static/img/boat.gif differ diff --git a/docs.helm.sh/rootfs/public/src/img/boat.png b/themes/helm/static/img/boat.png old mode 100644 new mode 100755 similarity index 100% rename from docs.helm.sh/rootfs/public/src/img/boat.png rename to themes/helm/static/img/boat.png diff --git a/themes/helm/static/img/boat.svg b/themes/helm/static/img/boat.svg new file mode 100644 index 0000000000..34dcfe5526 --- /dev/null +++ b/themes/helm/static/img/boat.svg @@ -0,0 +1,60 @@ + + + + Group + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/helm/static/img/btn-get-helm.png b/themes/helm/static/img/btn-get-helm.png new file mode 100755 index 0000000000..1a0ff7c743 Binary files /dev/null and b/themes/helm/static/img/btn-get-helm.png differ diff --git a/docs.helm.sh/rootfs/public/src/img/chart-illustration.png b/themes/helm/static/img/chart-illustration.png old mode 100644 new mode 100755 similarity index 100% rename from docs.helm.sh/rootfs/public/src/img/chart-illustration.png rename to themes/helm/static/img/chart-illustration.png diff --git a/themes/helm/static/img/cncf-color.png b/themes/helm/static/img/cncf-color.png new file mode 100755 index 0000000000..97796cba6c Binary files /dev/null and b/themes/helm/static/img/cncf-color.png differ diff --git a/themes/helm/static/img/cncf-white.svg b/themes/helm/static/img/cncf-white.svg new file mode 100644 index 0000000000..08e148ac79 --- /dev/null +++ b/themes/helm/static/img/cncf-white.svg @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/themes/helm/static/img/create-a-bucket.png b/themes/helm/static/img/create-a-bucket.png new file mode 100755 index 0000000000..f7f5dbfdc3 Binary files /dev/null and b/themes/helm/static/img/create-a-bucket.png differ diff --git a/themes/helm/static/img/create-a-gh-page-button.png b/themes/helm/static/img/create-a-gh-page-button.png new file mode 100755 index 0000000000..b9d43a7059 Binary files /dev/null and b/themes/helm/static/img/create-a-gh-page-button.png differ diff --git a/docs.helm.sh/rootfs/public/src/img/deis-logo-white.png b/themes/helm/static/img/deis-logo-white.png old mode 100644 new mode 100755 similarity index 100% rename from docs.helm.sh/rootfs/public/src/img/deis-logo-white.png rename to themes/helm/static/img/deis-logo-white.png diff --git a/themes/helm/static/img/edit-permissions.png b/themes/helm/static/img/edit-permissions.png new file mode 100755 index 0000000000..b1e39f4b20 Binary files /dev/null and b/themes/helm/static/img/edit-permissions.png differ diff --git a/docs.helm.sh/rootfs/public/src/img/favicon-152.png b/themes/helm/static/img/favicon-152.png similarity index 100% rename from docs.helm.sh/rootfs/public/src/img/favicon-152.png rename to themes/helm/static/img/favicon-152.png diff --git a/docs.helm.sh/rootfs/public/src/img/favicon.ico b/themes/helm/static/img/favicon.ico similarity index 100% rename from docs.helm.sh/rootfs/public/src/img/favicon.ico rename to themes/helm/static/img/favicon.ico diff --git a/docs.helm.sh/rootfs/public/src/img/favicon.png b/themes/helm/static/img/favicon.png similarity index 100% rename from docs.helm.sh/rootfs/public/src/img/favicon.png rename to themes/helm/static/img/favicon.png diff --git a/docs.helm.sh/rootfs/public/src/img/feature-icon-1.png b/themes/helm/static/img/feature-icon-1.png old mode 100644 new mode 100755 similarity index 100% rename from docs.helm.sh/rootfs/public/src/img/feature-icon-1.png rename to themes/helm/static/img/feature-icon-1.png diff --git a/docs.helm.sh/rootfs/public/src/img/feature-icon-2.png b/themes/helm/static/img/feature-icon-2.png old mode 100644 new mode 100755 similarity index 100% rename from docs.helm.sh/rootfs/public/src/img/feature-icon-2.png rename to themes/helm/static/img/feature-icon-2.png diff --git a/docs.helm.sh/rootfs/public/src/img/feature-icon-3.png b/themes/helm/static/img/feature-icon-3.png old mode 100644 new mode 100755 similarity index 100% rename from docs.helm.sh/rootfs/public/src/img/feature-icon-3.png rename to themes/helm/static/img/feature-icon-3.png diff --git a/docs.helm.sh/rootfs/public/src/img/feature-icon-4.png b/themes/helm/static/img/feature-icon-4.png old mode 100644 new mode 100755 similarity index 100% rename from docs.helm.sh/rootfs/public/src/img/feature-icon-4.png rename to themes/helm/static/img/feature-icon-4.png diff --git a/docs.helm.sh/rootfs/public/src/img/features-bg.png b/themes/helm/static/img/features-bg.png old mode 100644 new mode 100755 similarity index 100% rename from docs.helm.sh/rootfs/public/src/img/features-bg.png rename to themes/helm/static/img/features-bg.png diff --git a/docs.helm.sh/rootfs/public/src/img/fish.png b/themes/helm/static/img/fish.png old mode 100644 new mode 100755 similarity index 100% rename from docs.helm.sh/rootfs/public/src/img/fish.png rename to themes/helm/static/img/fish.png diff --git a/helm.sh/assets/images/geometry3.png b/themes/helm/static/img/geometry3.png old mode 100644 new mode 100755 similarity index 100% rename from helm.sh/assets/images/geometry3.png rename to themes/helm/static/img/geometry3.png diff --git a/themes/helm/static/img/github.svg b/themes/helm/static/img/github.svg new file mode 100755 index 0000000000..34b2509eb6 --- /dev/null +++ b/themes/helm/static/img/github.svg @@ -0,0 +1,10 @@ + + + + Fill 5 + Created with Sketch. + + + + + \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/src/img/google.png b/themes/helm/static/img/google.png similarity index 100% rename from docs.helm.sh/rootfs/public/src/img/google.png rename to themes/helm/static/img/google.png diff --git a/themes/helm/static/img/helm-3-badge.svg b/themes/helm/static/img/helm-3-badge.svg new file mode 100644 index 0000000000..df3383e237 --- /dev/null +++ b/themes/helm/static/img/helm-3-badge.svg @@ -0,0 +1,32 @@ + + + + Artboard + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/src/img/helm-blue-vector.svg b/themes/helm/static/img/helm-blue-vector.svg old mode 100644 new mode 100755 similarity index 100% rename from docs.helm.sh/rootfs/public/src/img/helm-blue-vector.svg rename to themes/helm/static/img/helm-blue-vector.svg diff --git a/docs.helm.sh/rootfs/public/src/img/helm-charts.png b/themes/helm/static/img/helm-charts.png old mode 100644 new mode 100755 similarity index 100% rename from docs.helm.sh/rootfs/public/src/img/helm-charts.png rename to themes/helm/static/img/helm-charts.png diff --git a/docs.helm.sh/rootfs/public/src/img/helm-footer-logo.png b/themes/helm/static/img/helm-footer-logo.png old mode 100644 new mode 100755 similarity index 100% rename from docs.helm.sh/rootfs/public/src/img/helm-footer-logo.png rename to themes/helm/static/img/helm-footer-logo.png diff --git a/themes/helm/static/img/helm-hub.jpg b/themes/helm/static/img/helm-hub.jpg new file mode 100644 index 0000000000..66bdda9d2b Binary files /dev/null and b/themes/helm/static/img/helm-hub.jpg differ diff --git a/docs.helm.sh/rootfs/public/src/img/helm-logo-deis.png b/themes/helm/static/img/helm-logo-deis.png old mode 100644 new mode 100755 similarity index 100% rename from docs.helm.sh/rootfs/public/src/img/helm-logo-deis.png rename to themes/helm/static/img/helm-logo-deis.png diff --git a/docs.helm.sh/rootfs/public/src/img/helm-logo-microsoft.png b/themes/helm/static/img/helm-logo-microsoft.png old mode 100644 new mode 100755 similarity index 100% rename from docs.helm.sh/rootfs/public/src/img/helm-logo-microsoft.png rename to themes/helm/static/img/helm-logo-microsoft.png diff --git a/docs.helm.sh/rootfs/public/src/img/helm-logo-microsoft.svg b/themes/helm/static/img/helm-logo-microsoft.svg old mode 100644 new mode 100755 similarity index 100% rename from docs.helm.sh/rootfs/public/src/img/helm-logo-microsoft.svg rename to themes/helm/static/img/helm-logo-microsoft.svg diff --git a/docs.helm.sh/rootfs/public/src/img/helm-logo.svg b/themes/helm/static/img/helm-logo.svg old mode 100644 new mode 100755 similarity index 100% rename from docs.helm.sh/rootfs/public/src/img/helm-logo.svg rename to themes/helm/static/img/helm-logo.svg diff --git a/themes/helm/static/img/helm-pyramid.png b/themes/helm/static/img/helm-pyramid.png new file mode 100644 index 0000000000..319007d38b Binary files /dev/null and b/themes/helm/static/img/helm-pyramid.png differ diff --git a/themes/helm/static/img/helm-pyramid.svg b/themes/helm/static/img/helm-pyramid.svg new file mode 100644 index 0000000000..b0f2f61c65 --- /dev/null +++ b/themes/helm/static/img/helm-pyramid.svg @@ -0,0 +1,37 @@ + + + + Artboard + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs.helm.sh/rootfs/public/src/img/helm-white-vector.svg b/themes/helm/static/img/helm-white-vector.svg old mode 100644 new mode 100755 similarity index 100% rename from docs.helm.sh/rootfs/public/src/img/helm-white-vector.svg rename to themes/helm/static/img/helm-white-vector.svg diff --git a/themes/helm/static/img/helm.svg b/themes/helm/static/img/helm.svg new file mode 100644 index 0000000000..1e2db8a2e6 --- /dev/null +++ b/themes/helm/static/img/helm.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs.helm.sh/rootfs/public/src/img/logo-with-deis.png b/themes/helm/static/img/logo-with-deis.png old mode 100644 new mode 100755 similarity index 100% rename from docs.helm.sh/rootfs/public/src/img/logo-with-deis.png rename to themes/helm/static/img/logo-with-deis.png diff --git a/docs.helm.sh/rootfs/public/src/img/logo.png b/themes/helm/static/img/logo.png old mode 100644 new mode 100755 similarity index 100% rename from docs.helm.sh/rootfs/public/src/img/logo.png rename to themes/helm/static/img/logo.png diff --git a/themes/helm/static/img/logo.svg b/themes/helm/static/img/logo.svg new file mode 100644 index 0000000000..1e2db8a2e6 --- /dev/null +++ b/themes/helm/static/img/logo.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/helm.sh/assets/images/logowall/bitnami.png b/themes/helm/static/img/logowall/bitnami.png old mode 100644 new mode 100755 similarity index 100% rename from helm.sh/assets/images/logowall/bitnami.png rename to themes/helm/static/img/logowall/bitnami.png diff --git a/themes/helm/static/img/logowall/bloodorange.png b/themes/helm/static/img/logowall/bloodorange.png new file mode 100755 index 0000000000..05ac7cdeec Binary files /dev/null and b/themes/helm/static/img/logowall/bloodorange.png differ diff --git a/themes/helm/static/img/logowall/codecademy.png b/themes/helm/static/img/logowall/codecademy.png new file mode 100644 index 0000000000..387db47edb Binary files /dev/null and b/themes/helm/static/img/logowall/codecademy.png differ diff --git a/helm.sh/assets/images/logowall/codecentric.png b/themes/helm/static/img/logowall/codecentric.png old mode 100644 new mode 100755 similarity index 100% rename from helm.sh/assets/images/logowall/codecentric.png rename to themes/helm/static/img/logowall/codecentric.png diff --git a/helm.sh/assets/images/logowall/codefresh.png b/themes/helm/static/img/logowall/codefresh.png old mode 100644 new mode 100755 similarity index 100% rename from helm.sh/assets/images/logowall/codefresh.png rename to themes/helm/static/img/logowall/codefresh.png diff --git a/helm.sh/assets/images/logowall/google.png b/themes/helm/static/img/logowall/google.png old mode 100644 new mode 100755 similarity index 100% rename from helm.sh/assets/images/logowall/google.png rename to themes/helm/static/img/logowall/google.png diff --git a/themes/helm/static/img/logowall/ibm.png b/themes/helm/static/img/logowall/ibm.png new file mode 100644 index 0000000000..93dc534533 Binary files /dev/null and b/themes/helm/static/img/logowall/ibm.png differ diff --git a/helm.sh/assets/images/logowall/microsoft.png b/themes/helm/static/img/logowall/microsoft.png old mode 100644 new mode 100755 similarity index 100% rename from helm.sh/assets/images/logowall/microsoft.png rename to themes/helm/static/img/logowall/microsoft.png diff --git a/themes/helm/static/img/logowall/montreal.png b/themes/helm/static/img/logowall/montreal.png new file mode 100755 index 0000000000..8856020068 Binary files /dev/null and b/themes/helm/static/img/logowall/montreal.png differ diff --git a/themes/helm/static/img/logowall/samsungsds.png b/themes/helm/static/img/logowall/samsungsds.png new file mode 100755 index 0000000000..936bff9dc3 Binary files /dev/null and b/themes/helm/static/img/logowall/samsungsds.png differ diff --git a/themes/helm/static/img/logowall/suse.png b/themes/helm/static/img/logowall/suse.png new file mode 100644 index 0000000000..d9878e4856 Binary files /dev/null and b/themes/helm/static/img/logowall/suse.png differ diff --git a/helm.sh/assets/images/logowall/tm.png b/themes/helm/static/img/logowall/tm.png old mode 100644 new mode 100755 similarity index 100% rename from helm.sh/assets/images/logowall/tm.png rename to themes/helm/static/img/logowall/tm.png diff --git a/themes/helm/static/img/logowall/weaveworks.png b/themes/helm/static/img/logowall/weaveworks.png new file mode 100644 index 0000000000..1f2cb6168c Binary files /dev/null and b/themes/helm/static/img/logowall/weaveworks.png differ diff --git a/docs.helm.sh/rootfs/public/images/make-bucket-public.png b/themes/helm/static/img/make-bucket-public.png similarity index 100% rename from docs.helm.sh/rootfs/public/images/make-bucket-public.png rename to themes/helm/static/img/make-bucket-public.png diff --git a/docs.helm.sh/rootfs/public/src/img/microsoft.png b/themes/helm/static/img/microsoft.png old mode 100644 new mode 100755 similarity index 100% rename from docs.helm.sh/rootfs/public/src/img/microsoft.png rename to themes/helm/static/img/microsoft.png diff --git a/docs.helm.sh/rootfs/public/src/img/microsoft.svg b/themes/helm/static/img/microsoft.svg old mode 100644 new mode 100755 similarity index 100% rename from docs.helm.sh/rootfs/public/src/img/microsoft.svg rename to themes/helm/static/img/microsoft.svg diff --git a/themes/helm/static/img/og-image.png b/themes/helm/static/img/og-image.png new file mode 100644 index 0000000000..82fa393056 Binary files /dev/null and b/themes/helm/static/img/og-image.png differ diff --git a/docs.helm.sh/rootfs/public/src/img/pattern-topo-sm.png b/themes/helm/static/img/pattern-topo-sm.png old mode 100644 new mode 100755 similarity index 100% rename from docs.helm.sh/rootfs/public/src/img/pattern-topo-sm.png rename to themes/helm/static/img/pattern-topo-sm.png diff --git a/docs.helm.sh/rootfs/public/src/img/pattern-topo-white.png b/themes/helm/static/img/pattern-topo-white.png old mode 100644 new mode 100755 similarity index 100% rename from docs.helm.sh/rootfs/public/src/img/pattern-topo-white.png rename to themes/helm/static/img/pattern-topo-white.png diff --git a/docs.helm.sh/rootfs/public/src/img/pattern-topo.png b/themes/helm/static/img/pattern-topo.png old mode 100644 new mode 100755 similarity index 100% rename from docs.helm.sh/rootfs/public/src/img/pattern-topo.png rename to themes/helm/static/img/pattern-topo.png diff --git a/docs.helm.sh/rootfs/public/src/img/pattern-waves.png b/themes/helm/static/img/pattern-waves.png old mode 100644 new mode 100755 similarity index 100% rename from docs.helm.sh/rootfs/public/src/img/pattern-waves.png rename to themes/helm/static/img/pattern-waves.png diff --git a/helm.sh/assets/images/phippy-sm-smiling.png b/themes/helm/static/img/phippy-sm-smiling.png old mode 100644 new mode 100755 similarity index 100% rename from helm.sh/assets/images/phippy-sm-smiling.png rename to themes/helm/static/img/phippy-sm-smiling.png diff --git a/themes/helm/static/img/set-a-gh-page.png b/themes/helm/static/img/set-a-gh-page.png new file mode 100755 index 0000000000..ee9dccd693 Binary files /dev/null and b/themes/helm/static/img/set-a-gh-page.png differ diff --git a/docs.helm.sh/rootfs/public/src/img/skippbox.png b/themes/helm/static/img/skippbox.png old mode 100644 new mode 100755 similarity index 100% rename from docs.helm.sh/rootfs/public/src/img/skippbox.png rename to themes/helm/static/img/skippbox.png diff --git a/themes/helm/static/img/topography.png b/themes/helm/static/img/topography.png new file mode 100644 index 0000000000..a4bdec55eb Binary files /dev/null and b/themes/helm/static/img/topography.png differ diff --git a/themes/helm/static/img/twitter.svg b/themes/helm/static/img/twitter.svg new file mode 100755 index 0000000000..899a4f6ce3 --- /dev/null +++ b/themes/helm/static/img/twitter.svg @@ -0,0 +1,12 @@ + + + + Shape + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/themes/helm/theme.toml b/themes/helm/theme.toml new file mode 100755 index 0000000000..77c47a08ca --- /dev/null +++ b/themes/helm/theme.toml @@ -0,0 +1,6 @@ +name = "helmdocs" +license = "MIT" +licenselink = "//github.com/helm/helm-www" +description = "Theme for the Helm Project Docs" +homepage = "//github.com/helm/helm" +tags = ["documentation", "helm", "kubernetes"] diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000000..a3ca310ae0 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,839 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@nodelib/fs.scandir@2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b" + integrity sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw== + dependencies: + "@nodelib/fs.stat" "2.0.3" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.3", "@nodelib/fs.stat@^2.0.2": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz#34dc5f4cabbc720f4e60f75a747e7ecd6c175bd3" + integrity sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz#011b9202a70a6366e436ca5c065844528ab04976" + integrity sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ== + dependencies: + "@nodelib/fs.scandir" "2.1.3" + fastq "^1.6.0" + +"@types/color-name@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" + integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== + +"@types/glob@^7.1.1": + version "7.1.3" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.3.tgz#e6ba80f36b7daad2c685acd9266382e68985c183" + integrity sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w== + dependencies: + "@types/minimatch" "*" + "@types/node" "*" + +"@types/minimatch@*": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" + integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== + +"@types/node@*": + version "14.11.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.11.1.tgz#56af902ad157e763f9ba63d671c39cda3193c835" + integrity sha512-oTQgnd0hblfLsJ6BvJzzSL+Inogp3lq9fGgqRkMB/ziKMgEUaFl801OncOzUmalfzt14N0oPHMK47ipl+wbTIw== + +ansi-regex@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" + integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359" + integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA== + dependencies: + "@types/color-name" "^1.1.1" + color-convert "^2.0.1" + +anymatch@~3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" + integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +autoprefixer@9.7.4: + version "9.7.4" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.7.4.tgz#f8bf3e06707d047f0641d87aee8cfb174b2a5378" + integrity sha512-g0Ya30YrMBAEZk60lp+qfX5YQllG+S5W3GYCFvyHTvhOki0AEQJLPEcIuGRsqVwLi8FvXPVtwTGhfr38hVpm0g== + dependencies: + browserslist "^4.8.3" + caniuse-lite "^1.0.30001020" + chalk "^2.4.2" + normalize-range "^0.1.2" + num2fraction "^1.2.2" + postcss "^7.0.26" + postcss-value-parser "^4.0.2" + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +binary-extensions@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.1.0.tgz#30fa40c9e7fe07dbc895678cd287024dea241dd9" + integrity sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^3.0.1, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +browserslist@^4.8.3: + version "4.16.6" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.6.tgz#d7901277a5a88e554ed305b183ec9b0c08f66fa2" + integrity sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ== + dependencies: + caniuse-lite "^1.0.30001219" + colorette "^1.2.2" + electron-to-chromium "^1.3.723" + escalade "^3.1.1" + node-releases "^1.1.71" + +caller-callsite@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" + integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= + dependencies: + callsites "^2.0.0" + +caller-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" + integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= + dependencies: + caller-callsite "^2.0.0" + +callsites@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" + integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= + +camelcase@^5.0.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +caniuse-lite@^1.0.30001020, caniuse-lite@^1.0.30001219: + version "1.0.30001228" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz#bfdc5942cd3326fa51ee0b42fbef4da9d492a7fa" + integrity sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A== + +chalk@^2.0.1, chalk@^2.4.1, chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" + integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chokidar@^3.3.0: + version "3.4.2" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.2.tgz#38dc8e658dec3809741eb3ef7bb0a47fe424232d" + integrity sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A== + dependencies: + anymatch "~3.1.1" + braces "~3.0.2" + glob-parent "~5.1.0" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.4.0" + optionalDependencies: + fsevents "~2.1.2" + +cliui@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" + integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^6.2.0" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +colorette@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" + integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +cosmiconfig@^5.0.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a" + integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA== + dependencies: + import-fresh "^2.0.0" + is-directory "^0.3.1" + js-yaml "^3.13.1" + parse-json "^4.0.0" + +decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + +dependency-graph@^0.8.0: + version "0.8.1" + resolved "https://registry.yarnpkg.com/dependency-graph/-/dependency-graph-0.8.1.tgz#9b8cae3aa2c7bd95ccb3347a09a2d1047a6c3c5a" + integrity sha512-g213uqF8fyk40W8SBjm079n3CZB4qSpCrA2ye1fLGzH/4HEgB6tzuW2CbLE7leb4t45/6h44Ud59Su1/ROTfqw== + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +electron-to-chromium@^1.3.723: + version "1.3.736" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.736.tgz#f632d900a1f788dab22fec9c62ec5c9c8f0c4052" + integrity sha512-DY8dA7gR51MSo66DqitEQoUMQ0Z+A2DSXFi7tK304bdTVqczCAfUuyQw6Wdg8hIoo5zIxkU1L24RQtUce1Ioig== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +fast-glob@^3.0.3: + version "3.2.4" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.4.tgz#d20aefbf99579383e7f3cc66529158c9b98554d3" + integrity sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.0" + merge2 "^1.3.0" + micromatch "^4.0.2" + picomatch "^2.2.1" + +fastq@^1.6.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.8.0.tgz#550e1f9f59bbc65fe185cb6a9b4d95357107f481" + integrity sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q== + dependencies: + reusify "^1.0.4" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +fs-extra@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@~2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" + integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== + +get-caller-file@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-stdin@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-7.0.0.tgz#8d5de98f15171a125c5e516643c7a6d0ea8a96f6" + integrity sha512-zRKcywvrXlXsA0v0i9Io4KDRaAw7+a1ZpjRwl9Wox8PFlVCCHra7E9c4kqXCoCM9nR5tBkaTTZRBoCm60bFqTQ== + +glob-parent@^5.1.0, glob-parent@~5.1.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob@^7.1.3: + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globby@^10.0.1: + version "10.0.2" + resolved "https://registry.yarnpkg.com/globby/-/globby-10.0.2.tgz#277593e745acaa4646c3ab411289ec47a0392543" + integrity sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg== + dependencies: + "@types/glob" "^7.1.1" + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.0.3" + glob "^7.1.3" + ignore "^5.1.1" + merge2 "^1.2.3" + slash "^3.0.0" + +graceful-fs@^4.1.6, graceful-fs@^4.2.0: + version "4.2.4" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" + integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +ignore@^5.1.1: + version "5.1.8" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" + integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== + +import-cwd@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9" + integrity sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk= + dependencies: + import-from "^2.1.0" + +import-fresh@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" + integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY= + dependencies: + caller-path "^2.0.0" + resolve-from "^3.0.0" + +import-from@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-from/-/import-from-2.1.0.tgz#335db7f2a7affd53aaa471d4b8021dee36b7f3b1" + integrity sha1-M1238qev/VOqpHHUuAId7ja387E= + dependencies: + resolve-from "^3.0.0" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-directory@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" + integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +js-yaml@^3.13.1: + version "3.14.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482" + integrity sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +json-parse-better-errors@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= + optionalDependencies: + graceful-fs "^4.1.6" + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +lodash@^4.17.11: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +log-symbols@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" + integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg== + dependencies: + chalk "^2.0.1" + +merge2@^1.2.3, merge2@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +micromatch@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" + integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== + dependencies: + braces "^3.0.1" + picomatch "^2.0.5" + +minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +node-releases@^1.1.71: + version "1.1.72" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.72.tgz#14802ab6b1039a79a0c7d662b610a5bbd76eacbe" + integrity sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw== + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +normalize-range@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" + integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= + +num2fraction@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" + integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4= + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1: + version "2.2.2" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" + integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== + +pify@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= + +postcss-cli@7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/postcss-cli/-/postcss-cli-7.1.0.tgz#769b07b8865aaa3e98c7c63a3d256b4f51e3e237" + integrity sha512-tCGK0GO2reu644dUHxks8U2SAtKnzftQTAXN1dwzFPoKXZr0b7VX4vTkQ2Pl2Lunas6+o8uHR56hlcYBm1srZg== + dependencies: + chalk "^3.0.0" + chokidar "^3.3.0" + dependency-graph "^0.8.0" + fs-extra "^8.1.0" + get-stdin "^7.0.0" + globby "^10.0.1" + postcss "^7.0.0" + postcss-load-config "^2.0.0" + postcss-reporter "^6.0.0" + pretty-hrtime "^1.0.3" + read-cache "^1.0.0" + yargs "^15.0.2" + +postcss-load-config@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-2.1.0.tgz#c84d692b7bb7b41ddced94ee62e8ab31b417b003" + integrity sha512-4pV3JJVPLd5+RueiVVB+gFOAa7GWc25XQcMp86Zexzke69mKf6Nx9LRcQywdz7yZI9n1udOxmLuAwTBypypF8Q== + dependencies: + cosmiconfig "^5.0.0" + import-cwd "^2.0.0" + +postcss-reporter@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/postcss-reporter/-/postcss-reporter-6.0.1.tgz#7c055120060a97c8837b4e48215661aafb74245f" + integrity sha512-LpmQjfRWyabc+fRygxZjpRxfhRf9u/fdlKf4VHG4TSPbV2XNsuISzYW1KL+1aQzx53CAppa1bKG4APIB/DOXXw== + dependencies: + chalk "^2.4.1" + lodash "^4.17.11" + log-symbols "^2.2.0" + postcss "^7.0.7" + +postcss-value-parser@^4.0.2: + version "4.1.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb" + integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ== + +postcss@^7.0.0, postcss@^7.0.26, postcss@^7.0.7: + version "7.0.36" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.36.tgz#056f8cffa939662a8f5905950c07d5285644dfcb" + integrity sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw== + dependencies: + chalk "^2.4.2" + source-map "^0.6.1" + supports-color "^6.1.0" + +pretty-hrtime@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" + integrity sha1-t+PqQkNaTJsnWdmeDyAesZWALuE= + +read-cache@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/read-cache/-/read-cache-1.0.0.tgz#e664ef31161166c9751cdbe8dbcf86b5fb58f774" + integrity sha1-5mTvMRYRZsl1HNvo28+GtftY93Q= + dependencies: + pify "^2.3.0" + +readdirp@~3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.4.0.tgz#9fdccdf9e9155805449221ac645e8303ab5b9ada" + integrity sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ== + dependencies: + picomatch "^2.2.1" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + +resolve-from@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" + integrity sha1-six699nWiBvItuZTM17rywoYh0g= + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +run-parallel@^1.1.9: + version "1.1.9" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.9.tgz#c9dd3a7cf9f4b2c4b6244e173a6ed866e61dd679" + integrity sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q== + +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +source-map@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +string-width@^4.1.0, string-width@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" + integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.0" + +strip-ansi@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" + integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== + dependencies: + ansi-regex "^5.0.0" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" + integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + +wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +y18n@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.1.tgz#8db2b83c31c5d75099bb890b23f3094891e247d4" + integrity sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ== + +yargs-parser@^18.1.2: + version "18.1.3" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" + integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs@^15.0.2: + version "15.4.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8" + integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A== + dependencies: + cliui "^6.0.0" + decamelize "^1.2.0" + find-up "^4.1.0" + get-caller-file "^2.0.1" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^4.2.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^18.1.2"