├── .github
├── mergify.yml
└── workflows
│ └── container-image.yml
├── .gitignore
├── .gitlint
├── .yamllint.yaml
├── LICENSE
├── Makefile
├── Makefile.opensuse
├── README.md
├── docs
├── development.md
├── release-process.md
└── server.md
├── examples
├── kubernetes
│ ├── README.md
│ ├── pv.yml
│ ├── pvc.yml
│ ├── samba-ad-server-deployment.yml
│ ├── samba-ctdb-dm-sset.yml
│ ├── samba-ctdb-sset.yml
│ ├── sambadeployment.converged.yml
│ ├── sambadeployment.yml
│ ├── sambadmpod.yml
│ └── sambapod.yml
└── podman
│ ├── README.md
│ ├── config.json
│ └── smb-wb-pod.sh
├── hack
├── build-image
├── install-tools.sh
└── release-gen-download-section.sh
├── images
├── ad-server
│ ├── Containerfile.centos
│ ├── Containerfile.fedora
│ ├── Containerfile.opensuse
│ ├── install-packages.sh
│ └── install-sambacc.sh
├── client
│ ├── Containerfile.centos
│ ├── Containerfile.fedora
│ └── Containerfile.opensuse
├── common
│ └── install-sambacc-common.sh
├── server
│ ├── Containerfile.centos
│ ├── Containerfile.fedora
│ ├── Containerfile.opensuse
│ ├── install-packages.sh
│ ├── install-sambacc.sh
│ └── smb.conf
└── toolbox
│ ├── Containerfile.centos
│ ├── Containerfile.fedora
│ └── Containerfile.opensuse
└── tests
├── common.sh
├── files
├── coredns-snippet.template
├── samba-ad-server-deployment.yml
└── samba-domain-member-pod.yml
├── test-deploy-ad-member.sh
├── test-deploy-ad-server.sh
├── test-remove-ad-member.sh
├── test-remove-ad-server.sh
├── test-samba-ad-server-kubernetes.sh
└── test-samba-container.sh
/.github/mergify.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # each test should be listed separately, do not use regular expressions:
3 | # https://docs.mergify.io/conditions.html#validating-all-status-check
4 | # TODO: Use mergify's recently added 'shared configuration support'
5 | # to dedup some of the check-x=y repetition in the future.
6 | queue_rules:
7 | - name: default
8 | conditions:
9 | - check-success=checks
10 | - check-success=check-commits
11 | - check-success=build-server (default, centos, amd64)
12 | - check-success=build-server (default, fedora, amd64)
13 | - check-success=build-server (default, opensuse, amd64)
14 | - check-success=build-server (nightly, centos, amd64)
15 | - check-success=build-server (nightly, fedora, amd64)
16 | - check-success=build-ad-server (default, fedora, amd64)
17 | - check-success=build-ad-server (default, opensuse, amd64)
18 | - check-success=build-ad-server (nightly, centos, amd64)
19 | - check-success=build-ad-server (nightly, fedora, amd64)
20 | - check-success=build-client (centos, amd64)
21 | - check-success=build-client (fedora, amd64)
22 | - check-success=build-client (opensuse, amd64)
23 | - check-success=build-toolbox (centos, amd64)
24 | - check-success=build-toolbox (fedora, amd64)
25 | - check-success=build-toolbox (opensuse, amd64)
26 | - check-success=test-server (default, centos, amd64)
27 | - check-success=test-server (default, fedora, amd64)
28 | - check-success=test-server (default, opensuse, amd64)
29 | - check-success=test-server (nightly, centos, amd64)
30 | - check-success=test-server (nightly, fedora, amd64)
31 | - check-success=test-ad-server-kubernetes (default, fedora, amd64)
32 | - check-success=test-ad-server-kubernetes (default, opensuse, amd64)
33 | - check-success=test-ad-server-kubernetes (nightly, centos, amd64)
34 | - check-success=test-ad-server-kubernetes (nightly, fedora, amd64)
35 | - check-success=dpulls
36 | merge_method: rebase
37 | update_method: rebase
38 |
39 |
40 | pull_request_rules:
41 | # Clearing approvals after content changes
42 | - name: Remove outdated approvals
43 | conditions:
44 | - base=master
45 | actions:
46 | dismiss_reviews:
47 | approved: true
48 | changes_requested: false
49 | # Perform automatic merge on conditions
50 | - name: Automatic merge on approval
51 | conditions:
52 | - check-success=checks
53 | - check-success=check-commits
54 | - check-success=build-server (default, centos, amd64)
55 | - check-success=build-server (default, fedora, amd64)
56 | - check-success=build-server (default, opensuse, amd64)
57 | - check-success=build-server (nightly, centos, amd64)
58 | - check-success=build-server (nightly, fedora, amd64)
59 | - check-success=build-ad-server (default, fedora, amd64)
60 | - check-success=build-ad-server (default, opensuse, amd64)
61 | - check-success=build-ad-server (nightly, centos, amd64)
62 | - check-success=build-ad-server (nightly, fedora, amd64)
63 | - check-success=build-client (centos, amd64)
64 | - check-success=build-client (fedora, amd64)
65 | - check-success=build-client (opensuse, amd64)
66 | - check-success=build-toolbox (centos, amd64)
67 | - check-success=build-toolbox (fedora, amd64)
68 | - check-success=build-toolbox (opensuse, amd64)
69 | - check-success=test-server (default, centos, amd64)
70 | - check-success=test-server (default, fedora, amd64)
71 | - check-success=test-server (default, opensuse, amd64)
72 | - check-success=test-server (nightly, centos, amd64)
73 | - check-success=test-server (nightly, fedora, amd64)
74 | - check-success=test-ad-server-kubernetes (default, fedora, amd64)
75 | - check-success=test-ad-server-kubernetes (default, opensuse, amd64)
76 | - check-success=test-ad-server-kubernetes (nightly, centos, amd64)
77 | - check-success=test-ad-server-kubernetes (nightly, fedora, amd64)
78 | - check-success=dpulls
79 | - "-draft"
80 | # Contributors should set the 'do-not-merge' label if they don't want
81 | # the PR to be (auto)merged for some reason.
82 | - "label!=do-not-merge"
83 | # A reviewer should set a label starting with 'review-in-progress' (and
84 | # suffixed by their username) in order to indicate a detailed review has
85 | # been started and not completed. This will hold the PR until the
86 | # label has been removed.
87 | - "-label~=^review-in-progress"
88 | - "base=master"
89 | # Even if there are 2 or more approvals we won't automerge if there are
90 | # any changes requested.
91 | - "#changes-requested-reviews-by=0"
92 | - or:
93 | # Any contributor's PR can be automerged with 2 (or more) reviews.
94 | - "#approved-reviews-by>=2"
95 | # A maintainer's contribution that has already aged long enough to
96 | # earn the "priority-review" label can be merged immediately.
97 | # The label can also be applied manually in case of an important
98 | # bugfix, etc.
99 | - and:
100 | - "label=priority-review"
101 | - "author=@maintainers"
102 | - "#approved-reviews-by>=1"
103 | actions:
104 | queue: {}
105 | dismiss_reviews: {}
106 | # Conflict resolution prompt
107 | - name: Ask contributor to resolve a conflict
108 | conditions:
109 | - conflict
110 | actions:
111 | comment:
112 | message: "This pull request now has conflicts with the target branch.
113 | Please resolve these conflicts and force push the updated branch."
114 | # Label PRs that have been sitting there unchanged, aging like a fine wine
115 | #
116 | # NOTE: the updated-at "counter" resets every time the PR is changed so
117 | # reacting to a reviewer's feedback and fixing a typo (for example) will
118 | # reset the counter. Thus we now apply a label once we hit the 15 day window
119 | # so that we know that PR had, at some time, sat unchanged for that long.
120 | - name: Label aged PRs
121 | conditions:
122 | - "updated-at<15 days ago"
123 | - "-draft"
124 | actions:
125 | label:
126 | add:
127 | - "priority-review"
128 |
--------------------------------------------------------------------------------
/.github/workflows/container-image.yml:
--------------------------------------------------------------------------------
1 | name: Samba Container Image CI
2 |
3 | on:
4 | push:
5 | branches: [master]
6 | pull_request:
7 | branches: [master]
8 | schedule:
9 | - cron: '0 2 * * *'
10 | # Allow manually triggering a run in the github ui.
11 | # See: https://docs.github.com/en/actions/using-workflows/manually-running-a-workflow
12 | workflow_dispatch: {}
13 |
14 | env:
15 | CONTAINER_CMD: docker
16 | jobs:
17 | checks:
18 | runs-on: ubuntu-latest
19 | steps:
20 | - uses: actions/checkout@v4
21 | # We need a newer version of shellcheck to avoid problems with the
22 | # relative imports. Our scripts work on v0.7.2 and up but not the
23 | # v0.7.0 preinstalled in the ubutnu image. We can force a local
24 | # install by expliclity setting SHELLCHECK to `$ALT_BIN/shellcheck`
25 | - name: Run static check tools
26 | run: make check SHELLCHECK=$PWD/.bin/shellcheck
27 |
28 | check-commits:
29 | runs-on: ubuntu-latest
30 | if: github.event_name == 'pull_request'
31 | steps:
32 | - uses: actions/checkout@v4
33 | with:
34 | fetch-depth: 0
35 | ref: ${{ github.event.pull_request.head.sha }}
36 | - name: Ensure branches
37 | run: git fetch
38 | - name: Lint git commit messages
39 | run: make check-gitlint
40 |
41 | build-server:
42 | # Reminder: the nightly-server images consume nightly samba rpm builds
43 | # it is not *just* an image that gets built nightly
44 | strategy:
45 | matrix:
46 | package_source: [default, nightly]
47 | os: [centos, fedora, opensuse]
48 | arch: [amd64, arm64]
49 | exclude:
50 | # there are no nightly packages for opensuse
51 | - package_source: nightly
52 | os: opensuse
53 | - os: centos
54 | arch: arm64
55 | include:
56 | - package_source: devbuilds
57 | os: centos
58 | arch: amd64
59 | runs-on: ubuntu-latest
60 | env:
61 | BUILDAH_FORMAT: oci
62 | IMG_TAG: ${{ matrix.package_source }}-${{ matrix.os }}-${{ matrix.arch }}
63 | steps:
64 | - uses: actions/checkout@v4
65 | - name: Build the server image
66 | run: make KIND=server PACKAGE_SOURCE=${{ matrix.package_source }} OS_NAME=${{ matrix.os}} BUILD_ARCH=${{ matrix.arch}} build-image
67 | - name: Upload server image
68 | uses: ishworkh/container-image-artifact-upload@v2.0.0
69 | with:
70 | image: "samba-server:${{ env.IMG_TAG }}"
71 | container_engine: ${{ env.CONTAINER_CMD }}
72 | retention_days: 1
73 |
74 | build-ad-server:
75 | strategy:
76 | matrix:
77 | package_source: [default, nightly]
78 | os: [centos, fedora, opensuse]
79 | arch: [amd64, arm64]
80 | exclude:
81 | # there are no nightly packages for opensuse
82 | - package_source: nightly
83 | os: opensuse
84 | # the distro packages for centos do not include an ad-dc
85 | - package_source: default
86 | os: centos
87 | - os: centos
88 | arch: arm64
89 | runs-on: ubuntu-latest
90 | env:
91 | BUILDAH_FORMAT: oci
92 | IMG_TAG: ${{ matrix.package_source }}-${{ matrix.os }}-${{ matrix.arch }}
93 | steps:
94 | - uses: actions/checkout@v4
95 | - name: Build the ad server image
96 | run: make KIND=ad-server PACKAGE_SOURCE=${{ matrix.package_source }} OS_NAME=${{ matrix.os }} BUILD_ARCH=${{ matrix.arch }} build-image
97 | - name: Upload ad server image
98 | uses: ishworkh/container-image-artifact-upload@v2.0.0
99 | with:
100 | image: "samba-ad-server:${{ env.IMG_TAG }}"
101 | container_engine: ${{ env.CONTAINER_CMD }}
102 | retention_days: 1
103 |
104 | build-client:
105 | strategy:
106 | matrix:
107 | os: [centos, fedora, opensuse]
108 | arch: [amd64, arm64]
109 | exclude:
110 | - os: centos
111 | arch: arm64
112 | runs-on: ubuntu-latest
113 | env:
114 | BUILDAH_FORMAT: oci
115 | IMG_TAG: default-${{ matrix.os }}-${{ matrix.arch }}
116 | steps:
117 | - uses: actions/checkout@v4
118 | - name: build the client image
119 | run: make KIND=client OS_NAME=${{ matrix.os }} BUILD_ARCH=${{ matrix.arch }} build-image
120 | # The client image is used as a base for the samba-toolbox build process.
121 | - name: Upload the client image
122 | uses: ishworkh/container-image-artifact-upload@v2.0.0
123 | with:
124 | image: "samba-client:${{ env.IMG_TAG }}"
125 | container_engine: ${{ env.CONTAINER_CMD }}
126 | retention_days: 1
127 |
128 | build-toolbox:
129 | strategy:
130 | matrix:
131 | os: [centos, fedora, opensuse]
132 | arch: [amd64]
133 | needs: build-client
134 | runs-on: ubuntu-latest
135 | env:
136 | BUILDAH_FORMAT: oci
137 | IMG_TAG: default-${{ matrix.os }}-${{ matrix.arch }}
138 | steps:
139 | - uses: actions/checkout@v4
140 | # Download locally stored samba-client image to be used as base for building
141 | # samba-toolbox.
142 | - name: Download client image
143 | uses: ishworkh/container-image-artifact-download@v2.0.0
144 | with:
145 | image: "samba-client:${{ env.IMG_TAG }}"
146 | container_engine: ${{ env.CONTAINER_CMD }}
147 | # Workaround: retag the image so that the FQIN image matches the name in
148 | # the toolbox containerfiles.
149 | - name: Apply OS-latest tag to image (for centos)
150 | run: ${{ env.CONTAINER_CMD }} tag samba-client:${{ env.IMG_TAG }} quay.io/samba.org/samba-client:${{ matrix.os }}-latest
151 | - name: Apply latest tag to image (for fedora)
152 | run: ${{ env.CONTAINER_CMD }} tag samba-client:${{ env.IMG_TAG }} quay.io/samba.org/samba-client:latest
153 | - name: Build the toolbox image
154 | run: make KIND=toolbox OS_NAME=${{ matrix.os }} BUILD_ARCH=${{ matrix.arch }} build-image
155 | # Upload the toolbox image for reference and/or image push
156 | - name: Upload the toolbox image
157 | uses: ishworkh/container-image-artifact-upload@v2.0.0
158 | with:
159 | image: "samba-toolbox:${{ env.IMG_TAG }}"
160 | container_engine: ${{ env.CONTAINER_CMD }}
161 | retention_days: 1
162 |
163 | test-server:
164 | strategy:
165 | matrix:
166 | package_source: [default, nightly]
167 | os: [centos, fedora, opensuse]
168 | arch: [amd64]
169 | exclude:
170 | # there are no nightly packages for opensuse
171 | - package_source: nightly
172 | os: opensuse
173 | include:
174 | - package_source: devbuilds
175 | os: centos
176 | arch: amd64
177 | needs: build-server
178 | runs-on: ubuntu-latest
179 | env:
180 | BUILDAH_FORMAT: oci
181 | IMG_TAG: ${{ matrix.package_source }}-${{ matrix.os }}-${{ matrix.arch }}
182 | steps:
183 | - uses: actions/checkout@v4
184 | - name: Download server image
185 | uses: ishworkh/container-image-artifact-download@v2.0.0
186 | with:
187 | image: "samba-server:${{ env.IMG_TAG }}"
188 | container_engine: ${{ env.CONTAINER_CMD }}
189 | - name: Test the server image
190 | run: LOCAL_TAG=samba-server:${{ env.IMG_TAG }} tests/test-samba-container.sh
191 |
192 | test-ad-server-kubernetes:
193 | strategy:
194 | matrix:
195 | package_source: [default, nightly]
196 | os: [centos, fedora, opensuse]
197 | arch: [amd64]
198 | exclude:
199 | # there are no nightly packages for opensuse
200 | - package_source: nightly
201 | os: opensuse
202 | # the distro packages for centos do not include an ad-dc
203 | - package_source: default
204 | os: centos
205 | needs:
206 | - build-ad-server
207 | - build-server
208 | runs-on: ubuntu-latest
209 | env:
210 | BUILDAH_FORMAT: oci
211 | IMG_TAG: ${{ matrix.package_source }}-${{ matrix.os }}-${{ matrix.arch }}
212 | steps:
213 | - uses: actions/checkout@v4
214 | - uses: nolar/setup-k3d-k3s@v1
215 | - name: get nodes
216 | run: kubectl get nodes
217 | - name: Download ad server image
218 | uses: ishworkh/container-image-artifact-download@v2.0.0
219 | with:
220 | image: "samba-ad-server:${{ env.IMG_TAG }}"
221 | container_engine: ${{ env.CONTAINER_CMD }}
222 | - name: Download file server image
223 | uses: ishworkh/container-image-artifact-download@v2.0.0
224 | with:
225 | image: "samba-server:${{ env.IMG_TAG }}"
226 | container_engine: ${{ env.CONTAINER_CMD }}
227 | - name: import images to k3d
228 | run: k3d image import samba-server:${{ env.IMG_TAG }} samba-ad-server:${{ env.IMG_TAG }}
229 | - name: run the ad-dc deployment test
230 | run: ./tests/test-samba-ad-server-kubernetes.sh
231 |
232 | push:
233 | # verify it passes the test jobs first
234 | needs:
235 | - build-client
236 | - build-toolbox
237 | - test-server
238 | - test-ad-server-kubernetes
239 | runs-on: ubuntu-latest
240 | env:
241 | REPO_BASE: quay.io/samba.org
242 | # NOTE: the fromJSON below is needed beause the syntax github uses
243 | # doesn't actually understand JS/JSON style arrays (inline). When I left it
244 | # out I just got an error. It is present in their example(s).
245 | if: >
246 | contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name)
247 | && github.repository == 'samba-in-kubernetes/samba-container'
248 | steps:
249 | - uses: actions/checkout@v4
250 | - name: log in to quay.io
251 | run: ${CONTAINER_CMD} login -u "${{ secrets.QUAY_USER }}" -p "${{ secrets.QUAY_PASS }}" quay.io
252 | # pull in already built images we plan on pushing
253 | # (server images)
254 | - name: Fetch server default-fedora-amd64
255 | uses: ishworkh/container-image-artifact-download@v2.0.0
256 | with:
257 | image: "samba-server:default-fedora-amd64"
258 | container_engine: ${{ env.CONTAINER_CMD }}
259 | - name: Fetch server default-fedora-arm64
260 | uses: ishworkh/container-image-artifact-download@v2.0.0
261 | with:
262 | image: "samba-server:default-fedora-arm64"
263 | container_engine: ${{ env.CONTAINER_CMD }}
264 | - name: Fetch server default-opensuse-arm64
265 | uses: ishworkh/container-image-artifact-download@v2.0.0
266 | with:
267 | image: "samba-server:default-opensuse-arm64"
268 | container_engine: ${{ env.CONTAINER_CMD }}
269 | - name: Fetch server nightly-fedora-amd64
270 | uses: ishworkh/container-image-artifact-download@v2.0.0
271 | with:
272 | image: "samba-server:nightly-fedora-amd64"
273 | container_engine: ${{ env.CONTAINER_CMD }}
274 | - name: Fetch server nightly-fedora-arm64
275 | uses: ishworkh/container-image-artifact-download@v2.0.0
276 | with:
277 | image: "samba-server:nightly-fedora-arm64"
278 | container_engine: ${{ env.CONTAINER_CMD }}
279 | - name: Fetch server nightly-centos-amd64
280 | uses: ishworkh/container-image-artifact-download@v2.0.0
281 | with:
282 | image: "samba-server:nightly-centos-amd64"
283 | container_engine: ${{ env.CONTAINER_CMD }}
284 | - name: Fetch server devbuilds-centos-amd64
285 | uses: ishworkh/container-image-artifact-download@v2.0.0
286 | with:
287 | image: "samba-server:devbuilds-centos-amd64"
288 | container_engine: ${{ env.CONTAINER_CMD }}
289 | # (ad server images)
290 | - name: Fetch ad-server default-fedora-amd64
291 | uses: ishworkh/container-image-artifact-download@v2.0.0
292 | with:
293 | image: "samba-ad-server:default-fedora-amd64"
294 | container_engine: ${{ env.CONTAINER_CMD }}
295 | - name: Fetch ad-server default-fedora-arm64
296 | uses: ishworkh/container-image-artifact-download@v2.0.0
297 | with:
298 | image: "samba-ad-server:default-fedora-arm64"
299 | container_engine: ${{ env.CONTAINER_CMD }}
300 | - name: Fetch ad-server default-opensuse-arm64
301 | uses: ishworkh/container-image-artifact-download@v2.0.0
302 | with:
303 | image: "samba-ad-server:default-opensuse-arm64"
304 | container_engine: ${{ env.CONTAINER_CMD }}
305 | - name: Fetch ad-server nightly-fedora-amd64
306 | uses: ishworkh/container-image-artifact-download@v2.0.0
307 | with:
308 | image: "samba-ad-server:nightly-fedora-amd64"
309 | container_engine: ${{ env.CONTAINER_CMD }}
310 | - name: Fetch ad-server nightly-fedora-arm64
311 | uses: ishworkh/container-image-artifact-download@v2.0.0
312 | with:
313 | image: "samba-ad-server:nightly-fedora-arm64"
314 | container_engine: ${{ env.CONTAINER_CMD }}
315 | # (client images)
316 | - name: Fetch client default-fedora-amd64
317 | uses: ishworkh/container-image-artifact-download@v2.0.0
318 | with:
319 | image: "samba-client:default-fedora-amd64"
320 | container_engine: ${{ env.CONTAINER_CMD }}
321 | - name: Fetch client default-fedora-arm64
322 | uses: ishworkh/container-image-artifact-download@v2.0.0
323 | with:
324 | image: "samba-client:default-fedora-arm64"
325 | container_engine: ${{ env.CONTAINER_CMD }}
326 | - name: Fetch client default-opensuse-arm64
327 | uses: ishworkh/container-image-artifact-download@v2.0.0
328 | with:
329 | image: "samba-client:default-opensuse-arm64"
330 | container_engine: ${{ env.CONTAINER_CMD }}
331 | # (toolbox images)
332 | - name: Fetch toolbox default-fedora-amd64
333 | uses: ishworkh/container-image-artifact-download@v2.0.0
334 | with:
335 | image: "samba-toolbox:default-fedora-amd64"
336 | container_engine: ${{ env.CONTAINER_CMD }}
337 | # reapply missing tags
338 | - name: Retag images
339 | run: >
340 | ./hack/build-image
341 | --retag
342 | --container-engine=${CONTAINER_CMD}
343 | --repo-base=${REPO_BASE}
344 | --no-distro-qualified
345 | -i samba-server:default-fedora-amd64
346 | -i samba-server:default-fedora-arm64
347 | -i samba-server:default-opensuse-arm64
348 | -i samba-server:nightly-fedora-amd64
349 | -i samba-server:nightly-fedora-arm64
350 | -i samba-server:nightly-centos-amd64
351 | -i samba-server:devbuilds-centos-amd64
352 | -i samba-ad-server:default-fedora-amd64
353 | -i samba-ad-server:default-fedora-arm64
354 | -i samba-ad-server:default-opensuse-arm64
355 | -i samba-ad-server:nightly-fedora-amd64
356 | -i samba-ad-server:nightly-fedora-arm64
357 | -i samba-client:default-fedora-amd64
358 | -i samba-client:default-fedora-arm64
359 | -i samba-client:default-opensuse-arm64
360 | -i samba-toolbox:default-fedora-amd64
361 | - name: Push images
362 | run: >
363 | ./hack/build-image
364 | --push
365 | --container-engine=${CONTAINER_CMD}
366 | --verbose
367 | --push-state=exists
368 | --push-selected-tags=mixed
369 | -i ${REPO_BASE}/samba-server:default-fedora-amd64
370 | -i ${REPO_BASE}/samba-server:default-fedora-arm64
371 | -i ${REPO_BASE}/samba-server:default-opensuse-arm64
372 | -i ${REPO_BASE}/samba-server:nightly-fedora-amd64
373 | -i ${REPO_BASE}/samba-server:nightly-centos-amd64
374 | -i ${REPO_BASE}/samba-server:devbuilds-centos-amd64
375 | -i ${REPO_BASE}/samba-ad-server:default-fedora-amd64
376 | -i ${REPO_BASE}/samba-ad-server:default-fedora-arm64
377 | -i ${REPO_BASE}/samba-ad-server:default-opensuse-arm64
378 | -i ${REPO_BASE}/samba-ad-server:nightly-fedora-amd64
379 | -i ${REPO_BASE}/samba-client:default-fedora-amd64
380 | -i ${REPO_BASE}/samba-client:default-fedora-arm64
381 | -i ${REPO_BASE}/samba-client:default-opensuse-arm64
382 | -i ${REPO_BASE}/samba-toolbox:default-fedora-amd64
383 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *~
2 | .build.server
3 | .build.opensuse-server
4 | .build.ad-server
5 | .build.opensuse-ad-server
6 | .build.client
7 | .build.opensuse-client
8 | .build.toolbox
9 | .build.opensuse-toolbox
10 | .build.nightly.server
11 | .build.nightly.ad-server
12 | .common
13 | .bin
14 |
--------------------------------------------------------------------------------
/.gitlint:
--------------------------------------------------------------------------------
1 | # Edit this file as you like.
2 | #
3 | # All these sections are optional. Each section with the exception of [general] represents
4 | # one rule and each key in it is an option for that specific rule.
5 | #
6 | # Rules and sections can be referenced by their full name or by id. For example
7 | # section "[body-max-line-length]" could also be written as "[B1]". Full section names are
8 | # used in here for clarity.
9 | #
10 | [general]
11 | # Ignore certain rules, this example uses both full name and id
12 | # ignore=title-trailing-punctuation, T3
13 |
14 | # verbosity should be a value between 1 and 3, the commandline -v flags take precedence over this
15 | verbosity=3
16 |
17 | # By default gitlint will ignore merge, revert, fixup and squash commits.
18 | ignore-merge-commits=true
19 | # ignore-revert-commits=true
20 | # ignore-fixup-commits=true
21 | # ignore-squash-commits=true
22 |
23 | # Ignore any data send to gitlint via stdin
24 | # ignore-stdin=true
25 |
26 | # Fetch additional meta-data from the local repository when manually passing a
27 | # commit message to gitlint via stdin or --commit-msg. Disabled by default.
28 | # staged=true
29 |
30 | # Enable debug mode (prints more output). Disabled by default.
31 | # debug=true
32 |
33 | # Enable search regex and remove warning message.
34 | regex-style-search=true
35 |
36 | # Enable community contributed rules
37 | # See http://jorisroovers.github.io/gitlint/contrib_rules for details
38 | # contrib=contrib-body-requires-signed-off-by
39 |
40 | # Set the extra-path where gitlint will search for user defined rules
41 | # See http://jorisroovers.github.io/gitlint/user_defined_rules for details
42 | # extra-path=examples/
43 |
44 | # This is an example of how to configure the "title-max-length" rule and
45 | # set the line-length it enforces to 80
46 | [title-max-length]
47 | line-length=72
48 |
49 | # Conversely, you can also enforce minimal length of a title with the
50 | # "title-min-length" rule:
51 | # [title-min-length]
52 | # min-length=5
53 |
54 | [title-must-not-contain-word]
55 | # Comma-separated list of words that should not occur in the title. Matching is case
56 | # insensitive. It's fine if the keyword occurs as part of a larger word (so "WIPING"
57 | # will not cause a violation, but "WIP: my title" will.
58 | words=wip,WIP
59 |
60 | [title-match-regex]
61 | # python-style regex that the commit-msg title must match
62 | # Note that the regex can contradict with other rules if not used correctly
63 | # (e.g. title-must-not-contain-word).
64 | regex=^.*
65 |
66 | # [body-max-line-length]
67 | # line-length=72
68 |
69 | # [body-min-length]
70 | # min-length=5
71 |
72 | # [body-is-missing]
73 | # Whether to ignore this rule on merge commits (which typically only have a title)
74 | # default = True
75 | # ignore-merge-commits=false
76 |
77 | # [body-changed-file-mention]
78 | # List of files that need to be explicitly mentioned in the body when they are changed
79 | # This is useful for when developers often erroneously edit certain files or git submodules.
80 | # By specifying this rule, developers can only change the file when they explicitly reference
81 | # it in the commit message.
82 | # files=gitlint/rules.py,README.md
83 |
84 | # [body-match-regex]
85 | # python-style regex that the commit-msg body must match.
86 | # E.g. body must end in My-Commit-Tag: foo
87 | # regex=My-Commit-Tag: foo$
88 |
89 | # [author-valid-email]
90 | # python-style regex that the commit author email address must match.
91 | # For example, use the following regex if you only want to allow email addresses from foo.com
92 | # regex=[^@]+@foo.com
93 |
94 | # [ignore-by-title]
95 | # Ignore certain rules for commits of which the title matches a regex
96 | # E.g. Match commit titles that start with "Release"
97 | # regex=^Release(.*)
98 |
99 | # Ignore certain rules, you can reference them by their id or by their full name
100 | # Use 'all' to ignore all rules
101 | # ignore=T1,body-min-length
102 |
103 | # [ignore-by-body]
104 | # Ignore certain rules for commits of which the body has a line that matches a regex
105 | # E.g. Match bodies that have a line that that contain "release"
106 | # regex=(.*)release(.*)
107 | #
108 | # Ignore certain rules, you can reference them by their id or by their full name
109 | # Use 'all' to ignore all rules
110 | # ignore=T1,body-min-length
111 |
112 | [ignore-body-lines]
113 | # Ignore certain lines in a commit body that match a regex.
114 | # E.g. Ignore all lines that start with 'Co-Authored-By'
115 | # regex=^Co-Authored-By
116 |
117 | # ignore lines that are "footnotes", that start like `[1]: ` or `[2]: ` and so on
118 | # this will make it easy to put long urls in commit messages without
119 | # triggering gitlint body rules
120 | regex=^\[[0-9]+\]:? +
121 |
122 | # This is a contrib rule - a community contributed rule. These are disabled by default.
123 | # You need to explicitly enable them one-by-one by adding them to the "contrib" option
124 | # under [general] section above.
125 | # [contrib-title-conventional-commits]
126 | # Specify allowed commit types. For details see: https://www.conventionalcommits.org/
127 | # types = bugfix,user-story,epic
128 |
--------------------------------------------------------------------------------
/.yamllint.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | extends: default
3 | yaml-files:
4 | - '*.yaml'
5 | - '*.yml'
6 | - '.yamllint'
7 | ignore: |
8 | vendor
9 | rules:
10 | braces: enable
11 | brackets: enable
12 | colons: enable
13 | commas: enable
14 | comments: disable
15 | comments-indentation:
16 | level: warning
17 | document-end: disable
18 | document-start: disable
19 | empty-lines:
20 | max-start: 1
21 | level: warning
22 | empty-values: disable
23 | hyphens: enable
24 | indentation:
25 | level: warning
26 | key-duplicates: enable
27 | key-ordering: disable
28 | line-length: disable
29 | new-line-at-end-of-file: enable
30 | new-lines: enable
31 | octal-values: enable
32 | quoted-strings: disable
33 | trailing-spaces: enable
34 | truthy:
35 | level: warning
36 | allowed-values: ['true', 'false', 'on']
37 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU General Public License is a free, copyleft license for
11 | software and other kinds of works.
12 |
13 | The licenses for most software and other practical works are designed
14 | to take away your freedom to share and change the works. By contrast,
15 | the GNU General Public License is intended to guarantee your freedom to
16 | share and change all versions of a program--to make sure it remains free
17 | software for all its users. We, the Free Software Foundation, use the
18 | GNU General Public License for most of our software; it applies also to
19 | any other work released this way by its authors. You can apply it to
20 | your programs, too.
21 |
22 | When we speak of free software, we are referring to freedom, not
23 | price. Our General Public Licenses are designed to make sure that you
24 | have the freedom to distribute copies of free software (and charge for
25 | them if you wish), that you receive source code or can get it if you
26 | want it, that you can change the software or use pieces of it in new
27 | free programs, and that you know you can do these things.
28 |
29 | To protect your rights, we need to prevent others from denying you
30 | these rights or asking you to surrender the rights. Therefore, you have
31 | certain responsibilities if you distribute copies of the software, or if
32 | you modify it: responsibilities to respect the freedom of others.
33 |
34 | For example, if you distribute copies of such a program, whether
35 | gratis or for a fee, you must pass on to the recipients the same
36 | freedoms that you received. You must make sure that they, too, receive
37 | or can get the source code. And you must show them these terms so they
38 | know their rights.
39 |
40 | Developers that use the GNU GPL protect your rights with two steps:
41 | (1) assert copyright on the software, and (2) offer you this License
42 | giving you legal permission to copy, distribute and/or modify it.
43 |
44 | For the developers' and authors' protection, the GPL clearly explains
45 | that there is no warranty for this free software. For both users' and
46 | authors' sake, the GPL requires that modified versions be marked as
47 | changed, so that their problems will not be attributed erroneously to
48 | authors of previous versions.
49 |
50 | Some devices are designed to deny users access to install or run
51 | modified versions of the software inside them, although the manufacturer
52 | can do so. This is fundamentally incompatible with the aim of
53 | protecting users' freedom to change the software. The systematic
54 | pattern of such abuse occurs in the area of products for individuals to
55 | use, which is precisely where it is most unacceptable. Therefore, we
56 | have designed this version of the GPL to prohibit the practice for those
57 | products. If such problems arise substantially in other domains, we
58 | stand ready to extend this provision to those domains in future versions
59 | of the GPL, as needed to protect the freedom of users.
60 |
61 | Finally, every program is threatened constantly by software patents.
62 | States should not allow patents to restrict development and use of
63 | software on general-purpose computers, but in those that do, we wish to
64 | avoid the special danger that patents applied to a free program could
65 | make it effectively proprietary. To prevent this, the GPL assures that
66 | patents cannot be used to render the program non-free.
67 |
68 | The precise terms and conditions for copying, distribution and
69 | modification follow.
70 |
71 | TERMS AND CONDITIONS
72 |
73 | 0. Definitions.
74 |
75 | "This License" refers to version 3 of the GNU General Public License.
76 |
77 | "Copyright" also means copyright-like laws that apply to other kinds of
78 | works, such as semiconductor masks.
79 |
80 | "The Program" refers to any copyrightable work licensed under this
81 | License. Each licensee is addressed as "you". "Licensees" and
82 | "recipients" may be individuals or organizations.
83 |
84 | To "modify" a work means to copy from or adapt all or part of the work
85 | in a fashion requiring copyright permission, other than the making of an
86 | exact copy. The resulting work is called a "modified version" of the
87 | earlier work or a work "based on" the earlier work.
88 |
89 | A "covered work" means either the unmodified Program or a work based
90 | on the Program.
91 |
92 | To "propagate" a work means to do anything with it that, without
93 | permission, would make you directly or secondarily liable for
94 | infringement under applicable copyright law, except executing it on a
95 | computer or modifying a private copy. Propagation includes copying,
96 | distribution (with or without modification), making available to the
97 | public, and in some countries other activities as well.
98 |
99 | To "convey" a work means any kind of propagation that enables other
100 | parties to make or receive copies. Mere interaction with a user through
101 | a computer network, with no transfer of a copy, is not conveying.
102 |
103 | An interactive user interface displays "Appropriate Legal Notices"
104 | to the extent that it includes a convenient and prominently visible
105 | feature that (1) displays an appropriate copyright notice, and (2)
106 | tells the user that there is no warranty for the work (except to the
107 | extent that warranties are provided), that licensees may convey the
108 | work under this License, and how to view a copy of this License. If
109 | the interface presents a list of user commands or options, such as a
110 | menu, a prominent item in the list meets this criterion.
111 |
112 | 1. Source Code.
113 |
114 | The "source code" for a work means the preferred form of the work
115 | for making modifications to it. "Object code" means any non-source
116 | form of a work.
117 |
118 | A "Standard Interface" means an interface that either is an official
119 | standard defined by a recognized standards body, or, in the case of
120 | interfaces specified for a particular programming language, one that
121 | is widely used among developers working in that language.
122 |
123 | The "System Libraries" of an executable work include anything, other
124 | than the work as a whole, that (a) is included in the normal form of
125 | packaging a Major Component, but which is not part of that Major
126 | Component, and (b) serves only to enable use of the work with that
127 | Major Component, or to implement a Standard Interface for which an
128 | implementation is available to the public in source code form. A
129 | "Major Component", in this context, means a major essential component
130 | (kernel, window system, and so on) of the specific operating system
131 | (if any) on which the executable work runs, or a compiler used to
132 | produce the work, or an object code interpreter used to run it.
133 |
134 | The "Corresponding Source" for a work in object code form means all
135 | the source code needed to generate, install, and (for an executable
136 | work) run the object code and to modify the work, including scripts to
137 | control those activities. However, it does not include the work's
138 | System Libraries, or general-purpose tools or generally available free
139 | programs which are used unmodified in performing those activities but
140 | which are not part of the work. For example, Corresponding Source
141 | includes interface definition files associated with source files for
142 | the work, and the source code for shared libraries and dynamically
143 | linked subprograms that the work is specifically designed to require,
144 | such as by intimate data communication or control flow between those
145 | subprograms and other parts of the work.
146 |
147 | The Corresponding Source need not include anything that users
148 | can regenerate automatically from other parts of the Corresponding
149 | Source.
150 |
151 | The Corresponding Source for a work in source code form is that
152 | same work.
153 |
154 | 2. Basic Permissions.
155 |
156 | All rights granted under this License are granted for the term of
157 | copyright on the Program, and are irrevocable provided the stated
158 | conditions are met. This License explicitly affirms your unlimited
159 | permission to run the unmodified Program. The output from running a
160 | covered work is covered by this License only if the output, given its
161 | content, constitutes a covered work. This License acknowledges your
162 | rights of fair use or other equivalent, as provided by copyright law.
163 |
164 | You may make, run and propagate covered works that you do not
165 | convey, without conditions so long as your license otherwise remains
166 | in force. You may convey covered works to others for the sole purpose
167 | of having them make modifications exclusively for you, or provide you
168 | with facilities for running those works, provided that you comply with
169 | the terms of this License in conveying all material for which you do
170 | not control copyright. Those thus making or running the covered works
171 | for you must do so exclusively on your behalf, under your direction
172 | and control, on terms that prohibit them from making any copies of
173 | your copyrighted material outside their relationship with you.
174 |
175 | Conveying under any other circumstances is permitted solely under
176 | the conditions stated below. Sublicensing is not allowed; section 10
177 | makes it unnecessary.
178 |
179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180 |
181 | No covered work shall be deemed part of an effective technological
182 | measure under any applicable law fulfilling obligations under article
183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
184 | similar laws prohibiting or restricting circumvention of such
185 | measures.
186 |
187 | When you convey a covered work, you waive any legal power to forbid
188 | circumvention of technological measures to the extent such circumvention
189 | is effected by exercising rights under this License with respect to
190 | the covered work, and you disclaim any intention to limit operation or
191 | modification of the work as a means of enforcing, against the work's
192 | users, your or third parties' legal rights to forbid circumvention of
193 | technological measures.
194 |
195 | 4. Conveying Verbatim Copies.
196 |
197 | You may convey verbatim copies of the Program's source code as you
198 | receive it, in any medium, provided that you conspicuously and
199 | appropriately publish on each copy an appropriate copyright notice;
200 | keep intact all notices stating that this License and any
201 | non-permissive terms added in accord with section 7 apply to the code;
202 | keep intact all notices of the absence of any warranty; and give all
203 | recipients a copy of this License along with the Program.
204 |
205 | You may charge any price or no price for each copy that you convey,
206 | and you may offer support or warranty protection for a fee.
207 |
208 | 5. Conveying Modified Source Versions.
209 |
210 | You may convey a work based on the Program, or the modifications to
211 | produce it from the Program, in the form of source code under the
212 | terms of section 4, provided that you also meet all of these conditions:
213 |
214 | a) The work must carry prominent notices stating that you modified
215 | it, and giving a relevant date.
216 |
217 | b) The work must carry prominent notices stating that it is
218 | released under this License and any conditions added under section
219 | 7. This requirement modifies the requirement in section 4 to
220 | "keep intact all notices".
221 |
222 | c) You must license the entire work, as a whole, under this
223 | License to anyone who comes into possession of a copy. This
224 | License will therefore apply, along with any applicable section 7
225 | additional terms, to the whole of the work, and all its parts,
226 | regardless of how they are packaged. This License gives no
227 | permission to license the work in any other way, but it does not
228 | invalidate such permission if you have separately received it.
229 |
230 | d) If the work has interactive user interfaces, each must display
231 | Appropriate Legal Notices; however, if the Program has interactive
232 | interfaces that do not display Appropriate Legal Notices, your
233 | work need not make them do so.
234 |
235 | A compilation of a covered work with other separate and independent
236 | works, which are not by their nature extensions of the covered work,
237 | and which are not combined with it such as to form a larger program,
238 | in or on a volume of a storage or distribution medium, is called an
239 | "aggregate" if the compilation and its resulting copyright are not
240 | used to limit the access or legal rights of the compilation's users
241 | beyond what the individual works permit. Inclusion of a covered work
242 | in an aggregate does not cause this License to apply to the other
243 | parts of the aggregate.
244 |
245 | 6. Conveying Non-Source Forms.
246 |
247 | You may convey a covered work in object code form under the terms
248 | of sections 4 and 5, provided that you also convey the
249 | machine-readable Corresponding Source under the terms of this License,
250 | in one of these ways:
251 |
252 | a) Convey the object code in, or embodied in, a physical product
253 | (including a physical distribution medium), accompanied by the
254 | Corresponding Source fixed on a durable physical medium
255 | customarily used for software interchange.
256 |
257 | b) Convey the object code in, or embodied in, a physical product
258 | (including a physical distribution medium), accompanied by a
259 | written offer, valid for at least three years and valid for as
260 | long as you offer spare parts or customer support for that product
261 | model, to give anyone who possesses the object code either (1) a
262 | copy of the Corresponding Source for all the software in the
263 | product that is covered by this License, on a durable physical
264 | medium customarily used for software interchange, for a price no
265 | more than your reasonable cost of physically performing this
266 | conveying of source, or (2) access to copy the
267 | Corresponding Source from a network server at no charge.
268 |
269 | c) Convey individual copies of the object code with a copy of the
270 | written offer to provide the Corresponding Source. This
271 | alternative is allowed only occasionally and noncommercially, and
272 | only if you received the object code with such an offer, in accord
273 | with subsection 6b.
274 |
275 | d) Convey the object code by offering access from a designated
276 | place (gratis or for a charge), and offer equivalent access to the
277 | Corresponding Source in the same way through the same place at no
278 | further charge. You need not require recipients to copy the
279 | Corresponding Source along with the object code. If the place to
280 | copy the object code is a network server, the Corresponding Source
281 | may be on a different server (operated by you or a third party)
282 | that supports equivalent copying facilities, provided you maintain
283 | clear directions next to the object code saying where to find the
284 | Corresponding Source. Regardless of what server hosts the
285 | Corresponding Source, you remain obligated to ensure that it is
286 | available for as long as needed to satisfy these requirements.
287 |
288 | e) Convey the object code using peer-to-peer transmission, provided
289 | you inform other peers where the object code and Corresponding
290 | Source of the work are being offered to the general public at no
291 | charge under subsection 6d.
292 |
293 | A separable portion of the object code, whose source code is excluded
294 | from the Corresponding Source as a System Library, need not be
295 | included in conveying the object code work.
296 |
297 | A "User Product" is either (1) a "consumer product", which means any
298 | tangible personal property which is normally used for personal, family,
299 | or household purposes, or (2) anything designed or sold for incorporation
300 | into a dwelling. In determining whether a product is a consumer product,
301 | doubtful cases shall be resolved in favor of coverage. For a particular
302 | product received by a particular user, "normally used" refers to a
303 | typical or common use of that class of product, regardless of the status
304 | of the particular user or of the way in which the particular user
305 | actually uses, or expects or is expected to use, the product. A product
306 | is a consumer product regardless of whether the product has substantial
307 | commercial, industrial or non-consumer uses, unless such uses represent
308 | the only significant mode of use of the product.
309 |
310 | "Installation Information" for a User Product means any methods,
311 | procedures, authorization keys, or other information required to install
312 | and execute modified versions of a covered work in that User Product from
313 | a modified version of its Corresponding Source. The information must
314 | suffice to ensure that the continued functioning of the modified object
315 | code is in no case prevented or interfered with solely because
316 | modification has been made.
317 |
318 | If you convey an object code work under this section in, or with, or
319 | specifically for use in, a User Product, and the conveying occurs as
320 | part of a transaction in which the right of possession and use of the
321 | User Product is transferred to the recipient in perpetuity or for a
322 | fixed term (regardless of how the transaction is characterized), the
323 | Corresponding Source conveyed under this section must be accompanied
324 | by the Installation Information. But this requirement does not apply
325 | if neither you nor any third party retains the ability to install
326 | modified object code on the User Product (for example, the work has
327 | been installed in ROM).
328 |
329 | The requirement to provide Installation Information does not include a
330 | requirement to continue to provide support service, warranty, or updates
331 | for a work that has been modified or installed by the recipient, or for
332 | the User Product in which it has been modified or installed. Access to a
333 | network may be denied when the modification itself materially and
334 | adversely affects the operation of the network or violates the rules and
335 | protocols for communication across the network.
336 |
337 | Corresponding Source conveyed, and Installation Information provided,
338 | in accord with this section must be in a format that is publicly
339 | documented (and with an implementation available to the public in
340 | source code form), and must require no special password or key for
341 | unpacking, reading or copying.
342 |
343 | 7. Additional Terms.
344 |
345 | "Additional permissions" are terms that supplement the terms of this
346 | License by making exceptions from one or more of its conditions.
347 | Additional permissions that are applicable to the entire Program shall
348 | be treated as though they were included in this License, to the extent
349 | that they are valid under applicable law. If additional permissions
350 | apply only to part of the Program, that part may be used separately
351 | under those permissions, but the entire Program remains governed by
352 | this License without regard to the additional permissions.
353 |
354 | When you convey a copy of a covered work, you may at your option
355 | remove any additional permissions from that copy, or from any part of
356 | it. (Additional permissions may be written to require their own
357 | removal in certain cases when you modify the work.) You may place
358 | additional permissions on material, added by you to a covered work,
359 | for which you have or can give appropriate copyright permission.
360 |
361 | Notwithstanding any other provision of this License, for material you
362 | add to a covered work, you may (if authorized by the copyright holders of
363 | that material) supplement the terms of this License with terms:
364 |
365 | a) Disclaiming warranty or limiting liability differently from the
366 | terms of sections 15 and 16 of this License; or
367 |
368 | b) Requiring preservation of specified reasonable legal notices or
369 | author attributions in that material or in the Appropriate Legal
370 | Notices displayed by works containing it; or
371 |
372 | c) Prohibiting misrepresentation of the origin of that material, or
373 | requiring that modified versions of such material be marked in
374 | reasonable ways as different from the original version; or
375 |
376 | d) Limiting the use for publicity purposes of names of licensors or
377 | authors of the material; or
378 |
379 | e) Declining to grant rights under trademark law for use of some
380 | trade names, trademarks, or service marks; or
381 |
382 | f) Requiring indemnification of licensors and authors of that
383 | material by anyone who conveys the material (or modified versions of
384 | it) with contractual assumptions of liability to the recipient, for
385 | any liability that these contractual assumptions directly impose on
386 | those licensors and authors.
387 |
388 | All other non-permissive additional terms are considered "further
389 | restrictions" within the meaning of section 10. If the Program as you
390 | received it, or any part of it, contains a notice stating that it is
391 | governed by this License along with a term that is a further
392 | restriction, you may remove that term. If a license document contains
393 | a further restriction but permits relicensing or conveying under this
394 | License, you may add to a covered work material governed by the terms
395 | of that license document, provided that the further restriction does
396 | not survive such relicensing or conveying.
397 |
398 | If you add terms to a covered work in accord with this section, you
399 | must place, in the relevant source files, a statement of the
400 | additional terms that apply to those files, or a notice indicating
401 | where to find the applicable terms.
402 |
403 | Additional terms, permissive or non-permissive, may be stated in the
404 | form of a separately written license, or stated as exceptions;
405 | the above requirements apply either way.
406 |
407 | 8. Termination.
408 |
409 | You may not propagate or modify a covered work except as expressly
410 | provided under this License. Any attempt otherwise to propagate or
411 | modify it is void, and will automatically terminate your rights under
412 | this License (including any patent licenses granted under the third
413 | paragraph of section 11).
414 |
415 | However, if you cease all violation of this License, then your
416 | license from a particular copyright holder is reinstated (a)
417 | provisionally, unless and until the copyright holder explicitly and
418 | finally terminates your license, and (b) permanently, if the copyright
419 | holder fails to notify you of the violation by some reasonable means
420 | prior to 60 days after the cessation.
421 |
422 | Moreover, your license from a particular copyright holder is
423 | reinstated permanently if the copyright holder notifies you of the
424 | violation by some reasonable means, this is the first time you have
425 | received notice of violation of this License (for any work) from that
426 | copyright holder, and you cure the violation prior to 30 days after
427 | your receipt of the notice.
428 |
429 | Termination of your rights under this section does not terminate the
430 | licenses of parties who have received copies or rights from you under
431 | this License. If your rights have been terminated and not permanently
432 | reinstated, you do not qualify to receive new licenses for the same
433 | material under section 10.
434 |
435 | 9. Acceptance Not Required for Having Copies.
436 |
437 | You are not required to accept this License in order to receive or
438 | run a copy of the Program. Ancillary propagation of a covered work
439 | occurring solely as a consequence of using peer-to-peer transmission
440 | to receive a copy likewise does not require acceptance. However,
441 | nothing other than this License grants you permission to propagate or
442 | modify any covered work. These actions infringe copyright if you do
443 | not accept this License. Therefore, by modifying or propagating a
444 | covered work, you indicate your acceptance of this License to do so.
445 |
446 | 10. Automatic Licensing of Downstream Recipients.
447 |
448 | Each time you convey a covered work, the recipient automatically
449 | receives a license from the original licensors, to run, modify and
450 | propagate that work, subject to this License. You are not responsible
451 | for enforcing compliance by third parties with this License.
452 |
453 | An "entity transaction" is a transaction transferring control of an
454 | organization, or substantially all assets of one, or subdividing an
455 | organization, or merging organizations. If propagation of a covered
456 | work results from an entity transaction, each party to that
457 | transaction who receives a copy of the work also receives whatever
458 | licenses to the work the party's predecessor in interest had or could
459 | give under the previous paragraph, plus a right to possession of the
460 | Corresponding Source of the work from the predecessor in interest, if
461 | the predecessor has it or can get it with reasonable efforts.
462 |
463 | You may not impose any further restrictions on the exercise of the
464 | rights granted or affirmed under this License. For example, you may
465 | not impose a license fee, royalty, or other charge for exercise of
466 | rights granted under this License, and you may not initiate litigation
467 | (including a cross-claim or counterclaim in a lawsuit) alleging that
468 | any patent claim is infringed by making, using, selling, offering for
469 | sale, or importing the Program or any portion of it.
470 |
471 | 11. Patents.
472 |
473 | A "contributor" is a copyright holder who authorizes use under this
474 | License of the Program or a work on which the Program is based. The
475 | work thus licensed is called the contributor's "contributor version".
476 |
477 | A contributor's "essential patent claims" are all patent claims
478 | owned or controlled by the contributor, whether already acquired or
479 | hereafter acquired, that would be infringed by some manner, permitted
480 | by this License, of making, using, or selling its contributor version,
481 | but do not include claims that would be infringed only as a
482 | consequence of further modification of the contributor version. For
483 | purposes of this definition, "control" includes the right to grant
484 | patent sublicenses in a manner consistent with the requirements of
485 | this License.
486 |
487 | Each contributor grants you a non-exclusive, worldwide, royalty-free
488 | patent license under the contributor's essential patent claims, to
489 | make, use, sell, offer for sale, import and otherwise run, modify and
490 | propagate the contents of its contributor version.
491 |
492 | In the following three paragraphs, a "patent license" is any express
493 | agreement or commitment, however denominated, not to enforce a patent
494 | (such as an express permission to practice a patent or covenant not to
495 | sue for patent infringement). To "grant" such a patent license to a
496 | party means to make such an agreement or commitment not to enforce a
497 | patent against the party.
498 |
499 | If you convey a covered work, knowingly relying on a patent license,
500 | and the Corresponding Source of the work is not available for anyone
501 | to copy, free of charge and under the terms of this License, through a
502 | publicly available network server or other readily accessible means,
503 | then you must either (1) cause the Corresponding Source to be so
504 | available, or (2) arrange to deprive yourself of the benefit of the
505 | patent license for this particular work, or (3) arrange, in a manner
506 | consistent with the requirements of this License, to extend the patent
507 | license to downstream recipients. "Knowingly relying" means you have
508 | actual knowledge that, but for the patent license, your conveying the
509 | covered work in a country, or your recipient's use of the covered work
510 | in a country, would infringe one or more identifiable patents in that
511 | country that you have reason to believe are valid.
512 |
513 | If, pursuant to or in connection with a single transaction or
514 | arrangement, you convey, or propagate by procuring conveyance of, a
515 | covered work, and grant a patent license to some of the parties
516 | receiving the covered work authorizing them to use, propagate, modify
517 | or convey a specific copy of the covered work, then the patent license
518 | you grant is automatically extended to all recipients of the covered
519 | work and works based on it.
520 |
521 | A patent license is "discriminatory" if it does not include within
522 | the scope of its coverage, prohibits the exercise of, or is
523 | conditioned on the non-exercise of one or more of the rights that are
524 | specifically granted under this License. You may not convey a covered
525 | work if you are a party to an arrangement with a third party that is
526 | in the business of distributing software, under which you make payment
527 | to the third party based on the extent of your activity of conveying
528 | the work, and under which the third party grants, to any of the
529 | parties who would receive the covered work from you, a discriminatory
530 | patent license (a) in connection with copies of the covered work
531 | conveyed by you (or copies made from those copies), or (b) primarily
532 | for and in connection with specific products or compilations that
533 | contain the covered work, unless you entered into that arrangement,
534 | or that patent license was granted, prior to 28 March 2007.
535 |
536 | Nothing in this License shall be construed as excluding or limiting
537 | any implied license or other defenses to infringement that may
538 | otherwise be available to you under applicable patent law.
539 |
540 | 12. No Surrender of Others' Freedom.
541 |
542 | If conditions are imposed on you (whether by court order, agreement or
543 | otherwise) that contradict the conditions of this License, they do not
544 | excuse you from the conditions of this License. If you cannot convey a
545 | covered work so as to satisfy simultaneously your obligations under this
546 | License and any other pertinent obligations, then as a consequence you may
547 | not convey it at all. For example, if you agree to terms that obligate you
548 | to collect a royalty for further conveying from those to whom you convey
549 | the Program, the only way you could satisfy both those terms and this
550 | License would be to refrain entirely from conveying the Program.
551 |
552 | 13. Use with the GNU Affero General Public License.
553 |
554 | Notwithstanding any other provision of this License, you have
555 | permission to link or combine any covered work with a work licensed
556 | under version 3 of the GNU Affero General Public License into a single
557 | combined work, and to convey the resulting work. The terms of this
558 | License will continue to apply to the part which is the covered work,
559 | but the special requirements of the GNU Affero General Public License,
560 | section 13, concerning interaction through a network will apply to the
561 | combination as such.
562 |
563 | 14. Revised Versions of this License.
564 |
565 | The Free Software Foundation may publish revised and/or new versions of
566 | the GNU General Public License from time to time. Such new versions will
567 | be similar in spirit to the present version, but may differ in detail to
568 | address new problems or concerns.
569 |
570 | Each version is given a distinguishing version number. If the
571 | Program specifies that a certain numbered version of the GNU General
572 | Public License "or any later version" applies to it, you have the
573 | option of following the terms and conditions either of that numbered
574 | version or of any later version published by the Free Software
575 | Foundation. If the Program does not specify a version number of the
576 | GNU General Public License, you may choose any version ever published
577 | by the Free Software Foundation.
578 |
579 | If the Program specifies that a proxy can decide which future
580 | versions of the GNU General Public License can be used, that proxy's
581 | public statement of acceptance of a version permanently authorizes you
582 | to choose that version for the Program.
583 |
584 | Later license versions may give you additional or different
585 | permissions. However, no additional obligations are imposed on any
586 | author or copyright holder as a result of your choosing to follow a
587 | later version.
588 |
589 | 15. Disclaimer of Warranty.
590 |
591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599 |
600 | 16. Limitation of Liability.
601 |
602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610 | SUCH DAMAGES.
611 |
612 | 17. Interpretation of Sections 15 and 16.
613 |
614 | If the disclaimer of warranty and limitation of liability provided
615 | above cannot be given local legal effect according to their terms,
616 | reviewing courts shall apply local law that most closely approximates
617 | an absolute waiver of all civil liability in connection with the
618 | Program, unless a warranty or assumption of liability accompanies a
619 | copy of the Program in return for a fee.
620 |
621 | END OF TERMS AND CONDITIONS
622 |
623 | How to Apply These Terms to Your New Programs
624 |
625 | If you develop a new program, and you want it to be of the greatest
626 | possible use to the public, the best way to achieve this is to make it
627 | free software which everyone can redistribute and change under these terms.
628 |
629 | To do so, attach the following notices to the program. It is safest
630 | to attach them to the start of each source file to most effectively
631 | state the exclusion of warranty; and each file should have at least
632 | the "copyright" line and a pointer to where the full notice is found.
633 |
634 |
635 | Copyright (C)
636 |
637 | This program is free software: you can redistribute it and/or modify
638 | it under the terms of the GNU General Public License as published by
639 | the Free Software Foundation, either version 3 of the License, or
640 | (at your option) any later version.
641 |
642 | This program is distributed in the hope that it will be useful,
643 | but WITHOUT ANY WARRANTY; without even the implied warranty of
644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645 | GNU General Public License for more details.
646 |
647 | You should have received a copy of the GNU General Public License
648 | along with this program. If not, see .
649 |
650 | Also add information on how to contact you by electronic and paper mail.
651 |
652 | If the program does terminal interaction, make it output a short
653 | notice like this when it starts in an interactive mode:
654 |
655 | Copyright (C)
656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 | This is free software, and you are welcome to redistribute it
658 | under certain conditions; type `show c' for details.
659 |
660 | The hypothetical commands `show w' and `show c' should show the appropriate
661 | parts of the General Public License. Of course, your program's commands
662 | might be different; for a GUI interface, you would use an "about box".
663 |
664 | You should also get your employer (if you work as a programmer) or school,
665 | if any, to sign a "copyright disclaimer" for the program, if necessary.
666 | For more information on this, and how to apply and follow the GNU GPL, see
667 | .
668 |
669 | The GNU General Public License does not permit incorporating your program
670 | into proprietary programs. If your program is a subroutine library, you
671 | may consider it more useful to permit linking proprietary applications with
672 | the library. If this is what you want to do, use the GNU Lesser General
673 | Public License instead of this License. But first, please read
674 | .
675 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | SELF = $(lastword $(MAKEFILE_LIST))
2 | ROOT_DIR = $(realpath $(dir $(SELF)))
3 |
4 | CONTAINER_CMD ?=
5 |
6 | ALT_BIN=$(CURDIR)/.bin
7 | SHELLCHECK=$(shell command -v shellcheck || echo $(ALT_BIN)/shellcheck)
8 | GITLINT=$(shell command -v gitlint || echo $(ALT_BIN)/gitlint)
9 | YAMLLINT_CMD=$(shell command -v yamllint || echo $(ALT_BIN)/yamllint)
10 | BUILD_IMAGE=$(ROOT_DIR)/hack/build-image --without-repo-bases
11 |
12 |
13 | SERVER_DIR:=images/server
14 | AD_SERVER_DIR:=images/ad-server
15 | CLIENT_DIR:=images/client
16 | TOOLBOX_DIR:=images/toolbox
17 |
18 | OS_NAME=
19 | SRC_OS_NAME=$(if $(OS_NAME),$(OS_NAME),fedora)
20 |
21 | SERVER_SRC_FILE=$(SERVER_DIR)/Containerfile.$(SRC_OS_NAME)
22 | SERVER_SOURCES=\
23 | $(SERVER_DIR)/smb.conf \
24 | $(SERVER_DIR)/install-packages.sh \
25 | $(SERVER_DIR)/install-sambacc.sh
26 | AD_SERVER_SRC_FILE=$(AD_SERVER_DIR)/Containerfile.$(SRC_OS_NAME)
27 | AD_SERVER_SOURCES=\
28 | $(AD_SERVER_DIR)/install-packages.sh \
29 | $(AD_SERVER_DIR)/install-sambacc.sh
30 | CLIENT_SRC_FILE=$(CLIENT_DIR)/Containerfile.$(SRC_OS_NAME)
31 | TOOLBOX_SRC_FILE=$(TOOLBOX_DIR)/Containerfile.$(SRC_OS_NAME)
32 |
33 | BUILDFILE_PREFIX=.build
34 | BUILDFILE_SERVER=$(shell $(call _BUILD_KP,server,default,--print-buildfile))
35 | BUILDFILE_NIGHTLY_SERVER=$(shell $(call _BUILD_KP,server,nightly,--print-buildfile))
36 | BUILDFILE_AD_SERVER=$(shell $(call _BUILD_KP,ad-server,default,--print-buildfile))
37 | BUILDFILE_NIGHTLY_AD_SERVER=$(shell $(call _BUILD_KP,ad-server,nightly,--print-buildfile))
38 | BUILDFILE_CLIENT=$(shell $(call _BUILD_KP,client,default,--print-buildfile))
39 | BUILDFILE_TOOLBOX=$(shell $(call _BUILD_KP,toolbox,default,--print-buildfile))
40 | DYN_BUILDFILE=$(shell $(call _BUILD_KP,$(KIND),$(if $(PACKAGE_SOURCE),$(PACKAGE_SOURCE),default),--print-buildfile) 2>/dev/null || echo invalid)
41 |
42 | REPO_BASE=quay.io/samba.org/
43 |
44 | _BUILD_KP=$(BUILD_IMAGE) $(if $(CONTAINER_CMD),--container-engine=$(CONTAINER_CMD)) $(BI_PREFIX_ARGS) --kind=$1 --package-source=$2 --distro-base=$(SRC_OS_NAME) --repo-base=$(REPO_BASE) $(if $(BUILD_ARCH),--arch=$(BUILD_ARCH)) $3
45 |
46 |
47 | arch_flag=$(strip $(if $(filter docker,$(CONTAINER_CMD)),\
48 | $(if $(filter-out $(HOST_ARCH),$(BUILD_ARCH)),\
49 | $(error Setting BUILD_ARCH != $(HOST_ARCH) not supported on docker)),\
50 | $(if $(BUILD_ARCH),--arch $(BUILD_ARCH))))
51 |
52 | build: build-server build-nightly-server build-ad-server build-client \
53 | build-toolbox
54 | .PHONY: build
55 |
56 |
57 | .PHONY: debug-vars
58 | debug-vars:
59 | @echo OS_NAME: $(OS_NAME)
60 | @echo TAG: $(TAG)
61 | @echo NIGHTLY_TAG: $(NIGHTLY_TAG)
62 | @echo SERVER_NAME: $(SERVER_NAME)
63 | @echo NIGHTLY_SERVER_NAME: $(NIGHTLY_SERVER_NAME)
64 | @echo AD_SERVER_NAME: $(AD_SERVER_NAME)
65 |
66 | @echo BUILDFILE_SERVER: $(BUILDFILE_SERVER)
67 | @echo BUILDFILE_AD_SERVER: $(BUILDFILE_AD_SERVER)
68 | @echo BUILDFILE_NIGHTLY_AD_SERVER: $(BUILDFILE_iNIGHTLY_AD_SERVER)
69 | @echo BUILDFILE_NIGHTLY_SERVER: $(BUILDFILE_NIGHTLY_SERVER)
70 | @echo BUILDFILE_CLIENT: $(BUILDFILE_CLIENT)
71 | @echo BUILDFILE_TOOLBOX: $(BUILDFILE_TOOLBOX)
72 |
73 | @echo SERVER_SRC_FILE: $(SERVER_SRC_FILE)
74 | @echo AD_SERVER_SRC_FILE: $(AD_SERVER_SRC_FILE)
75 | @echo CLIENT_SERVER_SRC_FILE: $(CLIENT_SRC_FILE)
76 | @echo TOOLBOX_SRC_FILE: $(TOOLBOX_SRC_FILE)
77 |
78 |
79 | ### Image Build and Push Rules ###
80 |
81 | build-image: $(DYN_BUILDFILE)
82 | .PHONY: build-image
83 |
84 | $(DYN_BUILDFILE):
85 | @[ "$(KIND)" ] || (echo "KIND must be specfied"; exit 1)
86 | $(call _BUILD_KP,$(KIND),$(if $(PACKAGE_SOURCE),$(PACKAGE_SOURCE),default)) $(EXTRA_BUILD_ARGS)
87 |
88 | build-server: $(BUILDFILE_SERVER)
89 | .PHONY: build-server
90 | $(BUILDFILE_SERVER): Makefile $(SERVER_SRC_FILE) $(SERVER_SOURCES)
91 | $(call _BUILD_KP,server,default) $(EXTRA_BUILD_ARGS)
92 |
93 | push-server: build-server
94 | $(call _BUILD_KP,server,default,--push)
95 | .PHONY: push-server
96 |
97 | build-nightly-server: $(BUILDFILE_NIGHTLY_SERVER)
98 | .PHONY: build-nightly-server
99 | $(BUILDFILE_NIGHTLY_SERVER): Makefile $(SERVER_SRC_FILE) $(SERVER_SOURCES)
100 | $(call _BUILD_KP,server,nightly) $(EXTRA_BUILD_ARGS)
101 |
102 | push-nightly-server: build-nightly-server
103 | $(call _BUILD_KP,server,nightly,--push)
104 | .PHONY: push-nightly-server
105 |
106 | build-ad-server: $(BUILDFILE_AD_SERVER)
107 | .PHONY: build-ad-server
108 | $(BUILDFILE_AD_SERVER): Makefile $(AD_SERVER_SRC_FILE) $(AD_SERVER_SOURCES)
109 | $(call _BUILD_KP,ad-server,default) $(EXTRA_BUILD_ARGS)
110 |
111 | push-ad-server: build-ad-server
112 | $(call _BUILD_KP,ad-server,default,--push)
113 | .PHONY: push-ad-server
114 |
115 | build-nightly-ad-server: $(BUILDFILE_NIGHTLY_AD_SERVER)
116 | .PHONY: build-nightly-ad-server
117 | $(BUILDFILE_NIGHTLY_AD_SERVER): Makefile $(AD_SERVER_SRC_FILE) $(AD_SERVER_SOURCES)
118 | $(call _BUILD_KP,ad-server,nightly) $(EXTRA_BUILD_ARGS)
119 |
120 | push-nightly-ad-server: build-nightly-ad-server
121 | $(call _BUILD_KP,ad-server,nightly,--push)
122 | .PHONY: push-nightly-ad-server
123 |
124 | build-client: $(BUILDFILE_CLIENT)
125 | .PHONY: build-client
126 | $(BUILDFILE_CLIENT): Makefile $(CLIENT_SRC_FILE)
127 | $(call _BUILD_KP,client,default) $(EXTRA_BUILD_ARGS)
128 |
129 | push-client: build-client
130 | $(call _BUILD_KP,client,default,--push)
131 | .PHONY: push-client
132 |
133 | build-toolbox: $(BUILDFILE_TOOLBOX)
134 | .PHONY: build-toolbox
135 | $(BUILDFILE_TOOLBOX): Makefile $(TOOLBOX_SRC_FILE)
136 | $(call _BUILD_KP,toolbox,default) $(EXTRA_BUILD_ARGS)
137 |
138 | push-toolbox: build-toolbox
139 | $(call _BUILD_KP,toolbox,default,--push)
140 | .PHONY: push-toolbox
141 |
142 |
143 | ### Test Rules: executes test scripts ###
144 |
145 | test: test-server test-nightly-server
146 | .PHONY: test
147 |
148 | test-server: build-server
149 | CONTAINER_CMD=$(CONTAINER_CMD) \
150 | LOCAL_TAG=$(shell cat $(BUILDFILE_SERVER) |cut -d' ' -f2) \
151 | tests/test-samba-container.sh
152 | .PHONY: test-server
153 |
154 | test-nightly-server: $(BUILDFILE_NIGHTLY_SERVER)
155 | CONTAINER_CMD=$(CONTAINER_CMD) \
156 | LOCAL_TAG=$(shell cat $(BUILDFILE_NIGHTLY_SERVER) |cut -d' ' -f2) \
157 | tests/test-samba-container.sh
158 | .PHONY: test-nightly-server
159 |
160 |
161 | ### Check Rules: static checks, quality tools ###
162 |
163 | check: check-shell-scripts check-yaml
164 | .PHONY: check
165 | # rule requires shellcheck and find to run
166 | check-shell-scripts: $(filter $(ALT_BIN)%,$(SHELLCHECK))
167 | $(SHELLCHECK) -P tests/ -eSC2181 -fgcc $$(find $(ROOT_DIR) -name "*.sh")
168 | .PHONY: check-shell-scripts
169 |
170 |
171 | check-yaml: $(filter $(ALT_BIN)%,$(YAMLLINT_CMD))
172 | $(YAMLLINT_CMD) -c $(CURDIR)/.yamllint.yaml $(CURDIR)
173 | .PHONY: check-yaml
174 |
175 | # not included in check to not disrupt wip branches
176 | check-gitlint: $(filter $(ALT_BIN)%,$(GITLINT))
177 | $(GITLINT) -C .gitlint --commits origin/master.. lint
178 | .PHONY: check-gitlint
179 |
180 |
181 | ### Misc. Rules ###
182 |
183 | $(ALT_BIN)/%:
184 | $(CURDIR)/hack/install-tools.sh --$* $(ALT_BIN)
185 |
186 | clean: clean-buildfiles clean-altbin
187 | .PHONY: clean
188 |
189 | clean-buildfiles:
190 | $(RM) $(BUILDFILE_PREFIX)*
191 | .PHONY: clean-buildfiles
192 |
193 | clean-altbin:
194 | $(RM) -r $(ALT_BIN)
195 | .PHONY: clean-altbin
196 |
--------------------------------------------------------------------------------
/Makefile.opensuse:
--------------------------------------------------------------------------------
1 | include Makefile
2 |
3 | OS_NAME=opensuse
4 | SERVER_SOURCES:=$(SERVER_DIR)/smb.conf
5 | REPO_BASE=registry.opensuse.org/opensuse/
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # samba-container
2 |
3 | Container images for [Samba](https://samba.org) services.
4 |
5 | ### Our images:
6 | * Are [OCI](https://opencontainers.org/) formatted container images
7 | * Provide application-like high-level entrypoint scripts
8 | * Are available as pre-built stable and "nightly" [variants](#image-variants)
9 | * Are used by the [samba-operator](https://github.com/samba-in-kubernetes/samba-operator) for Kubernetes
10 | * Don't require Kubernetes
11 | * Are [available at quay.io](https://quay.io/organization/samba.org)
12 | * Are used by the [ceph project](https://github.com/ceph/ceph) to provide SMB services on CephFS
13 |
14 | ### Image Types:
15 |
16 | |Image Type | Repository | Custom Entrypoint | Features |
17 | |-------------|------------|-------------------|----------|
18 | |[Samba Server](#samba-server) | [quay.io](https://quay.io/repository/samba.org/samba-server) | Yes | Standalone file server, Domain member file server |
19 | |[AD Domain Controller](#ad-dc) | [quay.io](https://quay.io/repository/samba.org/samba-ad-server) | Yes | Active Directory Domain Controller |
20 | |[Client](#client) | [quay.io](https://quay.io/repository/samba.org/samba-client) | No | Basic Userspace Client Utilities |
21 | |[Toolbox](#toolbox) | [quay.io](https://quay.io/repository/samba.org/samba-toolbox) | No | Extra debugging and testing tools |
22 |
23 |
24 | ## Samba Server
25 |
26 | The Samba server image defaults to the `samba-container` entrypoint.
27 |
28 | In the default configuration, the server container image exports one share,
29 | named "share", with the path `/share` which is expected to be a volume provided
30 | by the host. A default user, named "sambauser" is predefined with a password of
31 | "samba". This simple mode of operation is great for quick demos. Example:
32 |
33 | ```sh
34 | podman run --name samba --publish 10445:445 --volume=/path/on/host/to/share:/share:Z --rm quay.io/samba.org/samba-server:latest
35 | ```
36 | > **Note**
37 | > The port mapping option (`--publish`) is only needed when running
38 | > as non-root, e.g. for testing purposes.
39 |
40 | The `samba-container` entrypoint can perform many functions and is
41 | designed to make the container image act like a cohesive application.
42 | It can automate the management of Samba as well as the container environment
43 | to make them work together. This tool is provided by the
44 | [sambacc project](https://github.com/samba-in-kubernetes/sambacc).
45 |
46 | ```sh
47 | # print help
48 | podman run --rm quay.io/samba.org/samba-server:latest --help
49 | # print help for the run subcommand
50 | podman run --rm quay.io/samba.org/samba-server:latest run --help
51 | ```
52 |
53 | ### Changing the configuration
54 |
55 | The behavior of the container can be changed by invoking it with specific
56 | arguments for the `samba-container` script and/or setting environment
57 | variables.
58 |
59 | You can include a custom configuration via the following method:
60 | ```
61 | $EDITOR /path/to/config/config.json
62 | podman run --name samba --publish 10445:445 --volume=/path/on/host/to/share:/share:Z --volume=/path/to/config:/etc/samba-container -e SAMBACC_CONFIG=/etc/samba-container/config.json -e SAMBA_CONTAINER_ID=myid --rm quay.io/samba.org/samba-server:latest
63 | ```
64 |
65 |
66 |
67 | ## AD DC
68 |
69 | The AD DC image defaults to the `samba-dc-container` entrypoint.
70 |
71 | In the default configuration, the AD DC container image automatically
72 | provisions and serves a simple stock domain `DOMAIN1.SINK.TEST`.
73 | Because the Samba AD DC uses certain file system xattrs this container
74 | must currently be run with privileges. Example:
75 |
76 | ```sh
77 | podman run --rm --privileged quay.io/samba.org/samba-ad-server:latest
78 | ```
79 |
80 | The `samba-dc-container` entrypoint can perform multiple functions as is
81 | designed to make the container image act like a cohesive application.
82 | It helps automate the provisioning of and/or connection to a domain.
83 | This tool is provided by the
84 | [sambacc project](https://github.com/samba-in-kubernetes/sambacc).
85 |
86 |
87 |
88 | ## Client
89 |
90 | The project provides a simple samba client container image that can be
91 | useful for testing. One does not need to install the user space samba client
92 | locally but rather use the container image. It can run the samba client
93 | interactively when a TTY is available and can also be scripted for
94 | automated testing purposes. Example:
95 |
96 | ```sh
97 | podman run --rm -it quay.io/samba.org/samba-client:latest
98 | [root@dc0419d28c4e /]# smbclient -U 'sambauser' //foo.example.org/share
99 | ```
100 |
101 | ## Toolbox
102 |
103 | The project provides a container image container containing the samba test
104 | suite program
105 | ([smbtorture](https://wiki.samba.org/index.php/Writing_Torture_Tests)) as well
106 | as the user space client. This can be used for debugging and testing purposes.
107 | Example:
108 |
109 | ```sh
110 | podman run --rm -it quay.io/samba.org/samba-toolbox:latest
111 | [root@dc0419d28c4e /]# smbtorture --help
112 | ```
113 | ## Image Variants
114 |
115 | The server images come in two variants: stable and nightly. The
116 | stable variant is what you get with the "latest" tag and includes
117 | Samba packages from the Linux distribution used in our base images.
118 | The "nightly" images are based on Samba RPM packages created by the
119 | [samba-build project](https://github.com/samba-in-kubernetes/samba-build)
120 | which builds and tests Samba builds before release. The nightly images
121 | are tagged with "nightly" instead of "latest".
122 |
123 | ## Developers
124 |
125 | ### Building the containers
126 |
127 | ```sh
128 | # Build Everything
129 | make build
130 | ```
131 |
132 | Each container image type has a build target:
133 | ```sh
134 | # Build the server image
135 | make build-server
136 | # Build the server with "nightly" samba
137 | make build-nightly-server
138 | # Build the client
139 | make build-client
140 | # And so on...
141 | ```
142 |
143 | There are matching `push-*` rules that default to pushing the images to the
144 | "official" quay.io repositories. These rules can be executed by the appropriate
145 | github actions or by project maintainers.
146 |
--------------------------------------------------------------------------------
/docs/development.md:
--------------------------------------------------------------------------------
1 | # Development Guide
2 |
3 |
4 | ## Building samba containers with unreleased sambacc code
5 |
6 | Changes to `sambacc` are validated by a suite of unit tests to ensure a minium
7 | level of quality, but that is often not enough to fully validate a
8 | work-in-progress feature, especially one that needs to interact with components
9 | from Samba in complex ways. One may want to try out an unreleased branch of
10 | sambacc code as part of a samba container image. Two methods of doing this are:
11 | * Build sambacc RPMs and put them in a yum/dnf repo
12 | * Customize the Containerfile to use a sambacc build stage
13 |
14 | Both methods make use of the sambacc build image. The files needed to build the
15 | image are part of the [sambacc
16 | repo](https://github.com/samba-in-kubernetes/sambacc) and already-created
17 | images are available at quay.io:
18 | [quay.io/samba.org/sambacc](https://quay.io/repository/samba.org/sambacc).
19 |
20 | ### RPMs
21 |
22 | One can build rpms using the sambacc test-and-build container.
23 | In this example we assume you have a git checkout of sambacc as the
24 | local path. Create a new directory to store build artifacts in:
25 | ```
26 | mkdir -p _build
27 | ```
28 |
29 | Then run the container command like follows:
30 | ```
31 | podman run -v $PWD:/var/tmp/build/sambacc -v $PWD/_build:/srv/dist/:z -e SAMBACC_DISTNAME=dev quay.io/samba.org/sambacc:latest
32 | ```
33 |
34 | Breaking it down, we're mounting the current dir at `/var/tmp/build/sambacc`,
35 | mounting the build dir at `/srv/dist` and telling the build container
36 | to store artifacts under the "distribution name" of `dev`. This should
37 | result in rpms, whl files and other artifacts in `_build/dev`. You can
38 | name your "dist" anything.
39 |
40 | Now you have a directory with rpms in it you can run `createrepo` on them
41 | and/or publish them on the web. Managing the rpms is an exercise left to the
42 | reader.
43 |
44 | To get them into a samba-container image, like the samba-server or
45 | samba-ad-server image, we need to get or create a repo file pointing to the
46 | repo hosting your rpms. The repo file must be saved into the build container at
47 | a path named like `/tmp/sambacc-dist-latest/sambacc*.repo`, so that the
48 | `install-sambacc.sh` script that is run during the image build can find it.
49 |
50 | Typically this means modifying the Containerfile. Here's an example modification
51 | to the `images/server/Containerfile.fedora` file:
52 | ```
53 | COPY .common/install-sambacc-common.sh /usr/local/bin/install-sambacc-common.sh
54 | COPY install-sambacc.sh /usr/local/bin/install-sambacc.sh
55 | # Add an ADD command to copy our repofile into the build
56 | ADD https://my-cool-repo.example.org/mystuff/sambacc.repo /tmp/sambacc-dist-latest
57 | RUN /usr/local/bin/install-sambacc.sh \
58 | "/tmp/sambacc-dist-latest" \
59 | "${SAMBACC_VERSION_SUFFIX}"
60 | ```
61 |
62 | Now build the image the usual way. It should contain your specific sambacc rpms.
63 |
64 |
65 | ### Build Stage
66 |
67 | Rather than building the sambacc RPMs and creating a repo for them, the build
68 | steps can be combined by modifying the `Containerfile`s to add a specific build
69 | stage. First add the build stage to the top of the Containerfile:
70 | ```
71 | # --- new stuff ---
72 | FROM quay.io/samba.org/sambacc:latest AS sccbuilder
73 | ARG SAMBACC_VER=my-cool-branch
74 | ARG SAMBACC_REPO=https://github.com/example-user/sambacc
75 | RUN SAMBACC_DISTNAME=latest \
76 | /usr/local/bin/build.sh ${SAMBACC_VER} ${SAMBACC_REPO}
77 | # create yum/dnf repo for temp. packages (file uses paths in dest container)
78 | RUN dnf install -y /usr/bin/createrepo_c \
79 | && createrepo_c /srv/dist/latest \
80 | && echo -e '[sambacc]\nbaseurl=file:///tmp/sambacc-dist-latest\nenabled=1\ngpgcheck=0\n' > /srv/dist/latest/sambacc.repo
81 | # --- end new stuff ---
82 |
83 | FROM registry.fedoraproject.org/fedora:38
84 | ```
85 |
86 | The variables `SAMBACC_VER` and `SAMBACC_REPO` can be overridden on the command
87 | line so you don't have to keep modifying the Containerfile to set them, unless
88 | you want to. `SAMBACC_VER` takes a git ref and that can be a barnch name or a
89 | commit hash. Using a commit hash can be handy to avoid caching issues.
90 |
91 | Next, we need to make a modification to the RUN command that executes
92 | `install-sambacc.sh`:
93 | ```
94 | # add the --mount argument to map the dist dir of the sccbuilder
95 | # container to the /tmp/sambacc-dist-latest dir in the current build
96 | # container.
97 | RUN --mount=type=bind,from=sccbuilder,source=/srv/dist/latest,destination=/tmp/sambacc-dist-latest bash -x /usr/local/bin/install-sambacc.sh \
98 | "/tmp/sambacc-dist-latest" \
99 | "${SAMBACC_VERSION_SUFFIX}"
100 | ```
101 |
102 | Very old versions of podman and docker may not support `--mount`. As an
103 | alternative, you can add a `COPY` command to copy the rpms from one container
104 | to the other.
105 |
--------------------------------------------------------------------------------
/docs/release-process.md:
--------------------------------------------------------------------------------
1 | # samba-container Release Process
2 |
3 | ## Preparation
4 |
5 | The samba-container project has a dedicated branch, called `release`, for
6 | release versions. This is done to update certain files which control
7 | dependencies and versioning. Tags are applied directly to this branch
8 | and only this branch.
9 |
10 |
11 | ### Tagging
12 |
13 | Prior to tagging, check out the `release` branch and merge `master` into it.
14 | Example:
15 |
16 | ```
17 | git checkout master
18 | git pull --ff-only
19 | git checkout release
20 | git pull --ff-only
21 | git merge master
22 | # resolve any conflicts
23 | ```
24 |
25 | Now we need to "pin" the appropriate versions of samba and sambacc so that only
26 | explicitly specified versions of those packages will be included on release
27 | branch builds. Set `SAMBA_VERSION_SUFFIX` and `SAMBACC_VERSION_SUFFIX` in the
28 | container files in `images/`. Currently, only the fedora based images are
29 | included in the release. Thus you must set those variables in the fedora
30 | container files for server and ad-server. Commit these changes to the `release`
31 | branch. Currently, there is no PR process for release branches so make the
32 | commits directly to the `release` branch and push them. This implies that
33 | releases must be managed by users with the rights to push directly to the
34 | project's release branch.
35 |
36 | At this point, an optional but recommended step is to do a test build before
37 | tagging. Run `make build-ad-server build-server build-client build-toolbox`.
38 | You do not need to build the nightly package variants or other OS bases as
39 | these are not part of the released images. You can push the images to quay.io
40 | under your own repos to perform a early security scan as well.
41 |
42 | If you are happy with the content of the `release` branch, tag it. Example:
43 |
44 | ```
45 | git checkout release
46 | git tag -a -m 'Release v0.3' v0.3
47 | ```
48 |
49 | This creates an annotated tag. Release tags must be annotated tags.
50 |
51 | ### Build
52 |
53 | Using the tagged `release` branch, the container images for release will be
54 | built. It is very important to ensure that base images are up-to-date.
55 | It is very important to ensure that you perform the next set of steps with
56 | clean new builds and do not use cached images. To accomplish both tasks it
57 | is recommended to purge your local container engine of cached images
58 | (Example: `podman image rm --all`). You should have no images named like
59 | `quay.io/samba.org` in your local cache.
60 |
61 | Build the images from scratch. Example:
62 | ```
63 | make build-ad-server build-server build-client build-toolbox
64 | ```
65 |
66 | For each image that was just built, apply a temporary pre-release tag
67 | to it. Example:
68 | ```
69 | for img_name in ad-server server client toolbox ; do
70 | podman tag quay.io/samba.org/samba-${img_name}:{latest,v0.3pre1}
71 | done
72 | ```
73 |
74 | Log into quay.io. Push the images to quay.io using the temporary tag. Example:
75 | ```
76 | for img_name in ad-server server client toolbox ; do
77 | podman push quay.io/samba.org/samba-${img_name}:v0.3pre1
78 | done
79 | ```
80 |
81 | Wait for the security scan to complete. There shouldn't be any issues if you
82 | properly updated the base images before building. If there are issues and you
83 | are sure you used the newest base images, check the base images on quay.io and
84 | make sure that the number of issues are identical. The security scan can take
85 | some time, while it runs you may want to do other things.
86 |
87 |
88 | ## GitHub Release
89 |
90 | When you are satisfied that the tagged version is suitable for release, you
91 | can push the tag to the public repo:
92 | ```
93 | git push --follow-tags
94 | ```
95 |
96 | Draft a new set of release notes. Select the recently pushed tag. Start with
97 | the auto-generated release notes from GitHub (activate the `Generate release
98 | notes` button/link). Add an introductory section (see previous notes for an
99 | example). Add a "Highlights" section if there are any notable features or fixes
100 | in the release. The Highlights section can be skipped if the content of the
101 | release is unremarkable (e.g. few changes occurred since the previous release).
102 |
103 | Because this is a container based release we do not provide any build artifacts
104 | on GitHub (beyond the sources automatically provided there). Instead we add
105 | a Downloads section that notes the exact tags and digests that the images can
106 | be found at on quay.io.
107 |
108 | The downloads section can be generated using the shell script
109 | https://github.com/samba-in-kubernetes/samba-container/blob/master/hack/install-tools.sh in this repository.
110 |
111 | It needs to be invoked with the release tag as the only argument. E. G. :
112 |
113 | ```console
114 |
115 | $ ./hack/release-gen-download-section.sh v0.3
116 | ```
117 |
118 |
119 | It is important that the digest is fetched from qauy.io after it has been
120 | pushed. Do not use any local digest hashes. You may want to double check the
121 | values produced by the script with those in the quay.io UI. Click on the
122 | SHA256 link and then compare the full manifest hash using the UI widget that
123 | appears.
124 |
125 | Perform a final round of reviews, as needed, for the release notes and then
126 | publish the release.
127 |
128 | Once the release notes are drafted and then either immediately before or after
129 | publishing them, use the quay.io UI to copy each pre-release tag to the "latest"
130 | tag and a final "vX.Y" tag. Delete the temporary pre-release tags using the
131 | quay.io UI as they are no longer needed.
132 |
--------------------------------------------------------------------------------
/docs/server.md:
--------------------------------------------------------------------------------
1 |
2 | # Using the Samba Server Image
3 |
4 | The container image for the Samba server defaults to the `samba-container`
5 | entrypoint. If invoked without arguments, the container image defaults to the
6 | arguments `run smbd`. You can bypass the `samba-container` entrypoint to run
7 | any of the binaries in the container if you wish. However, the document that
8 | follows assumes the use of the `samba-container` entrypoint.
9 |
10 |
11 | The `samba-container` entrypoint is designed to make the container image
12 | feel like a cohesive application rather than just a collection of parts.
13 | However, there are times that a low-level understanding of Samba and its
14 | parts are useful and this document will assume some familiarity
15 | with Samba. If you're reading this document and find sections that you feel
16 | need better explanation, please file an issue in our project.
17 |
18 | The `samba-container` tool has a built in help system. Pass --help to
19 | the command or after any subcommand (example: `run --help`) to
20 | display the internal help text. The built-in help text will be the
21 | most up to date reflecting the version in use, but likely terser than
22 | this document.
23 |
24 |
25 | ## General Configuration
26 |
27 | There are two critical values that control the samba-container tool. First,
28 | the command line option `--config` and the equivalent environment variable
29 | `SAMBACC_CONFIG` specifies a path (or colon separated paths) to a JSON based
30 | configuration file. The JSON based configuration can contain multiple
31 | "instances" and so the `--identity` option and/or the equivalent environment
32 | variable `SAMBA_CONTAINER_ID` provides a name to identify which configuration
33 | to use.
34 |
35 | The complete [documentation for the JSON configuration
36 | file](https://github.com/samba-in-kubernetes/sambacc/blob/master/docs/configuration.md)
37 | can be found in the sambacc project. A default configuration file is included
38 | as part of container image which specifies a simple demonstration share.
39 |
40 | Other global CLI options include:
41 | * `--username` For any command that may require a username, specify a user name.
42 | * `--password` For any command that may require a password, specify a password.
43 | * `--join-marker` Specify the location of a file that indicates a domain join
44 | has already been performed.
45 | * `--samba-debug-level` Specify an integer, from 0 to 10, that will be
46 | passed to Samba commands for debugging purposes.
47 | * `--skip-if-file` Specify the location of a file. If the file exists the
48 | command will be skipped (it will not be further executed).
49 |
50 |
51 | ## Running Servers
52 |
53 | The `run` subcommand starts Samba servers. Valid Samba servers include: `smbd`,
54 | `winbindd`, and `ctdbd`. For example to start smbd explicitly you can run
55 | `podman run --rm --name smbd quay.io/samba.org/samba-server:latest run smbd` or
56 | to start winbind execute `podman run --rm --name winbindd
57 | quay.io/samba.org/samba-server:latest run winbindd`. The servers run in the foreground as is typical for application containers.
58 |
59 | The option `--setup` may be specified one or more times. The values
60 | to the setup option tell the tool what setup steps to perform before
61 | starting up the server. This allows one to have more precise control
62 | over the container configuration and environment.
63 |
64 | Valid values include:
65 | * `init-all` - A special value that tells the tool to perform all known
66 | and valid setup steps.
67 | * `config` - Import sambacc configuration into Samba's configuration registry.
68 | * `users` - Import users into the systems /etc files
69 | * `users_passdb` - Import users into Samba's password db
70 | * `nsswitch` - Configure the container's `/etc/nsswitch` file
71 | * `share_paths` - Create and/or update Share paths and their permissions
72 |
73 | Here's an example of running an smbd server with a specific set of setup steps.
74 | One might want to do something like this if Samba's db files are persisted
75 | across restarts of the container. Example:
76 | `podman run --rm --name -v /var/lib/sambactr/var:/var/lib/samba smbd quay.io/samba.org/samba-server:latest run --setup=users --setup=nsswitch --setup=share_paths smbd`
77 |
78 |
79 | ## Environment & System Control
80 |
81 | The `samba-container` tool provides a number of subcommands that help
82 | configure the general environment that the Samba servers run in.
83 | This includes the ephemeral system level files, Samba configuration,
84 | and the data volume(s) that contain the shares.
85 |
86 | ### init
87 |
88 | The `init` command works much like the `--setup=init-all` setup step,
89 | only it exits after completion rather than trying to start a server.
90 | This command can be used to prepare a directory (or directories) that
91 | will be later be mapped into a running server container.
92 |
93 | ### import
94 |
95 | The `import` command will import configuration parameters from the sambacc
96 | config to samba's registry-based configuration database.
97 |
98 | ### ensure-share-paths
99 |
100 | The `ensure-share-paths` command will examine the configured shares and check
101 | if the share paths already exist. If not, the command will create them.
102 | Depending on the configuration it may also check and/or update the permissions
103 | on the share directories as well.
104 |
105 | ### import-users
106 |
107 | The `import-users` command will take the users and groups listed in the
108 | JSON based configuration file and translate them to the "system files"
109 | `/etc/passwd` and `/etc/group` of the container. This allows the use of
110 | local (non-domain) user logons. Note that these files
111 | are part of the ephemeral base image of the container and thus largely
112 | exists to reflect the equivalent functionality in `--setup=users`.
113 |
114 | ### print-config
115 |
116 | The `print-config` subcommand translates the JSON based configuration
117 | into an smb.conf-style output of Samba specific parameters. It does not
118 | change any configuration. It is most useful for debugging what configuration
119 | values will be set by a sub-command like `import`.
120 |
121 |
122 | For example, the default configuration of the server image:
123 | ```
124 | podman run --rm quay.io/samba.org/samba-server:latest print-config
125 | [global]
126 | security = user
127 | server min protocol = SMB2
128 | load printers = no
129 | printing = bsd
130 | printcap name = /dev/null
131 | disable spoolss = yes
132 | guest ok = no
133 | netbios name = SAMBA
134 |
135 | [share]
136 | path = /share
137 | valid users = sambauser, otheruser
138 | ```
139 |
140 |
141 | ## Domain Join
142 |
143 |
144 | The `samba-container` tool provides mechanisms that wrap Samba's domain
145 | join functionality. The commands are only useful when the Samba state
146 | directory `/var/lib/samba` is persisted.
147 |
148 | The `join` command attempts an immediate domain join. The inputs for
149 | domain credentials is outlined below. The `must-join` command will
150 | check for available credentials but is allowed to wait until
151 | credentials become available or another process performs the join.
152 | The `must-join` subcommand is mostly useful when building a declarative
153 | set of container commands and the pipeline should block until
154 | the "instance" has been joined to a domain.
155 |
156 | Both `join` and `must-join` support the options:
157 | * `--insecure` Enable sourcing a domain username/password from CLI arguments
158 | or environment variables
159 | * `--no-insecure` Disable sourcing a domain username/password from CLI
160 | arguments or environment variables
161 | * `--files` Enable sourcing a domain username/password from dedicated
162 | JSON files.
163 | * `--no-files` Disable sourcing a domain username/password from dedicated
164 | JSON files.
165 | * `--join-file` (`-j`) Specify the path to a JSON file containing a
166 | domain user's name and password. May be specified more than once.
167 |
168 |
169 | The `join` command also supports the options:
170 | * `--interactive` Enable interactive password prompt
171 | * `--no-interactive` Disable interactive password prompt
172 |
173 | The `must-join` command also supports the options:
174 | * `--wait` Do not exit until a join to the domain has been completed
175 | * `--no-wait` Exit even if a join has not been completed
176 |
177 | For fully automated deployment of samba-server container with domain
178 | access the best currently supported method is to combine the `must-join`
179 | command with a secret store. For example, podman supports the `podman create
180 | secret` command and the `--secret` option to the run command. This
181 | allows one to store a JSON file with the required username and password.
182 | Other systems such as Kubernetes can combine the Secret resource with
183 | a store such as HashiCorp Vault.
184 |
185 | However, if one is not comfortable with storing a domain user with a password a
186 | partially automated deployment with a domain join can still be performed. One
187 | option is a workflow similar to a traditional Samba server on a physical or VM
188 | host. Execute containers with the `init` and then `join` subcommands (with tty
189 | support enabled (podman -it) and ensure that the Samba state directory(s) are
190 | persisted before starting the servers. Another option is to let the
191 | `must-join` command run and while it is in its wait loop, exec into the
192 | container and run the `join`.
193 |
194 | Example:
195 | ```
196 | $ podman run -d --rm --name joiner -v /var/lib/sambactr/var:/var/lib/samba quay.io/samba.org/samba-server:latest must-join --wait
197 | $ podman exec --rm -it joiner
198 | # samba-container join --interactive
199 | ```
200 |
201 |
202 | # Dynamic Configuration
203 |
204 | The `update-config` command can be used to support more dynamic configuration
205 | in the case of a JSON configuration shared between the host and the container.
206 | When the JSON configuration file is updated a container running `update-config`
207 | in concert with an smbd (and optional winbind) container can automatically
208 | update the configuration of the running Samba server.
209 |
210 | The `update-config` command can be launched in a container that shares the
211 | same pid namespace and persisted directories as the smbd/winbind containers.
212 | It will automatically check the Samba configuration matches the JSON
213 | configuration and update it if needed. It will also create any missing
214 | shares and update permissions like the `ensure-share-paths` subcommand.
215 |
216 | Passing the `--watch` option to `update-config` makes the process
217 | continue running rather than exiting after the initial updates. Periodically,
218 | this command will check for changes and repeat the configuration update
219 | action.
220 |
221 |
222 | # Combining Containers
223 |
224 | In a typical hardware or VM based Samba installation that is a domain member
225 | multiple server processes act in concert. The smbd process handles the SMB
226 | protocol while winbindd takes care of integration with Active Directory.
227 | Accomplishing this with the samba server containers is possible by starting
228 | multiple containers with namespaces shared between them.
229 |
230 | Namespaces that must be shared:
231 | * PID Namespace
232 | * UTS Namespace
233 | * Network namespace
234 |
235 | In addition you should share the directories/volumes that contain the samba
236 | state files (samba's TDB databases). You do not have to expose the volumes or
237 | directories containing shares to the winbind pod.
238 |
239 | An example script setting this up using [podman CLI commands is available in
240 | our examples
241 | directory](https://github.com/samba-in-kubernetes/samba-container/blob/master/examples/podman/smb-wb-pod.sh).
242 | Another example using [kubernetes
243 | YAML](https://github.com/samba-in-kubernetes/samba-container/blob/master/examples/kubernetes/sambadmpod.yml)
244 | is also available.
245 |
246 |
247 |
254 |
--------------------------------------------------------------------------------
/examples/kubernetes/README.md:
--------------------------------------------------------------------------------
1 | Examples for deploying samba as an application on top of a pvc.
2 |
--------------------------------------------------------------------------------
/examples/kubernetes/pv.yml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: PersistentVolume
3 | metadata:
4 | name: mypv
5 | labels:
6 | type: local
7 | spec:
8 | storageClassName: manual
9 | capacity:
10 | storage: 1Gi
11 | accessModes:
12 | - ReadWriteOnce
13 | hostPath:
14 | path: "/mnt/pv"
15 |
--------------------------------------------------------------------------------
/examples/kubernetes/pvc.yml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: PersistentVolumeClaim
3 | metadata:
4 | name: mypvc
5 | spec:
6 | storageClassName: manual
7 | accessModes:
8 | - ReadWriteOnce
9 | resources:
10 | requests:
11 | storage: 1Gi
12 |
--------------------------------------------------------------------------------
/examples/kubernetes/samba-ad-server-deployment.yml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: samba-ad-server
5 | labels:
6 | app: samba-ad
7 | spec:
8 | replicas: 1
9 | selector:
10 | matchLabels:
11 | app: samba-ad
12 | template:
13 | metadata:
14 | labels:
15 | app: samba-ad
16 | spec:
17 | containers:
18 | - name: samba-ad
19 | image: quay.io/samba.org/samba-ad-server:latest
20 | securityContext:
21 | capabilities:
22 | add: ["SYS_ADMIN"]
23 | ports:
24 | # https://wiki.samba.org/index.php/Samba_AD_DC_Port_Usage
25 | - containerPort: 53
26 | name: dns
27 | - containerPort: 135
28 | name: epm
29 | protocol: TCP
30 | - containerPort: 137
31 | name: netbios-ns
32 | protocol: UDP
33 | - containerPort: 138
34 | name: netbios-dgram
35 | protocol: UDP
36 | - containerPort: 139
37 | name: netbios-session
38 | protocol: TCP
39 | - containerPort: 389
40 | name: ldap
41 | - containerPort: 445
42 | name: smb
43 | protocol: TCP
44 | - containerPort: 464
45 | name: kerberos
46 | - containerPort: 636
47 | name: ldaps
48 | protocol: TCP
49 | - containerPort: 3268
50 | name: gc
51 | protocol: TCP
52 | - containerPort: 3269
53 | name: gc-ssl
54 | protocol: TCP
55 | # need 49152-65535 for dynamic RPC ports
56 | # but currently not possible to specify ranges
57 |
--------------------------------------------------------------------------------
/examples/kubernetes/samba-ctdb-dm-sset.yml:
--------------------------------------------------------------------------------
1 | #
2 | # An example of running samba with ctdb replication as a kubernetes
3 | # StatefulSet.
4 | #
5 | # This is *highly experimental* and not meant for real use. Use only if you're
6 | # interested in helping test or develop samba-container/sambacc CTDB support.
7 | #
8 | # This does not integrate with active directory.
9 | # This directly uses "rook-cephfs" for ReadWriteMany PVCs. If you have some
10 | # other storage class that supports rwx pvcs you need to edit the yaml below.
11 | # This only works with creating a clean set of pvcs & stateful set and scaling
12 | # up. It does *not* currently support pods getting restarted or scaling down.
13 | #
14 | # Use at your own risk, and have fun!
15 | #
16 | ---
17 | # Configuration for the samba smbd+winbind+ctdb pod.
18 | apiVersion: v1
19 | kind: ConfigMap
20 | metadata:
21 | name: samba-container-config-swc
22 | data:
23 | config.json: |
24 | {
25 | "samba-container-config": "v0",
26 | "configs": {
27 | "demo": {
28 | "shares": [
29 | "share"
30 | ],
31 | "globals": [
32 | "noprinting",
33 | "sambadm1",
34 | "vfs_fileid"
35 | ],
36 | "instance_features": ["ctdb"],
37 | "instance_name": "SAMBASWC"
38 | }
39 | },
40 | "shares": {
41 | "share": {
42 | "options": {
43 | "path": "/share",
44 | "read only": "no"
45 | }
46 | }
47 | },
48 | "_NOTE": "Change the security and workgroup keys to match your domain.",
49 | "globals": {
50 | "noprinting": {
51 | "options": {
52 | "load printers": "no",
53 | "printing": "bsd",
54 | "printcap name": "/dev/null",
55 | "disable spoolss": "yes"
56 | }
57 | },
58 | "sambadm1": {
59 | "options": {
60 | "log level": "10",
61 | "security": "ads",
62 | "workgroup": "CHANGEME",
63 | "realm": "CHANGEME.YOURDOMAIN.TLD",
64 | "server min protocol": "SMB2",
65 | "idmap config * : backend": "autorid",
66 | "idmap config * : range": "2000-9999999"
67 | }
68 | },
69 | "vfs_fileid": {
70 | "options": {
71 | "vfs objects": "fileid",
72 | "fileid:algorithm": "fsid"
73 | }
74 | }
75 | }
76 | }
77 | ---
78 | # Secret used to pass a AD join password to the pod.
79 | apiVersion: v1
80 | kind: Secret
81 | metadata:
82 | name: ad-join-secret
83 | type: Opaque
84 | stringData:
85 | # Change the value below to match the username and password for a user that
86 | # can join systems your test AD Domain
87 | join.json: |
88 | {"username": "Administrator", "password": "Passw0rd"}
89 | ---
90 | apiVersion: v1
91 | kind: PersistentVolumeClaim
92 | metadata:
93 | name: ctdb-shared-swc
94 | spec:
95 | accessModes:
96 | - ReadWriteMany
97 | storageClassName: rook-cephfs
98 | resources:
99 | requests:
100 | storage: 1Gi
101 | ---
102 | apiVersion: v1
103 | kind: PersistentVolumeClaim
104 | metadata:
105 | name: samba-share-data-swc
106 | spec:
107 | accessModes:
108 | - ReadWriteMany
109 | storageClassName: rook-cephfs
110 | resources:
111 | requests:
112 | storage: 2Gi
113 | ---
114 | apiVersion: v1
115 | kind: Service
116 | metadata:
117 | name: sssamba3-swc
118 | labels:
119 | app: clustered-samba-swc
120 | spec:
121 | ports:
122 | - port: 445
123 | name: smb
124 | clusterIP: None
125 | selector:
126 | app: clustered-samba-swc
127 | ---
128 | apiVersion: apps/v1
129 | kind: StatefulSet
130 | metadata:
131 | name: clustered-samba-swc
132 | spec:
133 | serviceName: "sssamba3-swc"
134 | replicas: 3
135 | selector:
136 | matchLabels:
137 | app: clustered-samba-swc
138 | template:
139 | metadata:
140 | labels:
141 | app: clustered-samba-swc
142 | spec:
143 | shareProcessNamespace: true
144 | initContainers:
145 | - image: quay.io/samba.org/samba-server:latest
146 | imagePullPolicy: Always
147 | name: init
148 | args:
149 | - "--config=/etc/samba-container/config.json"
150 | - "--id=demo"
151 | - "--skip-if-file=/var/lib/ctdb/shared/nodes"
152 | - "init"
153 | env: []
154 | securityContext:
155 | allowPrivilegeEscalation: true
156 | volumeMounts:
157 | - mountPath: "/etc/samba-container"
158 | name: samba-container-config
159 | - mountPath: "/var/lib/samba"
160 | name: samba-state-dir
161 | - mountPath: "/var/lib/ctdb/shared"
162 | name: ctdb-shared
163 | - image: quay.io/samba.org/samba-server:latest
164 | imagePullPolicy: Always
165 | name: import
166 | args:
167 | - "--config=/etc/samba-container/config.json"
168 | - "--id=demo"
169 | - "--skip-if-file=/var/lib/ctdb/shared/nodes"
170 | - "import"
171 | securityContext:
172 | allowPrivilegeEscalation: true
173 | volumeMounts:
174 | - mountPath: "/etc/samba-container"
175 | name: samba-container-config
176 | - mountPath: "/var/lib/samba"
177 | name: samba-state-dir
178 | - mountPath: "/var/lib/ctdb/shared"
179 | name: ctdb-shared
180 | - image: quay.io/samba.org/samba-server:latest
181 | imagePullPolicy: Always
182 | name: must-join
183 | args:
184 | - "--config=/etc/samba-container/config.json"
185 | - "--id=demo"
186 | - "--skip-if-file=/var/lib/ctdb/shared/nodes"
187 | - "must-join"
188 | - "--files"
189 | - "--join-file=/etc/join-data/join.json"
190 | securityContext:
191 | allowPrivilegeEscalation: true
192 | volumeMounts:
193 | - mountPath: "/etc/samba-container"
194 | name: samba-container-config
195 | - mountPath: "/var/lib/samba"
196 | name: samba-state-dir
197 | - mountPath: "/var/lib/ctdb/shared"
198 | name: ctdb-shared
199 | - mountPath: "/etc/join-data"
200 | name: samba-join-data
201 | readOnly: true
202 | - image: quay.io/samba.org/samba-server:latest
203 | imagePullPolicy: Always
204 | name: ctdb-migrate
205 | args:
206 | - "--config=/etc/samba-container/config.json"
207 | - "--id=demo"
208 | - "--skip-if-file=/var/lib/ctdb/shared/nodes"
209 | - "ctdb-migrate"
210 | - "--dest-dir=/var/lib/ctdb/persistent"
211 | env:
212 | - name: SAMBACC_CTDB
213 | value: "ctdb-is-experimental"
214 | securityContext:
215 | allowPrivilegeEscalation: true
216 | volumeMounts:
217 | - mountPath: "/etc/samba-container"
218 | name: samba-container-config
219 | - mountPath: "/var/lib/samba"
220 | name: samba-state-dir
221 | - mountPath: "/var/lib/ctdb/persistent"
222 | name: ctdb-persistent
223 | - mountPath: "/var/lib/ctdb/shared"
224 | name: ctdb-shared
225 | - image: quay.io/samba.org/samba-server:latest
226 | imagePullPolicy: Always
227 | name: ctdb-set-node
228 | args:
229 | - "--config=/etc/samba-container/config.json"
230 | - "--id=demo"
231 | - "ctdb-set-node"
232 | - "--hostname=$(HOSTNAME)"
233 | - "--take-node-number-from-hostname=after-last-dash"
234 | env:
235 | - name: SAMBACC_CTDB
236 | value: "ctdb-is-experimental"
237 | - name: HOSTNAME
238 | valueFrom:
239 | fieldRef:
240 | fieldPath: metadata.name
241 | securityContext:
242 | allowPrivilegeEscalation: true
243 | volumeMounts:
244 | - mountPath: "/etc/samba-container"
245 | name: samba-container-config
246 | - mountPath: "/var/lib/ctdb/shared"
247 | name: ctdb-shared
248 | - mountPath: "/etc/ctdb"
249 | name: ctdb-config
250 | - image: quay.io/samba.org/samba-server:latest
251 | imagePullPolicy: Always
252 | name: ctdb-must-have-node
253 | args:
254 | - "--config=/etc/samba-container/config.json"
255 | - "--id=demo"
256 | - "ctdb-must-have-node"
257 | - "--hostname=$(HOSTNAME)"
258 | - "--take-node-number-from-hostname=after-last-dash"
259 | env:
260 | - name: SAMBACC_CTDB
261 | value: "ctdb-is-experimental"
262 | - name: HOSTNAME
263 | valueFrom:
264 | fieldRef:
265 | fieldPath: metadata.name
266 | securityContext:
267 | allowPrivilegeEscalation: true
268 | volumeMounts:
269 | - mountPath: "/etc/samba-container"
270 | name: samba-container-config
271 | - mountPath: "/var/lib/ctdb/shared"
272 | name: ctdb-shared
273 | - mountPath: "/etc/ctdb"
274 | name: ctdb-config
275 | containers:
276 | - image: quay.io/samba.org/samba-server:latest
277 | imagePullPolicy: Always
278 | name: ctdb
279 | args:
280 | - "--config=/etc/samba-container/config.json"
281 | - "--id=demo"
282 | - "--debug-delay=2"
283 | - "run"
284 | - "ctdbd"
285 | - "--setup=smb_ctdb"
286 | - "--setup=ctdb_config"
287 | - "--setup=ctdb_etc"
288 | - "--setup=ctdb_nodes"
289 | securityContext:
290 | capabilities:
291 | add:
292 | - NET_RAW
293 | env:
294 | - name: SAMBACC_CTDB
295 | value: "ctdb-is-experimental"
296 | volumeMounts:
297 | - mountPath: "/etc/samba-container"
298 | name: samba-container-config
299 | - mountPath: "/var/lib/ctdb/shared"
300 | name: ctdb-shared
301 | - mountPath: "/var/lib/ctdb/persistent"
302 | name: ctdb-persistent
303 | - mountPath: "/var/lib/ctdb/volatile"
304 | name: ctdb-volatile
305 | - mountPath: "/etc/ctdb"
306 | name: ctdb-config
307 | - mountPath: "/var/run/ctdb"
308 | name: ctdb-sockets-dir
309 | - image: quay.io/samba.org/samba-server:latest
310 | imagePullPolicy: Always
311 | name: ctdb-manage-nodes
312 | args:
313 | - "--config=/etc/samba-container/config.json"
314 | - "--id=demo"
315 | - "ctdb-manage-nodes"
316 | - "--hostname=$(HOSTNAME)"
317 | - "--take-node-number-from-hostname=after-last-dash"
318 | env:
319 | - name: SAMBACC_CTDB
320 | value: "ctdb-is-experimental"
321 | - name: HOSTNAME
322 | valueFrom:
323 | fieldRef:
324 | fieldPath: metadata.name
325 | volumeMounts:
326 | - mountPath: "/etc/samba-container"
327 | name: samba-container-config
328 | - mountPath: "/var/lib/ctdb/shared"
329 | name: ctdb-shared
330 | - mountPath: "/etc/ctdb"
331 | name: ctdb-config
332 | - mountPath: "/var/run/ctdb"
333 | name: ctdb-sockets-dir
334 | - image: quay.io/samba.org/samba-server:latest
335 | imagePullPolicy: Always
336 | name: smb
337 | args:
338 | - "--config=/etc/samba-container/config.json"
339 | - "--id=demo"
340 | - "--debug-delay=12"
341 | - "run"
342 | - "smbd"
343 | - "--setup=nsswitch"
344 | - "--setup=smb_ctdb"
345 | ports:
346 | - containerPort: 445
347 | protocol: TCP
348 | name: "smb"
349 | securityContext:
350 | allowPrivilegeEscalation: true
351 | volumeMounts:
352 | - mountPath: "/etc/samba-container"
353 | name: samba-container-config
354 | - mountPath: "/share"
355 | name: samba-share-data
356 | - mountPath: "/var/lib/samba"
357 | name: samba-state-dir
358 | - mountPath: "/var/lib/ctdb/shared"
359 | name: ctdb-shared
360 | - mountPath: "/var/lib/ctdb/persistent"
361 | name: ctdb-persistent
362 | - mountPath: "/var/lib/ctdb/volatile"
363 | name: ctdb-volatile
364 | - mountPath: "/etc/ctdb"
365 | name: ctdb-config
366 | - mountPath: "/var/run/ctdb"
367 | name: ctdb-sockets-dir
368 | - mountPath: "/run/samba/winbindd"
369 | name: samba-sockets-dir
370 | - image: quay.io/samba.org/samba-server:latest
371 | name: winbind
372 | args:
373 | - "--config=/etc/samba-container/config.json"
374 | - "--id=demo"
375 | - "--debug-delay=10"
376 | - "run"
377 | - "winbindd"
378 | - "--setup=nsswitch"
379 | - "--setup=smb_ctdb"
380 | securityContext:
381 | allowPrivilegeEscalation: true
382 | volumeMounts:
383 | - mountPath: "/etc/samba-container"
384 | name: samba-container-config
385 | - mountPath: "/var/lib/samba"
386 | name: samba-state-dir
387 | - mountPath: "/var/lib/ctdb/shared"
388 | name: ctdb-shared
389 | - mountPath: "/var/lib/ctdb/persistent"
390 | name: ctdb-persistent
391 | - mountPath: "/var/lib/ctdb/volatile"
392 | name: ctdb-volatile
393 | - mountPath: "/etc/ctdb"
394 | name: ctdb-config
395 | - mountPath: "/var/run/ctdb"
396 | name: ctdb-sockets-dir
397 | - mountPath: "/run/samba/winbindd"
398 | name: samba-sockets-dir
399 | volumes:
400 | # /etc/ctdb
401 | - emptyDir: {}
402 | name: ctdb-config
403 | # /var/lib/ctdb/persistent
404 | - emptyDir: {}
405 | name: ctdb-persistent
406 | # /var/lib/ctdb/volatile
407 | - emptyDir: {}
408 | name: ctdb-volatile
409 | # /var/lib/ctdb/shared
410 | - persistentVolumeClaim:
411 | claimName: ctdb-shared-swc
412 | name: ctdb-shared
413 | # /var/run/ctdb
414 | - emptyDir:
415 | medium: Memory
416 | name: ctdb-sockets-dir
417 | # /var/lib/samba
418 | - emptyDir: {}
419 | name: samba-state-dir
420 | # /share
421 | - persistentVolumeClaim:
422 | claimName: samba-share-data-swc
423 | name: samba-share-data
424 | - emptyDir:
425 | medium: Memory
426 | name: samba-sockets-dir
427 | - configMap:
428 | name: samba-container-config-swc
429 | name: samba-container-config
430 | - secret:
431 | secretName: ad-join-secret
432 | items:
433 | - key: join.json
434 | path: join.json
435 | name: samba-join-data
436 |
--------------------------------------------------------------------------------
/examples/kubernetes/samba-ctdb-sset.yml:
--------------------------------------------------------------------------------
1 | #
2 | # An example of running samba with ctdb replication as a kubernetes
3 | # StatefulSet.
4 | #
5 | # This is *highly experimental* and not meant for real use. Use only if you're
6 | # interested in helping test or develop samba-container/sambacc CTDB support.
7 | #
8 | # This does not integrate with active directory.
9 | # This directly uses "rook-cephfs" for ReadWriteMany PVCs. If you have some
10 | # other storage class that supports rwx pvcs you need to edit the yaml below.
11 | # This only works with creating a clean set of pvcs & stateful set and scaling
12 | # up. It does *not* currently support pods getting restarted or scaling down.
13 | #
14 | # Use at your own risk, and have fun!
15 | #
16 | ---
17 | apiVersion: v1
18 | kind: PersistentVolumeClaim
19 | metadata:
20 | name: ctdb-shared
21 | spec:
22 | accessModes:
23 | - ReadWriteMany
24 | storageClassName: rook-cephfs
25 | resources:
26 | requests:
27 | storage: 1Gi
28 | ---
29 | apiVersion: v1
30 | kind: PersistentVolumeClaim
31 | metadata:
32 | name: samba-share-data
33 | spec:
34 | accessModes:
35 | - ReadWriteMany
36 | storageClassName: rook-cephfs
37 | resources:
38 | requests:
39 | storage: 2Gi
40 | ---
41 | apiVersion: v1
42 | kind: Service
43 | metadata:
44 | name: sssamba
45 | labels:
46 | app: clustered-samba
47 | spec:
48 | ports:
49 | - port: 445
50 | name: smb
51 | clusterIP: None
52 | selector:
53 | app: clustered-samba
54 | ---
55 | apiVersion: apps/v1
56 | kind: StatefulSet
57 | metadata:
58 | name: clustered-samba
59 | spec:
60 | serviceName: "sssamba"
61 | replicas: 3
62 | selector:
63 | matchLabels:
64 | app: clustered-samba
65 | template:
66 | metadata:
67 | labels:
68 | app: clustered-samba
69 | spec:
70 | shareProcessNamespace: true
71 | initContainers:
72 | - image: quay.io/samba.org/samba-server:latest
73 | imagePullPolicy: Always
74 | name: init
75 | args:
76 | - "--config=/usr/local/share/sambacc/examples/ctdb.json"
77 | - "--id=demo"
78 | - "--skip-if-file=/var/lib/ctdb/shared/nodes"
79 | - "init"
80 | env: []
81 | securityContext:
82 | allowPrivilegeEscalation: true
83 | volumeMounts:
84 | - mountPath: "/var/lib/samba"
85 | name: samba-state-dir
86 | - mountPath: "/var/lib/ctdb/shared"
87 | name: ctdb-shared
88 | - image: quay.io/samba.org/samba-server:latest
89 | imagePullPolicy: Always
90 | name: import
91 | args:
92 | - "--config=/usr/local/share/sambacc/examples/ctdb.json"
93 | - "--id=demo"
94 | - "--skip-if-file=/var/lib/ctdb/shared/nodes"
95 | - "import"
96 | securityContext:
97 | allowPrivilegeEscalation: true
98 | volumeMounts:
99 | - mountPath: "/var/lib/samba"
100 | name: samba-state-dir
101 | - mountPath: "/var/lib/ctdb/shared"
102 | name: ctdb-shared
103 | - image: quay.io/samba.org/samba-server:latest
104 | imagePullPolicy: Always
105 | name: import-users
106 | args:
107 | - "--config=/usr/local/share/sambacc/examples/ctdb.json"
108 | - "--id=demo"
109 | - "--skip-if-file=/var/lib/ctdb/shared/nodes"
110 | - "import-users"
111 | securityContext:
112 | allowPrivilegeEscalation: true
113 | volumeMounts:
114 | - mountPath: "/var/lib/samba"
115 | name: samba-state-dir
116 | - mountPath: "/var/lib/ctdb/shared"
117 | name: ctdb-shared
118 | - image: quay.io/samba.org/samba-server:latest
119 | imagePullPolicy: Always
120 | name: ctdb-migrate
121 | args:
122 | - "--config=/usr/local/share/sambacc/examples/ctdb.json"
123 | - "--id=demo"
124 | - "--skip-if-file=/var/lib/ctdb/shared/nodes"
125 | - "ctdb-migrate"
126 | - "--dest-dir=/var/lib/ctdb/persistent"
127 | env:
128 | - name: SAMBACC_CTDB
129 | value: "ctdb-is-experimental"
130 | securityContext:
131 | allowPrivilegeEscalation: true
132 | volumeMounts:
133 | - mountPath: "/var/lib/samba"
134 | name: samba-state-dir
135 | - mountPath: "/var/lib/ctdb/persistent"
136 | name: ctdb-persistent
137 | - mountPath: "/var/lib/ctdb/shared"
138 | name: ctdb-shared
139 | - image: quay.io/samba.org/samba-server:latest
140 | imagePullPolicy: Always
141 | name: ctdb-set-node
142 | args:
143 | - "--config=/usr/local/share/sambacc/examples/ctdb.json"
144 | - "--id=demo"
145 | - "ctdb-set-node"
146 | - "--hostname=$(HOSTNAME)"
147 | - "--take-node-number-from-hostname=after-last-dash"
148 | env:
149 | - name: SAMBACC_CTDB
150 | value: "ctdb-is-experimental"
151 | - name: HOSTNAME
152 | valueFrom:
153 | fieldRef:
154 | fieldPath: metadata.name
155 | securityContext:
156 | allowPrivilegeEscalation: true
157 | volumeMounts:
158 | - mountPath: "/var/lib/ctdb/shared"
159 | name: ctdb-shared
160 | - mountPath: "/etc/ctdb"
161 | name: ctdb-config
162 | - image: quay.io/samba.org/samba-server:latest
163 | imagePullPolicy: Always
164 | name: ctdb-must-have-node
165 | args:
166 | - "--config=/usr/local/share/sambacc/examples/ctdb.json"
167 | - "--id=demo"
168 | - "ctdb-must-have-node"
169 | - "--hostname=$(HOSTNAME)"
170 | - "--take-node-number-from-hostname=after-last-dash"
171 | env:
172 | - name: SAMBACC_CTDB
173 | value: "ctdb-is-experimental"
174 | - name: HOSTNAME
175 | valueFrom:
176 | fieldRef:
177 | fieldPath: metadata.name
178 | securityContext:
179 | allowPrivilegeEscalation: true
180 | volumeMounts:
181 | - mountPath: "/var/lib/ctdb/shared"
182 | name: ctdb-shared
183 | - mountPath: "/etc/ctdb"
184 | name: ctdb-config
185 | containers:
186 | - image: quay.io/samba.org/samba-server:latest
187 | imagePullPolicy: Always
188 | name: ctdb
189 | args:
190 | - "--config=/usr/local/share/sambacc/examples/ctdb.json"
191 | - "--id=demo"
192 | - "--debug-delay=2"
193 | - "run"
194 | - "ctdbd"
195 | - "--setup=smb_ctdb"
196 | - "--setup=ctdb_config"
197 | - "--setup=ctdb_etc"
198 | - "--setup=ctdb_nodes"
199 | env:
200 | - name: SAMBACC_CTDB
201 | value: "ctdb-is-experimental"
202 | volumeMounts:
203 | - mountPath: "/var/lib/ctdb/shared"
204 | name: ctdb-shared
205 | - mountPath: "/var/lib/ctdb/persistent"
206 | name: ctdb-persistent
207 | - mountPath: "/var/lib/ctdb/volatile"
208 | name: ctdb-volatile
209 | - mountPath: "/etc/ctdb"
210 | name: ctdb-config
211 | - mountPath: "/var/run/ctdb"
212 | name: ctdb-sockets-dir
213 | - image: quay.io/samba.org/samba-server:latest
214 | imagePullPolicy: Always
215 | name: ctdb-manage-nodes
216 | args:
217 | - "--config=/usr/local/share/sambacc/examples/ctdb.json"
218 | - "--id=demo"
219 | - "ctdb-manage-nodes"
220 | - "--hostname=$(HOSTNAME)"
221 | - "--take-node-number-from-hostname=after-last-dash"
222 | env:
223 | - name: SAMBACC_CTDB
224 | value: "ctdb-is-experimental"
225 | - name: HOSTNAME
226 | valueFrom:
227 | fieldRef:
228 | fieldPath: metadata.name
229 | volumeMounts:
230 | - mountPath: "/var/lib/ctdb/shared"
231 | name: ctdb-shared
232 | - mountPath: "/etc/ctdb"
233 | name: ctdb-config
234 | - mountPath: "/var/run/ctdb"
235 | name: ctdb-sockets-dir
236 | - image: quay.io/samba.org/samba-server:latest
237 | imagePullPolicy: Always
238 | name: smb
239 | args:
240 | - "--config=/usr/local/share/sambacc/examples/ctdb.json"
241 | - "--id=demo"
242 | - "--debug-delay=12"
243 | - "run"
244 | - "smbd"
245 | - "--setup=users"
246 | - "--setup=smb_ctdb"
247 | ports:
248 | - containerPort: 445
249 | protocol: TCP
250 | name: "smb"
251 | securityContext:
252 | allowPrivilegeEscalation: true
253 | volumeMounts:
254 | - mountPath: "/share"
255 | name: samba-share-data
256 | - mountPath: "/var/lib/ctdb/shared"
257 | name: ctdb-shared
258 | - mountPath: "/var/lib/ctdb/persistent"
259 | name: ctdb-persistent
260 | - mountPath: "/var/lib/ctdb/volatile"
261 | name: ctdb-volatile
262 | - mountPath: "/etc/ctdb"
263 | name: ctdb-config
264 | - mountPath: "/var/run/ctdb"
265 | name: ctdb-sockets-dir
266 | volumes:
267 | # /etc/ctdb
268 | - emptyDir: {}
269 | name: ctdb-config
270 | # /var/lib/ctdb/persistent
271 | - emptyDir: {}
272 | name: ctdb-persistent
273 | # /var/lib/ctdb/volatile
274 | - emptyDir: {}
275 | name: ctdb-volatile
276 | # /var/lib/ctdb/shared
277 | - persistentVolumeClaim:
278 | claimName: ctdb-shared
279 | name: ctdb-shared
280 | # /var/run/ctdb
281 | - emptyDir:
282 | medium: Memory
283 | name: ctdb-sockets-dir
284 | # /var/lib/samba
285 | - emptyDir: {}
286 | name: samba-state-dir
287 | # /share
288 | - persistentVolumeClaim:
289 | claimName: samba-share-data
290 | name: samba-share-data
291 |
--------------------------------------------------------------------------------
/examples/kubernetes/sambadeployment.converged.yml:
--------------------------------------------------------------------------------
1 | ---
2 | apiVersion: apps/v1
3 | kind: Deployment
4 | metadata:
5 | name: samba-pvc-deployment
6 | labels:
7 | app: samba
8 | spec:
9 | replicas: 1
10 | selector:
11 | matchLabels:
12 | app: samba
13 | template:
14 | metadata:
15 | labels:
16 | app: samba
17 | spec:
18 | volumes:
19 | - name: myvol
20 | persistentVolumeClaim:
21 | claimName: mypvc
22 | containers:
23 | - name: samba
24 | image: quay.io/samba.org/samba-server:latest
25 | ports:
26 | - containerPort: 445
27 | volumeMounts:
28 | - mountPath: "/share"
29 | name: myvol
30 | ---
31 | apiVersion: v1
32 | kind: PersistentVolumeClaim
33 | metadata:
34 | name: mypvc
35 | spec:
36 | storageClassName: manual
37 | accessModes:
38 | - ReadWriteOnce
39 | resources:
40 | requests:
41 | storage: 1Gi
42 | ---
43 | apiVersion: v1
44 | kind: PersistentVolume
45 | metadata:
46 | name: mypv
47 | labels:
48 | type: local
49 | spec:
50 | storageClassName: manual
51 | capacity:
52 | storage: 1Gi
53 | accessModes:
54 | - ReadWriteOnce
55 | hostPath:
56 | path: "/mnt/pv"
57 |
--------------------------------------------------------------------------------
/examples/kubernetes/sambadeployment.yml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: samba-pvc-deployment
5 | labels:
6 | app: samba
7 | spec:
8 | replicas: 1
9 | selector:
10 | matchLabels:
11 | app: samba
12 | template:
13 | metadata:
14 | labels:
15 | app: samba
16 | spec:
17 | volumes:
18 | - name: myvol
19 | persistentVolumeClaim:
20 | claimName: mypvc
21 | containers:
22 | - name: samba
23 | image: quay.io/samba.org/samba-server:latest
24 | ports:
25 | - containerPort: 445
26 | volumeMounts:
27 | - mountPath: "/share"
28 | name: myvol
29 |
--------------------------------------------------------------------------------
/examples/kubernetes/sambadmpod.yml:
--------------------------------------------------------------------------------
1 | #
2 | # A Samba smbd + winbindd pod that automatically becomes a domain member.
3 | # This setup requires the config map "samba-conainer-config" to match
4 | # your test domain. It requires the Administrator password to be present
5 | # in the "ad-join-secret" secret.
6 | #
7 | # This configuration assumes you can reach your AD's DNS via the normal
8 | # Kubernetes DNS configuration. If not you may wish to look into the
9 | # customizing the Pod DNS settings or Kubernetes DNS customization.
10 | #
11 | # Edit the lines below that contain "CHANGEME" and make them match
12 | # your domain's setting.
13 | #
14 | # Edit the string value for "JOIN_PASSWORD" in the secret below and
15 | # make sure it matches your domain administrator's password.
16 | #
17 | # You can tweak the samba-sharedir volume under "volumes" at the end
18 | # of the pod yaml below. Use this to toggle between a temporary share
19 | # or a PVC backed share.
20 | #
21 | # NOTE: All settings below can be modified but those mentioned above
22 | # will get you a running container more quickly, feel free to start
23 | # there and then begin tinkering!
24 | #
25 | ---
26 | # Configuration for the samba domain member pod.
27 | apiVersion: v1
28 | kind: ConfigMap
29 | metadata:
30 | name: samba-container-config
31 | data:
32 | config.json: |
33 | {
34 | "samba-container-config": "v0",
35 | "configs": {
36 | "sambadm1": {
37 | "shares": [
38 | "share"
39 | ],
40 | "globals": [
41 | "noprinting",
42 | "sambadm1"
43 | ],
44 | "instance_name": "SMBDM1"
45 | }
46 | },
47 | "shares": {
48 | "share": {
49 | "options": {
50 | "path": "/share",
51 | "read only": "no"
52 | }
53 | }
54 | },
55 | "_NOTE": "Change the security and workgroup keys to match your domain.",
56 | "globals": {
57 | "noprinting": {
58 | "options": {
59 | "load printers": "no",
60 | "printing": "bsd",
61 | "printcap name": "/dev/null",
62 | "disable spoolss": "yes"
63 | }
64 | },
65 | "sambadm1": {
66 | "options": {
67 | "log level": "10",
68 | "security": "ads",
69 | "workgroup": "CHANGEME",
70 | "realm": "CHANGEME.YOURDOMAIN.TLD",
71 | "server min protocol": "SMB2",
72 | "idmap config * : backend": "autorid",
73 | "idmap config * : range": "2000-9999999"
74 | }
75 | }
76 | }
77 | }
78 | ---
79 | # Secret used to pass a AD join password to the winbind pod.
80 | apiVersion: v1
81 | kind: Secret
82 | metadata:
83 | name: ad-join-secret
84 | type: Opaque
85 | stringData:
86 | # Change the value below to match the username and password for a user that
87 | # can join systems your test AD Domain
88 | join.json: |
89 | {"username": "Administrator", "password": "Passw0rd"}
90 | ---
91 | # The pod itself.
92 | apiVersion: v1
93 | kind: Pod
94 | metadata:
95 | labels:
96 | app: samba-dm-example
97 | name: samba-dm
98 | spec:
99 | shareProcessNamespace: true
100 | containers:
101 | - image: quay.io/samba.org/samba-server:latest
102 | name: smb
103 | command:
104 | - "samba-container"
105 | - "--debug-delay=1"
106 | - "run"
107 | - "smbd"
108 | env:
109 | - name: SAMBACC_CONFIG
110 | value: /etc/samba-container/config.json
111 | - name: SAMBA_CONTAINER_ID
112 | value: sambadm1
113 | - name: SAMBACC_VERSION
114 | value: "0.1"
115 | - name: HOSTNAME
116 | value: sambadm1
117 | ports:
118 | - containerPort: 445
119 | hostPort: 455
120 | protocol: TCP
121 | name: "smb"
122 | securityContext:
123 | allowPrivilegeEscalation: true
124 | volumeMounts:
125 | - mountPath: "/share"
126 | name: samba-sharedir
127 | - mountPath: "/etc/samba-container"
128 | name: samba-container-config
129 | - mountPath: "/var/lib/samba"
130 | name: samba-state-dir
131 | - mountPath: "/run/samba/winbindd"
132 | name: samba-sockets-dir
133 | - image: quay.io/samba.org/samba-server:latest
134 | name: winbind
135 | command:
136 | - "samba-container"
137 | - "run"
138 | - "winbindd"
139 | env:
140 | - name: SAMBACC_VERSION
141 | value: "0.1"
142 | - name: SAMBACC_CONFIG
143 | value: /etc/samba-container/config.json
144 | - name: SAMBA_CONTAINER_ID
145 | value: sambadm1
146 | - name: HOSTNAME
147 | value: sambadm1
148 | securityContext:
149 | allowPrivilegeEscalation: true
150 | volumeMounts:
151 | - mountPath: "/etc/samba-container"
152 | name: samba-container-config
153 | - mountPath: "/var/lib/samba"
154 | name: samba-state-dir
155 | - mountPath: "/run/samba/winbindd"
156 | name: samba-sockets-dir
157 | initContainers:
158 | - image: quay.io/samba.org/samba-server:latest
159 | name: init
160 | args:
161 | - "init"
162 | env:
163 | - name: SAMBACC_VERSION
164 | value: "0.1"
165 | - name: SAMBACC_CONFIG
166 | value: /etc/samba-container/config.json
167 | - name: SAMBA_CONTAINER_ID
168 | value: sambadm1
169 | - name: HOSTNAME
170 | value: sambadm1
171 | securityContext:
172 | allowPrivilegeEscalation: true
173 | volumeMounts:
174 | - mountPath: "/etc/samba-container"
175 | name: samba-container-config
176 | - mountPath: "/var/lib/samba"
177 | name: samba-state-dir
178 | - image: quay.io/samba.org/samba-server:latest
179 | name: must-join
180 | args:
181 | - "must-join"
182 | - "--files"
183 | - "--join-file=/etc/join-data/join.json"
184 | env:
185 | - name: SAMBACC_VERSION
186 | value: "0.1"
187 | - name: SAMBACC_CONFIG
188 | value: /etc/samba-container/config.json
189 | - name: SAMBA_CONTAINER_ID
190 | value: sambadm1
191 | - name: HOSTNAME
192 | value: sambadm1
193 | securityContext:
194 | allowPrivilegeEscalation: true
195 | volumeMounts:
196 | - mountPath: "/etc/samba-container"
197 | name: samba-container-config
198 | - mountPath: "/var/lib/samba"
199 | name: samba-state-dir
200 | - mountPath: "/etc/join-data"
201 | name: samba-join-data
202 | readOnly: true
203 | volumes:
204 | - configMap:
205 | name: samba-container-config
206 | name: samba-container-config
207 | - secret:
208 | secretName: ad-join-secret
209 | items:
210 | - key: join.json
211 | path: join.json
212 | name: samba-join-data
213 | - emptyDir:
214 | medium: Memory
215 | name: samba-sockets-dir
216 | - emptyDir: {}
217 | name: samba-state-dir
218 | # Comment out the section below to skip using a PVC for the share
219 | - persistentVolumeClaim:
220 | claimName: mypvc
221 | name: samba-sharedir
222 | # Uncomment the section below to use an empty dir for the share
223 | # - emptyDir:
224 | # medium: Memory
225 | # name: samba-sharedir
226 |
--------------------------------------------------------------------------------
/examples/kubernetes/sambapod.yml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Pod
3 | metadata:
4 | name: sambapod
5 | spec:
6 | volumes:
7 | - name: myvol
8 | persistentVolumeClaim:
9 | claimName: mypvc
10 | containers:
11 | - name: mycontainer
12 | image: quay.io/samba.org/samba-server:latest
13 | ports:
14 | - containerPort: 445
15 | name: "samba445"
16 | volumeMounts:
17 | - mountPath: "/share"
18 | name: myvol
19 |
--------------------------------------------------------------------------------
/examples/podman/README.md:
--------------------------------------------------------------------------------
1 |
2 | # Podman Examples
3 |
4 | These examples demonstrate using samba container images with podman.
5 |
6 | ## Domain Joined SMB Shares
7 |
8 | Included here is a shell script and a JSON config template that demonstrates
9 | using podman to run an smbd instance joined to Active Directory. Do note that
10 | the Active Directory in question must already exist and permit new joins using
11 | the Administrator account. You *must* edit the provided files to match your
12 | domain/environment.
13 |
14 | If you plan to run the pod with rootless podman do note that the smbd processes
15 | make use of the setuid and setgroups system apis. Rootless podman is restricted
16 | to a limited set of ids that are controlled by /etc/subuid and /etc/subgid. If
17 | the ID range configured for winbind exceed these limits the smbd process will
18 | panic when the user connects to the share. See the
19 | [rootless podman documentation](https://github.com/containers/podman/blob/master/docs/tutorials/rootless_tutorial.md#etcsubuid-and-etcsubgid-configuration)
20 | for more detail on this subject.
21 |
22 | Example:
23 | ```
24 | cd ./examples/podman
25 | # configure the example config for your domain:
26 | $EDITOR config.json
27 | # tweak script parameters for your environment:
28 | $EDITOR smb-wb-pod.sh
29 |
30 | ./smb-wb-pod.sh /tmp/samba-container-demo start
31 | # wait a little bit
32 | smbclient --port 4450 -U 'DOM\User%Pass' //localhost/share
33 |
34 | # stop it
35 | ./smb-wb-pod.sh /tmp/samba-container-demo stop
36 |
37 | # clean up working dir
38 | ./smb-wb-pod.sh /tmp/samba-container-demo clean
39 | ```
40 |
41 |
--------------------------------------------------------------------------------
/examples/podman/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "samba-container-config": "v0",
3 | "configs": {
4 | "wbtest": {
5 | "shares": [
6 | "share"
7 | ],
8 | "globals": [
9 | "noprinting",
10 | "wbtest"
11 | ],
12 | "instance_name": "WB1"
13 | }
14 | },
15 | "shares": {
16 | "share": {
17 | "options": {
18 | "path": "/share",
19 | "read only": "no"
20 | }
21 | }
22 | },
23 | "_NOTE": "Change the security and workgroup keys to match your domain.",
24 | "globals": {
25 | "noprinting": {
26 | "options": {
27 | "load printers": "no",
28 | "printing": "bsd",
29 | "printcap name": "/dev/null",
30 | "disable spoolss": "yes"
31 | }
32 | },
33 | "wbtest": {
34 | "options": {
35 | "log level": "10",
36 | "security": "ads",
37 | "workgroup": "CHANGEME",
38 | "realm": "CHANGEME.YOURDOMAIN.TLD",
39 | "server min protocol": "SMB2",
40 | "idmap config * : backend": "autorid",
41 | "idmap config * : range": "2000-9999999"
42 | }
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/examples/podman/smb-wb-pod.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # This script demonstrates using podman's pods feature to run a smbd
4 | # and winbind container together, configured via samba-container json.
5 | # It automatically joins the domain with the password specified below.
6 | # We don't currently have a secure containerized join so please only
7 | # use this on scratch testing domains.
8 |
9 | set -e
10 |
11 | # NOTE: This script depnds on the sambacc config json to:
12 | # a) Reside in the same directory as this script
13 | # b) Be configured for your AD domain settings
14 |
15 | #-- user settable options ---
16 | #
17 | # The container image to use
18 | image=quay.io/samba.org/samba-server:latest
19 | # The name of the pod
20 | name=domsamba
21 | # The port that 445 will be mapped to
22 | pubport=4450
23 | # Use the following vars to customize the podman cli for your particular
24 | # environment
25 | podextraopts=()
26 | ctrextraopts=()
27 | # The AD administrator password for INSECURE join
28 | ad_password="Passw0rd"
29 | #----------------------------
30 |
31 | workdir="$1"
32 |
33 | case "$2" in
34 | start)
35 | set -x
36 |
37 | mkdir -p "${workdir}"/state/private
38 | mkdir -p "${workdir}"/wbsockets
39 | mkdir -p "${workdir}"/config
40 | mkdir -p "${workdir}"/share
41 | chmod 0755 "${workdir}"/wbsockets
42 | chmod 0777 "${workdir}"/share
43 | cp config.json "${workdir}"/config/config.json
44 |
45 | podman pod create \
46 | --hostname="${name}" \
47 | --name="${name}" \
48 | --share=pid,uts,net \
49 | --publish="${pubport}:445" \
50 | "${podextraopts[@]}"
51 | podman pod start "${name}"
52 |
53 | podman container run \
54 | --detach \
55 | --pod="${name}" \
56 | --name="${name}-wb" \
57 | -v "${workdir}/config":/usr/local/etc \
58 | -v "${workdir}/state":/var/lib/samba:z \
59 | -v "${workdir}/wbsockets":/run/samba/winbindd:z \
60 | -e SAMBA_CONTAINER_ID="${name}" \
61 | -e SAMBACC_CONFIG="/usr/local/etc/config.json" \
62 | "${ctrextraopts[@]}" \
63 | "${image}" \
64 | --password="${ad_password}" \
65 | run \
66 | --insecure-auto-join \
67 | winbindd
68 | sleep 1s
69 | podman container run \
70 | --detach \
71 | --pod="${name}" \
72 | --name="${name}-smb" \
73 | -v "${workdir}/config":/usr/local/etc \
74 | -v "${workdir}/state":/var/lib/samba:z \
75 | -v "${workdir}/wbsockets":/run/samba/winbindd:z \
76 | -v "${workdir}/share":/share:z \
77 | -e SAMBA_CONTAINER_ID="${name}" \
78 | -e SAMBACC_CONFIG="/usr/local/etc/config.json" \
79 | "${ctrextraopts[@]}" \
80 | "${image}" \
81 | run \
82 | smbd
83 | ;;
84 | stop)
85 | podman pod stop wbtest
86 | podman pod rm wbtest
87 | ;;
88 | restart)
89 | "$0" "$1" stop
90 | "$0" "$1" start
91 | ;;
92 | clean)
93 | rm -rf "$workdir"
94 | ;;
95 | *)
96 | echo "Run smb filesharing with domain join in podman"
97 | echo ""
98 | echo "$0 {start,stop,clean}"
99 | echo " workdir: the directory to place shared container data"
100 | echo " start: start the pod"
101 | echo " stop: stop the pod"
102 | echo " restart: stop and then start the pod"
103 | echo " clean: remove the shared workdir"
104 | echo ""
105 | echo "Example:"
106 | echo " $0 /tmp/samba-container-demo start"
107 | ;;
108 | esac
109 |
--------------------------------------------------------------------------------
/hack/build-image:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python3
2 | """
3 | build-image - A script for building a matrix of samba container images.
4 |
5 | In order to cleanly implement both logic and maintain backwards compatibility
6 | with image naming schemes already in the wild the build-image script
7 | can be used to create "Fully Qualified Image Names" that combine the
8 | image kind (samba-server, client, etc) and a tag that indicates all
9 | the unique properties of the image. This includes the package source,
10 | the base os, and the architecture.
11 |
12 | In addition to building the images, one can push images, list images,
13 | and list build status files (aka buildfiles).
14 |
15 | Usage:
16 | # build an image
17 | ./hack/build-image --kind server --distro-base fedora --arch amd64
18 |
19 | # print out the FQIN
20 | ./hack/build-image --kind samba-server --distro-base fedora \\
21 | --arch amd64 --print
22 |
23 | # print out the FQIN and additional tags
24 | ./hack/build-image --kind samba-server --distro-base fedora \\
25 | --arch amd64 --print-tags
26 |
27 | # print out the FQIN and additional tags for multiple images, with
28 | # and without a repository base
29 | ./hack/build-image --kind samba-server \\
30 | --distro-base fedora \\
31 | --distro-base centos \\
32 | --distro-base opensuse \\
33 | --arch amd64 \\
34 | --repo-base quay.io/foobar --without-repo-bases --print-tags
35 |
36 | """
37 |
38 | import argparse
39 | import logging
40 | import os
41 | import pathlib
42 | import platform
43 | import shlex
44 | import shutil
45 | import subprocess
46 | import sys
47 |
48 |
49 | logger = logging.getLogger("build-image")
50 |
51 | # Set FORCE_ARCH_FLAG if you want to test passing the --arch flag to podman all
52 | # the time. This was the previous behavior but we found it to have some issues.
53 | # When this is false the --arch flag is passed to podman ONLY when the target
54 | # arch != the host system arch.
55 | FORCE_ARCH_FLAG = False
56 |
57 | # IMAGE_KINDS - map aliases/names to canonical names for the kinds
58 | # of images we can build
59 | IMG_SERVER = "samba-server"
60 | IMG_AD_SERVER = "samba-ad-server"
61 | IMG_CLIENT = "samba-client"
62 | IMG_TOOLBOX = "samba-toolbox"
63 | IMAGE_KINDS = {
64 | # short names
65 | "server": IMG_SERVER,
66 | "ad-server": IMG_AD_SERVER,
67 | "client": IMG_CLIENT,
68 | "toolbox": IMG_TOOLBOX,
69 | # canonical names
70 | "samba-server": IMG_SERVER,
71 | "samba-ad-server": IMG_AD_SERVER,
72 | "samba-client": IMG_CLIENT,
73 | "samba-toolbox": IMG_TOOLBOX,
74 | }
75 |
76 | # ARCHITECTURES - map supported arch names/alias to canonical names
77 | AMD64 = "amd64"
78 | ARM64 = "arm64"
79 | ARCHITECTURES = {
80 | # alternate names
81 | "x86_64": AMD64,
82 | "aarch64": ARM64,
83 | # canonical names
84 | "amd64": AMD64,
85 | "arm64": ARM64,
86 | }
87 |
88 | # DISTROS - list of supported distro bases
89 | FEDORA = "fedora"
90 | CENTOS = "centos"
91 | OPENSUSE = "opensuse"
92 | DISTROS = [
93 | FEDORA,
94 | CENTOS,
95 | OPENSUSE,
96 | ]
97 |
98 | # PACKAGE_SOURCES - list of known package sources
99 | DEFAULT = "default"
100 | NIGHTLY = "nightly"
101 | DEVBUILDS = "devbuilds"
102 | PACKAGE_SOURCES = [DEFAULT, NIGHTLY, DEVBUILDS]
103 |
104 | PACKAGES_FROM = {
105 | DEFAULT: "",
106 | NIGHTLY: "samba-nightly",
107 | DEVBUILDS: "devbuilds",
108 | }
109 |
110 | # SOURCE_DIRS - image source paths
111 | # (paths are relative to common image source dir)
112 | SOURCE_DIRS = {
113 | IMG_SERVER: "server",
114 | IMG_AD_SERVER: "ad-server",
115 | IMG_CLIENT: "client",
116 | IMG_TOOLBOX: "toolbox",
117 | }
118 |
119 | DEFAULT_PKG_SOURCES = [DEFAULT]
120 | DEFAULT_DISTRO_BASES = [FEDORA]
121 | LATEST = "latest"
122 | QUAL_NONE = "unqualified"
123 | QUAL_DISTRO = "distro-qualified"
124 | QUAL_FQIN = "fqin"
125 |
126 |
127 | _DISCOVERED_CONTAINER_ENGINES = []
128 |
129 |
130 | def check_kind(kind):
131 | """Return the canonical name for the image kind or raise a ValueError."""
132 | try:
133 | return IMAGE_KINDS[kind]
134 | except KeyError:
135 | raise ValueError(f"invalid kind: {kind}")
136 |
137 |
138 | def check_arch(arch):
139 | """Return the canonical name for the arch or raise a ValueError."""
140 | try:
141 | return ARCHITECTURES[arch]
142 | except KeyError:
143 | raise ValueError(f"invalid arch: {arch}")
144 |
145 |
146 | def check_distro(distro):
147 | """Return the canonical name for a distro base or raise a ValueError."""
148 | if distro in DISTROS:
149 | return distro
150 | raise ValueError(f"invalid distro: {distro}")
151 |
152 |
153 | def check_pkg_source(source):
154 | """Return the canonical name for a package source or raise a ValueError."""
155 | if source in PACKAGE_SOURCES:
156 | return source
157 | raise ValueError(f"invalid package source: {source}")
158 |
159 |
160 | def check_repo_base_for(value):
161 | """Return a tuple with a (distro_base, repo_base) pair or raise a
162 | ValueError.
163 | """
164 | if "=" not in value:
165 | raise ValueError("expected '=' in value")
166 | db, rb = value.split("=", 1)
167 | db = check_distro(db)
168 | return (db, rb)
169 |
170 |
171 | def _cmd_to_str(cmd):
172 | """Format a command for logging."""
173 | return " ".join(shlex.quote(arg) for arg in cmd)
174 |
175 |
176 | def run(cli, cmd, capture_output=False, check=False):
177 | """Execute a command. Wraps subprocess.run."""
178 | if cli.dry_run and not capture_output:
179 | logger.info("Would run: %s", _cmd_to_str(cmd))
180 | return subprocess.CompletedProcess(cmd, 0)
181 | logger.info("Running: %s", _cmd_to_str(cmd))
182 | return subprocess.run(cmd, capture_output=capture_output, check=check)
183 |
184 |
185 | def container_engine(cli):
186 | """Return the path to a container engine. If the container engine is not
187 | yet known, discover it and cache the result.
188 | """
189 | eng = cli.container_engine
190 | if eng:
191 | logger.info("Using specified container engine: %s", eng)
192 | return eng
193 | if _DISCOVERED_CONTAINER_ENGINES:
194 | return _DISCOVERED_CONTAINER_ENGINES[0]
195 | podman = shutil.which("podman")
196 | if podman:
197 | _DISCOVERED_CONTAINER_ENGINES.append(podman)
198 | docker = shutil.which("docker")
199 | if docker:
200 | _DISCOVERED_CONTAINER_ENGINES.append(docker)
201 | return _DISCOVERED_CONTAINER_ENGINES[0]
202 |
203 |
204 | def container_build(cli, target):
205 | """Construct and execute a command to build the target container image."""
206 | eng = container_engine(cli)
207 | tasks = []
208 |
209 | # For docker cross-builds we need to use buildx
210 | if "docker" in eng and target.arch != host_arch():
211 | args = [eng, "buildx"]
212 |
213 | # Docker's default builder only supports the host architecture.
214 | # Therefore, we need to create a new builder to support other
215 | # architectures, and we must ensure we start with a fresh builder
216 | # that does not contain any images from previous builds.
217 | tasks.append(
218 | lambda: run(cli, args + ["rm", target.flat_name()], check=False)
219 | )
220 | tasks.append(
221 | lambda: run(
222 | cli,
223 | args + ["create", f"--name={target.flat_name()}"],
224 | check=True,
225 | )
226 | )
227 |
228 | tasks.append(
229 | lambda: run(
230 | cli,
231 | args
232 | + [
233 | "build",
234 | f"--builder={target.flat_name()}",
235 | f"--platform=linux/{target.arch}",
236 | "--load",
237 | ]
238 | + create_common_container_engine_args(cli, target),
239 | check=True,
240 | )
241 | )
242 |
243 | tasks.append(
244 | lambda: run(cli, args + ["rm", target.flat_name()], check=True)
245 | )
246 | else:
247 | args = [eng, "build"]
248 | if target.arch != host_arch() or FORCE_ARCH_FLAG:
249 | # We've noticed a few small quirks when using podman with the --arch
250 | # option. The main issue is that building the client image works
251 | # but then the toolbox image fails because it somehow doesn't see
252 | # the image we just built as usable. This doesn't happen when
253 | # --arch is not provided. So if the target arch and the host_arch
254 | # are the same, skip passing the extra argument.
255 | args += [f"--arch={target.arch}"]
256 |
257 | tasks.append(
258 | lambda: run(
259 | cli,
260 | args + create_common_container_engine_args(cli, target),
261 | check=True,
262 | )
263 | )
264 |
265 | for task in tasks:
266 | task()
267 |
268 |
269 | def create_common_container_engine_args(cli, target):
270 | args = []
271 | pkgs_from = PACKAGES_FROM[target.pkg_source]
272 | if pkgs_from:
273 | args.append(f"--build-arg=INSTALL_PACKAGES_FROM={pkgs_from}")
274 | if target.pkg_source != DEFAULT:
275 | # consuming a recent samba with new specifics flag for mutex helper
276 | args.append(
277 | "--build-arg=SAMBA_SPECIFICS="
278 | "daemon_cli_debug_output,"
279 | "ctdb_leader_admin_command,"
280 | "ctdb_rados_mutex_skip_reg"
281 | )
282 |
283 | if cli.extra_build_arg:
284 | args.extend(cli.extra_build_arg)
285 |
286 | for tname in target.all_names(baseless=cli.without_repo_bases):
287 | args.append("-t")
288 | args.append(tname)
289 |
290 | args.append("-f")
291 | args.append(target_containerfile(target))
292 | args.append(kind_source_dir(target.name))
293 | return [str(a) for a in args]
294 |
295 |
296 | def container_push(cli, push_name):
297 | """Construct and execute a command to push a container image."""
298 | args = [container_engine(cli), "push", push_name]
299 | run(cli, args, check=True)
300 |
301 |
302 | def container_id(cli, target):
303 | """Construct and run a command to fetch a hexidecimal id for a container
304 | image.
305 | """
306 | args = [
307 | container_engine(cli),
308 | "inspect",
309 | "-f",
310 | "{{.Id}}",
311 | target.image_name(),
312 | ]
313 | res = run(cli, args, capture_output=True, check=True)
314 | return res.stdout.decode("utf8").strip()
315 |
316 |
317 | def container_tag(cli, target, tag, *tags):
318 | """Add additional tags to the existing target image."""
319 | if isinstance(target, str):
320 | src = target # permit target to be a string w/ the desired source
321 | else:
322 | src = target.image_name()
323 | base_args = [
324 | container_engine(cli),
325 | "tag",
326 | src,
327 | ]
328 | if "docker" not in base_args[0]:
329 | # podman can do it in one command, docker (on github ci) can not
330 | args = base_args + [tag] + list(tags)
331 | run(cli, args, check=True)
332 | return
333 | for new_tag in [tag] + list(tags):
334 | run(cli, base_args + [new_tag], check=True)
335 |
336 |
337 | def kind_source_dir(kind):
338 | """Return the path to a kind's source directory."""
339 | return pathlib.Path("images") / SOURCE_DIRS[check_kind(kind)]
340 |
341 |
342 | def target_containerfile(target):
343 | """Return the path to a containerfile given an image target."""
344 | return str(
345 | kind_source_dir(target.name) / f"Containerfile.{target.distro}"
346 | )
347 |
348 |
349 | def host_arch():
350 | """Return the name of the host's native architecture."""
351 | return check_arch(platform.machine().lower())
352 |
353 |
354 | def default_arches():
355 | """Return a list of the default architectures to use for building."""
356 | return [host_arch()]
357 |
358 |
359 | class RepoConfig:
360 | def __init__(self, default_repo_base, distro_repo=None):
361 | self.default = default_repo_base
362 | self.distro_map = dict(distro_repo or [])
363 |
364 | def find_base(self, distro):
365 | return self.distro_map.get(distro, self.default)
366 |
367 |
368 | class TargetImage:
369 | def __init__(
370 | self, name, pkg_source, distro, arch, extra_tag="", *, repo_base=""
371 | ):
372 | self.name = name
373 | self.pkg_source = pkg_source
374 | self.distro = distro
375 | self.arch = arch
376 | self.extra_tag = extra_tag
377 | self.repo_base = repo_base
378 | self.additional_tags = []
379 |
380 | def tag_name(self):
381 | tag_parts = [self.pkg_source, self.distro, self.arch]
382 | if self.extra_tag:
383 | tag_parts.append(self.extra_tag)
384 | tag = "-".join(tag_parts)
385 | return tag
386 |
387 | def image_name(self, *, tag=None, repo_base=None):
388 | if not tag:
389 | tag = self.tag_name()
390 | image_name = f"{self.name}:{tag}"
391 | repo_base = repo_base if repo_base is not None else self.repo_base
392 | if repo_base:
393 | repo_base = repo_base.rstrip("/")
394 | image_name = f"{repo_base}/{image_name}"
395 | return image_name
396 |
397 | def flat_name(self):
398 | return f"{self.name}.{self.tag_name()}"
399 |
400 | def __str__(self):
401 | return self.image_name()
402 |
403 | def all_names(self, baseless=False):
404 | yield self.image_name()
405 | for tag, _ in self.additional_tags:
406 | yield self.image_name(tag=tag)
407 | if self.repo_base and baseless:
408 | yield self.image_name(repo_base="")
409 | for tag, qual in self.additional_tags:
410 | if qual == QUAL_NONE:
411 | continue
412 | yield self.image_name(tag=tag, repo_base="")
413 |
414 | @classmethod
415 | def parse(cls, image_name):
416 | if "/" in image_name:
417 | base, rest = image_name.rsplit("/", 1)
418 | else:
419 | base = ""
420 | rest = image_name
421 | iname, tag = rest.split(":", 1)
422 | tparts = tag.split("-", 3)
423 | if len(tparts) < 3:
424 | raise ValueError(f"too few tag components: {tag!r}")
425 | return cls(
426 | iname,
427 | check_pkg_source(tparts[0]),
428 | check_distro(tparts[1]),
429 | check_arch(tparts[2]),
430 | extra_tag=(tparts[3] if len(tparts) > 3 else ""),
431 | repo_base=base,
432 | )
433 |
434 |
435 | def generate_images(cli):
436 | """Given full image names or a matrix of kind/pkg_source/distro_base/arch
437 | values generate a list of target images to build/process.
438 | """
439 | images = {}
440 | for img in cli.image or []:
441 | images[str(img)] = img
442 | rc = RepoConfig(cli.repo_base, cli.repo_base_for)
443 | for kind in cli.kind or []:
444 | for pkg_source in cli.package_source or DEFAULT_PKG_SOURCES:
445 | for distro_base in cli.distro_base or DEFAULT_DISTRO_BASES:
446 | for arch in cli.arch or default_arches():
447 | timg = TargetImage(
448 | kind,
449 | pkg_source,
450 | distro_base,
451 | arch,
452 | extra_tag=(cli.extra_tag or ""),
453 | repo_base=rc.find_base(distro_base),
454 | )
455 | images[str(timg)] = timg
456 | return list(images.values())
457 |
458 |
459 | def add_special_tags(img, distro_qualified=True):
460 | """Certain images have special tags. Given an image, add general (non-FQIN)
461 | tags to that image.
462 | """
463 | # Most of the policy (as opposed to mechanism) resides here where we decide
464 | # that certain images deserve some extra special tags. Mostly this serves
465 | # to keep us compatible with older tagging schemes from earlier versions of
466 | # the project.
467 | if img.distro in [FEDORA, OPENSUSE]:
468 | if img.arch == host_arch() and img.pkg_source == DEFAULT:
469 | img.additional_tags.append((LATEST, QUAL_NONE))
470 | if img.arch == host_arch() and img.pkg_source == NIGHTLY:
471 | img.additional_tags.append((NIGHTLY, QUAL_NONE))
472 | if not distro_qualified:
473 | return # skip creating "distro qualified" tags
474 | if img.arch == host_arch() and img.pkg_source == "default":
475 | img.additional_tags.append((f"{img.distro}-{LATEST}", QUAL_DISTRO))
476 | if img.arch == host_arch() and img.pkg_source == "nightly":
477 | img.additional_tags.append((f"{img.distro}-{NIGHTLY}", QUAL_DISTRO))
478 |
479 |
480 | def build(cli, target):
481 | """Command to build images."""
482 | build_file = pathlib.Path(f"{cli.buildfile_prefix}{target.flat_name()}")
483 | common_src = "./images/common"
484 | common_dst = str(kind_source_dir(target.name) / ".common")
485 | logger.debug("Copying common tree: %r -> %r", common_src, common_dst)
486 | shutil.copytree(common_src, common_dst, dirs_exist_ok=True)
487 | container_build(cli, target)
488 | cid = container_id(cli, target)
489 | with open(build_file, "w") as fh:
490 | fh.write(f"{cid} {target.image_name()}\n")
491 |
492 |
493 | class QMatcher:
494 | """Push only tags that meet the specified criteria:
495 | all - all tags;
496 | unqualified - only unqualified tags (eg. latest);
497 | distro - only distribution base qualifed tags (eg. fedora-latest);
498 | fqin - only fully qualified tags (eg. default-centos-amd64);
499 | mixed - only fqin and unqualified tags;
500 | least-qualified (default) - exactly one tag, with the least
501 | number of qualifications
502 | """
503 |
504 | def __init__(self, key):
505 | self.qualifications = []
506 | self.count = 0
507 | self.max_matches = 0
508 |
509 | if not key or key == "least-qualified":
510 | self.qualifications = [QUAL_NONE, QUAL_DISTRO, QUAL_FQIN]
511 | self.max_matches = 1
512 | elif key == "all":
513 | pass
514 | elif key == "mixed":
515 | self.qualifications = [QUAL_NONE, QUAL_FQIN]
516 | else:
517 | try:
518 | mq = {
519 | "unqualified": QUAL_NONE,
520 | "distro": QUAL_DISTRO,
521 | "fqin": QUAL_FQIN,
522 | }[key]
523 | except KeyError:
524 | raise argparse.ArgumentTypeError(
525 | "value must be one of:"
526 | " all, least-qualified, unqualified, distro, fqin;"
527 | f" not {key}"
528 | )
529 | self.qualifications = [mq]
530 |
531 | def __call__(self, qv):
532 | if self.max_matches and self.count >= self.max_matches:
533 | return False
534 | if not self.qualifications or qv in self.qualifications:
535 | self.count += 1
536 | return True
537 | return False
538 |
539 |
540 | def push(cli, target):
541 | """Command to push images."""
542 | if cli.push_state == "rebuild":
543 | build(cli, target)
544 | if cli.push_state == "exists":
545 | try:
546 | container_id(cli, target)
547 | except subprocess.CalledProcessError:
548 | build(cli, target)
549 |
550 | to_push = []
551 | push_name = target.image_name()
552 | for tag, qual in target.additional_tags:
553 | if tag in ("latest", "nightly"):
554 | to_push.append((target.image_name(tag=tag), qual))
555 | if tag.endswith(("-latest", "-nightly")):
556 | to_push.append((target.image_name(tag=tag), qual))
557 | to_push.append((push_name, QUAL_FQIN))
558 | qmatcher = cli.push_selected_tags or QMatcher("")
559 | for push_name, tag_qual in to_push:
560 | if qmatcher(tag_qual):
561 | container_push(cli, push_name)
562 |
563 |
564 | def retag(cli, target):
565 | """Command to regenerate any missing unqualified tags."""
566 | cid = container_id(cli, target)
567 | tags = []
568 | if cli.repo_base and target.repo_base != cli.repo_base:
569 | # if repo base is given on the cli, and differs from the
570 | # target, regenerate tags with the new distro base.
571 | # retag list
572 | target.repo_base = cli.repo_base
573 | # Ensure the new FQIN is part of the new tags list
574 | tags.append(target.image_name())
575 | tags += [target.image_name(tag=t) for t, _ in target.additional_tags]
576 | if tags:
577 | container_tag(cli, cid, *tags)
578 | else:
579 | logger.warning("no tags to add")
580 |
581 |
582 | def print_buildfile(cli, target):
583 | """Command to print build file names."""
584 | build_file = pathlib.Path(f"{cli.buildfile_prefix}{target.flat_name()}")
585 | print(build_file)
586 |
587 |
588 | def print_image(_, target):
589 | """Command to print (fqin) image names."""
590 | print(str(target))
591 |
592 |
593 | def print_tags(cli, target):
594 | """Command to print fqin image and additinal tag names."""
595 | for idx, name in enumerate(
596 | target.all_names(baseless=cli.without_repo_bases)
597 | ):
598 | prefix = "" if idx == 0 else " "
599 | print(f"{prefix}{name}")
600 |
601 |
602 | def main():
603 | parser = argparse.ArgumentParser()
604 | parser.add_argument(
605 | "--verbose",
606 | dest="log_level",
607 | action="store_const",
608 | const=logging.INFO,
609 | default=logging.WARNING,
610 | help="Emit verbose output",
611 | )
612 | parser.add_argument(
613 | "--debug",
614 | dest="log_level",
615 | action="store_const",
616 | const=logging.DEBUG,
617 | default=logging.WARNING,
618 | help="Emit debug level output",
619 | )
620 | parser.add_argument(
621 | "--repo-base",
622 | "-R",
623 | help=(
624 | "Common container registry repository base"
625 | " (eg. quay.io/samba.org)"
626 | ),
627 | )
628 | parser.add_argument(
629 | "--image",
630 | "-i",
631 | type=TargetImage.parse,
632 | action="append",
633 | help="Build precisely the named image (requires a FQIN)",
634 | )
635 | parser.add_argument(
636 | "--kind",
637 | "-k",
638 | type=check_kind,
639 | action="append",
640 | help="The kind of container to build (server, ad-server, etc...)",
641 | )
642 | parser.add_argument(
643 | "--distro-base",
644 | "-d",
645 | type=check_distro,
646 | action="append",
647 | help="The name of the base OS distribution to use.",
648 | )
649 | parser.add_argument(
650 | "--repo-base-for",
651 | "-F",
652 | type=check_repo_base_for,
653 | action="append",
654 | help=(
655 | "Assign a custom repo base given a distro base"
656 | "(like: --repo-base-for=centos=wonky.io/smb)"
657 | ),
658 | )
659 | parser.add_argument(
660 | "--arch",
661 | "-a",
662 | type=check_arch,
663 | action="append",
664 | help="The name of the CPU architecture to build for",
665 | )
666 | parser.add_argument(
667 | "--package-source",
668 | "-p",
669 | type=check_pkg_source,
670 | action="append",
671 | help="Source of Samba packages to use",
672 | )
673 | parser.add_argument(
674 | "--container-engine",
675 | help=(
676 | "Expliclty specify the path to the container engine"
677 | " (docker, podman, ...) to use"
678 | ),
679 | )
680 | parser.add_argument(
681 | "--extra-tag",
682 | help="Specify an extra tag extension. Handy for developers.",
683 | )
684 | parser.add_argument(
685 | "--dry-run", action="store_true", help="Do not run build commands"
686 | )
687 | parser.add_argument(
688 | "--push-state",
689 | choices=("exists", "rebuild"),
690 | default="exists",
691 | help=(
692 | "Only push if a state is met:"
693 | "exists - image exists; rebuild - image must be rebuilt."
694 | ),
695 | )
696 | parser.add_argument(
697 | "--push-selected-tags",
698 | type=QMatcher,
699 | help=QMatcher.__doc__,
700 | )
701 | parser.add_argument(
702 | "--buildfile-prefix",
703 | default=".build.",
704 | help="Specify prefix for build status files",
705 | )
706 | parser.add_argument(
707 | "--extra-build-arg",
708 | "-x",
709 | action="append",
710 | help="Extra argument to pass to container build command",
711 | )
712 | parser.add_argument(
713 | "--without-repo-bases",
714 | "-w",
715 | action="store_true",
716 | help=(
717 | "If an image has a repo base, also generate image names"
718 | " without the repo base"
719 | ),
720 | )
721 | parser.add_argument(
722 | "--distro-qualified",
723 | action=argparse.BooleanOptionalAction,
724 | default=True,
725 | help=(
726 | "Specify if image tags like fedora-nightly or centos-latest"
727 | " will be created."
728 | ),
729 | )
730 | behaviors = parser.add_mutually_exclusive_group()
731 | behaviors.add_argument(
732 | "--push",
733 | action="store_const",
734 | dest="main_action",
735 | const=push,
736 | help="Push images",
737 | )
738 | behaviors.add_argument(
739 | "--print",
740 | action="store_const",
741 | dest="main_action",
742 | const=print_image,
743 | help="Print the image names selected",
744 | )
745 | behaviors.add_argument(
746 | "--print-tags",
747 | action="store_const",
748 | dest="main_action",
749 | const=print_tags,
750 | help="Print the image and additional tags selected",
751 | )
752 | behaviors.add_argument(
753 | "--print-buildfile",
754 | action="store_const",
755 | dest="main_action",
756 | const=print_buildfile,
757 | help="Print the names of build status files",
758 | )
759 | behaviors.add_argument(
760 | "--retag",
761 | action="store_const",
762 | dest="main_action",
763 | const=retag,
764 | help=(
765 | "Regenerate any short (unqualified) tags expected to exist"
766 | " for a given FQIN. Requires FQIN to already exist locally."
767 | ),
768 | )
769 | cli = parser.parse_args()
770 |
771 | if os.environ.get("BUILD_IMAGE_DEBUG") in ("1", "yes"):
772 | cli.log_level = logging.DEBUG
773 | logging.basicConfig(level=cli.log_level)
774 |
775 | _action = cli.main_action if cli.main_action else build
776 | imgs = []
777 | try:
778 | imgs = generate_images(cli)
779 | for img in imgs:
780 | add_special_tags(img, cli.distro_qualified)
781 | logger.info("Image %s, extra tags: %s", img, img.additional_tags)
782 | _action(cli, img)
783 | except subprocess.CalledProcessError as err:
784 | logger.error("Failed command: %s", _cmd_to_str(err.cmd))
785 | sys.exit(err.returncode)
786 | if not imgs:
787 | logger.error("No images or image kinds supplied")
788 | sys.exit(2)
789 |
790 |
791 | if __name__ == "__main__":
792 | main()
793 |
--------------------------------------------------------------------------------
/hack/install-tools.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # helper script to install build auxiliary tools in local directory
3 | #
4 | # usage:
5 | # install-tools.sh --
6 | #
7 | #
8 | set -e
9 |
10 | _ensure_alt_bin() {
11 | mkdir -p "${ALT_BIN}"
12 | }
13 |
14 | _require_py() {
15 | if [ -z "$PY_CMD" ]; then
16 | echo "error: python3 command required, but not found" >&2
17 | echo "(set PY_CMD to specify python command)" >&2
18 | exit 5
19 | fi
20 | }
21 |
22 | _install_yamllint() {
23 | _require_py
24 | _ensure_alt_bin
25 | "${PY_CMD}" -m venv "${ALT_BIN}/.py"
26 | "${ALT_BIN}/.py/bin/pip" install "yamllint"
27 | installed_to="${ALT_BIN}/yamllint"
28 | ln -s "${ALT_BIN}/.py/bin/yamllint" "${installed_to}"
29 | }
30 |
31 | _install_gitlint() {
32 | _require_py
33 | _ensure_alt_bin
34 | "${PY_CMD}" -m venv "${ALT_BIN}/.py"
35 | "${ALT_BIN}/.py/bin/pip" install "gitlint==${GITLINT_VER}"
36 | installed_to="${ALT_BIN}/gitlint"
37 | ln -s "${ALT_BIN}/.py/bin/gitlint" "${installed_to}"
38 | }
39 |
40 | _install_shellcheck() {
41 | installed_to="${ALT_BIN}/shellcheck"
42 | local url="https://github.com/koalaman/shellcheck/releases/download/${SHELLCHECK_VER}/shellcheck-${SHELLCHECK_VER}.linux.x86_64.tar.xz"
43 | tmpdir="$(mktemp -d)"
44 | _ensure_alt_bin
45 | curl -Lo "${tmpdir}/shellcheck.tar.xz" "$url"
46 | mkdir "${tmpdir}/shellcheck"
47 | tar -xf "${tmpdir}/shellcheck.tar.xz" -C "${tmpdir}/shellcheck"
48 | mkdir -p ~/bin
49 | install -m0755 "${tmpdir}/shellcheck/shellcheck-${SHELLCHECK_VER}/shellcheck" "${installed_to}"
50 | rm -rf "${tmpdir}"
51 | }
52 |
53 |
54 | GITLINT_VER="0.19.1"
55 | SHELLCHECK_VER="v0.8.0"
56 |
57 |
58 | if [ -z "$PY_CMD" ]; then
59 | if ! PY_CMD="$(command -v python3)"; then
60 | echo "warning: failed to find python3 command" >&2
61 | fi
62 | fi
63 |
64 | ALT_BIN="${2:-.bin}"
65 | case "$1" in
66 | "--yamllint")
67 | if command -v "${ALT_BIN}/yamllint" 2>/dev/null; then
68 | exit 0
69 | fi
70 | _install_yamllint 1>&2
71 | echo "${installed_to}"
72 | ;;
73 | "--gitlint")
74 | if command -v "${ALT_BIN}/gitlint" 2>/dev/null; then
75 | exit 0
76 | fi
77 | _install_gitlint 1>&2
78 | echo "${installed_to}"
79 | ;;
80 | "--shellcheck")
81 | if command -v "${ALT_BIN}/shellcheck" 2>/dev/null; then
82 | exit 0
83 | fi
84 | _install_shellcheck 1>&2
85 | echo "${installed_to}"
86 | ;;
87 | *)
88 | echo "usage: $0 -- []"
89 | echo ""
90 | echo "available tools:"
91 | echo " --gitlint"
92 | echo " --yamllint"
93 | echo " --shellcheck"
94 | ;;
95 | esac
96 |
--------------------------------------------------------------------------------
/hack/release-gen-download-section.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # Requires `skopeo` and `jq` to be installed.
3 |
4 | set -e
5 |
6 | sk_digest() {
7 | skopeo inspect "docker://${1}" | jq -r .Digest
8 | }
9 |
10 | image_info() {
11 | curr_img="quay.io/samba.org/${1}:${2}"
12 | digest=$(sk_digest "${curr_img}")
13 | # strip preN from tag name
14 | final_tag=${2/%pre[0-9]*/}
15 | tag_img="quay.io/samba.org/${1}:${final_tag}"
16 | dst_img="quay.io/samba.org/${1}@${digest}"
17 |
18 | echo "### $1"
19 | echo "* By tag: $tag_img"
20 | echo "* By digest: $dst_img"
21 | echo ""
22 | }
23 |
24 | wip_tag=$1
25 | if [ -z "${wip_tag}" ] ; then
26 | echo "No tag provided!" >&2
27 | exit 1
28 | fi
29 |
30 | echo "## Downloads"
31 | echo ""
32 | echo "Images built for this release can be acquired from the quay.io image registry."
33 | echo ""
34 | for component in samba-server samba-ad-server samba-client samba-toolbox; do
35 | image_info "${component}" "${wip_tag}"
36 | done
37 |
38 |
--------------------------------------------------------------------------------
/images/ad-server/Containerfile.centos:
--------------------------------------------------------------------------------
1 | FROM quay.io/centos/centos:stream9
2 | ARG INSTALL_PACKAGES_FROM=default
3 | ARG SAMBA_VERSION_SUFFIX=""
4 | ARG SAMBACC_VERSION_SUFFIX=""
5 | ARG SAMBA_SPECIFICS=daemon_cli_debug_output
6 | ARG INSTALL_CUSTOM_REPO=
7 |
8 | MAINTAINER John Mulligan
9 |
10 | LABEL org.opencontainers.image.title="Samba ADDC container"
11 | LABEL org.opencontainers.image.description="Samba ADDC container"
12 | LABEL org.opencontainers.image.vendor="Samba in Kubernetes"
13 |
14 | COPY install-packages.sh /usr/local/bin/install-packages.sh
15 | RUN /usr/local/bin/install-packages.sh \
16 | "${INSTALL_PACKAGES_FROM}" \
17 | "${SAMBA_VERSION_SUFFIX}" \
18 | "${INSTALL_CUSTOM_REPO}"
19 |
20 | # If you want to install a custom version of sambacc into this image mount
21 | # a directory containing a sambacc RPM, or a sambacc wheel, or a .repo
22 | # file at /tmp/sambacc-dist-latest
23 | # If the directory is empty the script automatically falls back to using
24 | # the latest continuously built RPM from our sambacc COPR:
25 | # https://copr.fedorainfracloud.org/coprs/phlogistonjohn/sambacc
26 | COPY .common/install-sambacc-common.sh /usr/local/bin/install-sambacc-common.sh
27 | COPY install-sambacc.sh /usr/local/bin/install-sambacc.sh
28 | RUN /usr/local/bin/install-sambacc.sh \
29 | "/tmp/sambacc-dist-latest" \
30 | "${SAMBACC_VERSION_SUFFIX}"
31 |
32 |
33 | ENV SAMBACC_CONFIG="/etc/samba/container.json:/etc/samba/users.json"
34 | ENV SAMBA_CONTAINER_ID="demo"
35 | ENV SAMBA_SPECIFICS="$SAMBA_SPECIFICS"
36 | ENTRYPOINT ["samba-dc-container"]
37 | CMD ["run", "--setup=provision", "--setup=populate"]
38 |
39 | # vim:set syntax=dockerfile:
40 |
--------------------------------------------------------------------------------
/images/ad-server/Containerfile.fedora:
--------------------------------------------------------------------------------
1 | FROM registry.fedoraproject.org/fedora:41
2 | ARG INSTALL_PACKAGES_FROM=default
3 | ARG SAMBA_VERSION_SUFFIX=""
4 | ARG SAMBACC_VERSION_SUFFIX=""
5 | ARG SAMBA_SPECIFICS=daemon_cli_debug_output
6 | ARG INSTALL_CUSTOM_REPO=
7 |
8 | MAINTAINER John Mulligan
9 |
10 | LABEL org.opencontainers.image.title="Samba ADDC container"
11 | LABEL org.opencontainers.image.description="Samba ADDC container"
12 | LABEL org.opencontainers.image.vendor="Samba in Kubernetes"
13 |
14 | COPY install-packages.sh /usr/local/bin/install-packages.sh
15 | RUN /usr/local/bin/install-packages.sh \
16 | "${INSTALL_PACKAGES_FROM}" \
17 | "${SAMBA_VERSION_SUFFIX}" \
18 | "${INSTALL_CUSTOM_REPO}"
19 |
20 | # If you want to install a custom version of sambacc into this image mount
21 | # a directory containing a sambacc RPM, or a sambacc wheel, or a .repo
22 | # file at /tmp/sambacc-dist-latest
23 | # If the directory is empty the script automatically falls back to using
24 | # the latest continuously built RPM from our sambacc COPR:
25 | # https://copr.fedorainfracloud.org/coprs/phlogistonjohn/sambacc
26 | COPY .common/install-sambacc-common.sh /usr/local/bin/install-sambacc-common.sh
27 | COPY install-sambacc.sh /usr/local/bin/install-sambacc.sh
28 | RUN /usr/local/bin/install-sambacc.sh \
29 | "/tmp/sambacc-dist-latest" \
30 | "${SAMBACC_VERSION_SUFFIX}"
31 |
32 |
33 | ENV SAMBACC_CONFIG="/etc/samba/container.json:/etc/samba/users.json"
34 | ENV SAMBA_CONTAINER_ID="demo"
35 | ENV SAMBA_SPECIFICS="$SAMBA_SPECIFICS"
36 | ENTRYPOINT ["samba-dc-container"]
37 | CMD ["run", "--setup=provision", "--setup=populate"]
38 |
39 | # vim:set syntax=dockerfile:
40 |
--------------------------------------------------------------------------------
/images/ad-server/Containerfile.opensuse:
--------------------------------------------------------------------------------
1 | # Defines the tag for OBS and build script builds:
2 | #!BuildTag: opensuse/samba-ad-server:latest
3 | #!BuildTag: opensuse/samba-ad-server:%%MINOR%%
4 | #!BuildTag: opensuse/samba-ad-server:%%PKG_VERSION%%
5 | #!BuildTag: opensuse/samba-ad-server:%%PKG_VERSION%%-%RELEASE%
6 |
7 | # OBS doesn't allow a fully qualified image registry name for the offline build
8 | FROM opensuse/tumbleweed
9 | ARG SAMBA_SPECIFICS=daemon_cli_debug_output
10 |
11 | MAINTAINER David Mulder
12 |
13 | # labelprefix=org.opensuse.samba-ad-server
14 | LABEL org.opencontainers.image.title="Samba ADDC container"
15 | LABEL org.opencontainers.image.description="Samba ADDC container"
16 | LABEL org.opencontainers.image.created="%BUILDTIME%"
17 | LABEL org.opencontainers.image.version="%%PKG_VERSION%%-%RELEASE%"
18 | LABEL org.opencontainers.image.vendor="Samba in Kubernetes"
19 | LABEL org.openbuildservice.disturl="%DISTURL%"
20 | LABEL org.opensuse.reference="registry.opensuse.org/opensuse/samba-ad-server:%%PKG_VERSION%%-%RELEASE%"
21 | # endlabelprefix
22 |
23 | RUN zypper --non-interactive install --no-recommends \
24 | findutils \
25 | python3-pip \
26 | python3-jsonschema \
27 | samba-python3 \
28 | python3-pyxattr \
29 | tdb-tools \
30 | samba-ad-dc \
31 | procps \
32 | samba-client \
33 | samba-winbind \
34 | python3-dnspython \
35 | krb5-server \
36 | sambacc && \
37 | zypper clean;
38 | RUN ln -sf /usr/share/sambacc/examples/addc.json /etc/samba/container.json
39 | RUN rm -rf /etc/samba/smb.conf
40 | RUN cp /usr/etc/nsswitch.conf /etc/nsswitch.conf
41 |
42 |
43 | ENV SAMBACC_CONFIG="/etc/samba/container.json:/etc/samba/users.json"
44 | ENV SAMBA_CONTAINER_ID="demo"
45 | ENV SAMBA_SPECIFICS="$SAMBA_SPECIFICS"
46 | ENTRYPOINT ["samba-dc-container"]
47 | CMD ["run", "--setup=provision", "--setup=populate"]
48 |
49 | # vim:set syntax=dockerfile:
50 |
--------------------------------------------------------------------------------
/images/ad-server/install-packages.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -ex
4 |
5 | get_custom_repo() {
6 | url="$1"
7 | fname="$(basename "$url")"
8 | dest="/etc/yum.repos.d/${fname}"
9 | dnf install --setopt=install_weak_deps=False -y /usr/bin/curl
10 | curl -L "$url" -o "$dest"
11 | }
12 |
13 | install_packages_from="$1"
14 | samba_version_suffix="$2"
15 | install_custom_repo="$3"
16 | # reserve package_selection. keep args consistent with server image script.
17 | # unused for ad image (for now)
18 | # package_selection="$4"
19 |
20 | # shellcheck disable=SC1091
21 | OS_BASE="$(. /etc/os-release && echo "${ID}")"
22 |
23 | case "${install_packages_from}" in
24 | samba-nightly)
25 | get_custom_repo "https://artifacts.ci.centos.org/samba/pkgs/master/${OS_BASE}/samba-nightly-master.repo"
26 | ;;
27 | custom-repo)
28 | get_custom_repo "${install_custom_repo}"
29 | ;;
30 | esac
31 |
32 |
33 | # Assorted packages that must be installed in the container image to
34 | # support the functioning of the container
35 | support_packages=(\
36 | findutils \
37 | python-pip \
38 | python3-samba \
39 | python3-pyxattr \
40 | tdb-tools \
41 | procps-ng \
42 | /usr/bin/smbclient)
43 | # Packages belonging to the samba install. If a samba_version_suffix is given
44 | # all the samba_packages must share that version
45 | samba_packages=(samba-dc)
46 |
47 | # Assign version suffix to samba packages
48 | samba_versioned_packages=()
49 | for p in "${samba_packages[@]}"; do
50 | samba_versioned_packages+=("${p}${samba_version_suffix}")
51 | done
52 |
53 | dnf_cmd=(dnf)
54 | if [[ "${OS_BASE}" = centos ]]; then
55 | dnf install -y epel-next-release
56 | dnf_cmd+=(--enablerepo=crb)
57 | fi
58 |
59 | "${dnf_cmd[@]}" \
60 | install --setopt=install_weak_deps=False -y \
61 | "${support_packages[@]}" \
62 | "${samba_versioned_packages[@]}"
63 | dnf clean all
64 |
65 | rm -rf /etc/samba/smb.conf
66 |
--------------------------------------------------------------------------------
/images/ad-server/install-sambacc.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -ex
4 |
5 | # shellcheck source=images/common/install-sambacc-common.sh
6 | . install-sambacc-common.sh
7 | export DEFAULT_JSON_FILE=addc.json
8 | install_sambacc "$@"
9 |
--------------------------------------------------------------------------------
/images/client/Containerfile.centos:
--------------------------------------------------------------------------------
1 | # Copyright 2020 Michael Adam
2 |
3 | FROM quay.io/centos/centos:stream9
4 |
5 | MAINTAINER Michael Adam
6 |
7 | LABEL org.opencontainers.image.title="Samba Client container"
8 | LABEL org.opencontainers.image.description="Samba Client container"
9 | LABEL org.opencontainers.image.vendor="Samba in Kubernetes"
10 | LABEL org.opencontainers.image.url="https://github.com/samba-in-kubernetes/samba-container"
11 |
12 |
13 | # https://github.com/samba-in-kubernetes/samba-container/issues/96#issuecomment-1387467396
14 | #
15 | # samba-common, when pulled in as a dependency for samba-client, has a preferred
16 | # requirement on systemd-standalone-tmpfiles(rather than systemd) but is meant
17 | # to conflict with systemd itself of same version or higher. We can avoid the
18 | # conflict by choosing to install systemd over systemd-standalone-tmpfiles.
19 | RUN dnf -y install samba-client systemd \
20 | && dnf clean all
21 |
--------------------------------------------------------------------------------
/images/client/Containerfile.fedora:
--------------------------------------------------------------------------------
1 | # Copyright 2020 Michael Adam
2 |
3 | FROM registry.fedoraproject.org/fedora:41
4 |
5 | MAINTAINER Michael Adam
6 |
7 | LABEL org.opencontainers.image.title="Samba Client container"
8 | LABEL org.opencontainers.image.description="Samba Client container"
9 | LABEL org.opencontainers.image.vendor="Samba in Kubernetes"
10 | LABEL org.opencontainers.image.url="https://github.com/samba-in-kubernetes/samba-container"
11 |
12 |
13 | # https://github.com/samba-in-kubernetes/samba-container/issues/96#issuecomment-1387467396
14 | #
15 | # samba-common, when pulled in as a dependency for samba-client, has a preferred
16 | # requirement on systemd-standalone-tmpfiles(rather than systemd) but is meant
17 | # to conflict with systemd itself of same version or higher. We can avoid the
18 | # conflict by choosing to install systemd over systemd-standalone-tmpfiles.
19 | RUN dnf -y install samba-client systemd \
20 | && dnf clean all
21 |
--------------------------------------------------------------------------------
/images/client/Containerfile.opensuse:
--------------------------------------------------------------------------------
1 | # Defines the tag for OBS and build script builds:
2 | #!BuildTag: opensuse/samba-client:latest
3 | #!BuildTag: opensuse/samba-client:%%MINOR%%
4 | #!BuildTag: opensuse/samba-client:%%PKG_VERSION%%
5 | #!BuildTag: opensuse/samba-client:%%PKG_VERSION%%-%RELEASE%
6 |
7 | # OBS doesn't allow a fully qualified image registry name for the offline build
8 | FROM opensuse/tumbleweed
9 | MAINTAINER David Mulder
10 |
11 | # labelprefix=org.opensuse.samba-client
12 | LABEL org.opencontainers.image.title="Samba Client container"
13 | LABEL org.opencontainers.image.description="Samba Client container"
14 | LABEL org.opencontainers.image.created="%BUILDTIME%"
15 | LABEL org.opencontainers.image.version="%%PKG_VERSION%%-%RELEASE%"
16 | LABEL org.opencontainers.image.vendor="Samba in Kubernetes"
17 | LABEL org.openbuildservice.disturl="%DISTURL%"
18 | LABEL org.opensuse.reference="registry.opensuse.org/opensuse/samba-client:%%PKG_VERSION%%-%RELEASE%"
19 | # endlabelprefix
20 |
21 | RUN zypper --non-interactive install --no-recommends samba-client && zypper clean
22 |
--------------------------------------------------------------------------------
/images/common/install-sambacc-common.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | install_sambacc() {
4 | local distdir="$1"
5 | local sambacc_version_suffix="$2"
6 | if ! [ -d "${distdir}" ]; then
7 | echo "warning: no directory: ${distdir}" >&2
8 | else
9 | mapfile -d '' artifacts < \
10 | <(find "${distdir}" -type f -print0)
11 | fi
12 |
13 | local wheels=()
14 | local rpmfiles=()
15 | local rpmextras=()
16 | local repofiles=()
17 | for artifact in "${artifacts[@]}" ; do
18 | if [[ ${artifact} =~ sambacc.*\.whl$ ]]; then
19 | wheels+=("${artifact}")
20 | fi
21 | if [[ ${artifact} =~ python.?-sambacc-.*\.noarch\.rpm$ ]]; then
22 | rpmfiles+=("${artifact}")
23 | fi
24 | if [[ ${artifact} =~ python.?-sambacc+.*\.noarch\.rpm$ ]]; then
25 | rpmextras+=("${artifact}")
26 | fi
27 | if [[ ${artifact} =~ sambacc.*\.repo$ ]]; then
28 | repofiles+=("${artifact}")
29 | fi
30 | done
31 |
32 |
33 | local action=""
34 | echo "INFO: determining sambacc installation source."
35 | if [ "${#wheels[@]}" -gt 0 ]; then
36 | echo "INFO: wheel found"
37 | if [ "${#wheels[@]}" -gt 1 ]; then
38 | echo "ERROR: more than one wheel file found"
39 | exit 1
40 | elif [ "${#wheels[@]}" -eq 1 ]; then
41 | action=install-wheel
42 | fi
43 | fi
44 | if [ "${#rpmfiles[@]}" -gt 0 ]; then
45 | echo "INFO: rpm file found"
46 | if [ "${#rpmfiles[@]}" -gt 1 ]; then
47 | echo "ERROR: more than one sambacc rpm file found"
48 | exit 1
49 | elif [ "${#rpmfiles[@]}" -eq 1 ]; then
50 | action=install-rpm
51 | fi
52 | fi
53 | if [ "${#repofiles[@]}" -gt 0 ]; then
54 | echo "INFO: repo file found"
55 | if [ "${#repofiles[@]}" -gt 1 ]; then
56 | echo "ERROR: more than one repo file found"
57 | exit 1
58 | elif [ "${#repofiles[@]}" -eq 1 ]; then
59 | action=install-from-repo
60 | fi
61 | fi
62 | if [ -z "${action}" ]; then
63 |
64 | echo "INFO: no local sambacc installation source found. falling back to copr install."
65 | action=install-from-copr-repo
66 | fi
67 |
68 | echo "INFO: selected installation method: '${action}'"
69 | if [ -z "${DEFAULT_JSON_FILE}" ]; then
70 | echo "DEFAULT_JSON_FILE value unset"
71 | exit 1
72 | fi
73 |
74 | case $action in
75 | install-wheel)
76 | pip install "${wheels[0]}"
77 | container_json_file="/usr/local/share/sambacc/examples/${DEFAULT_JSON_FILE}"
78 | ;;
79 | install-rpm)
80 | dnf install -y "${rpmfiles[0]}" "${rpmextras[@]}"
81 | dnf clean all
82 | container_json_file="/usr/share/sambacc/examples/${DEFAULT_JSON_FILE}"
83 | ;;
84 | install-from-repo)
85 | local tgt="${repofiles[0]}"
86 | cp "${tgt}" /etc/yum.repos.d/"$(basename "${tgt}")"
87 | dnf install -y "python3-sambacc${sambacc_version_suffix}"
88 | dnf clean all
89 | container_json_file="/usr/share/sambacc/examples/${DEFAULT_JSON_FILE}"
90 | ;;
91 | install-from-copr-repo)
92 | # shellcheck disable=SC1091
93 | OS_BASE="$(. /etc/os-release && echo "${ID}")"
94 | dnf install -y 'dnf-command(copr)'
95 |
96 | copr_args=("phlogistonjohn/sambacc")
97 | if [ "$OS_BASE" = centos ]; then
98 | # centos needs a little help determining what repository
99 | # within the copr to use. By default it only wants
100 | # to add `epel-9-$arch`.
101 | copr_args+=("centos-stream+epel-next-9-$(uname -p)")
102 | fi
103 | dnf copr enable -y "${copr_args[@]}"
104 | dnf install -y "python3-sambacc${sambacc_version_suffix}"
105 | dnf clean all
106 | container_json_file="/usr/share/sambacc/examples/${DEFAULT_JSON_FILE}"
107 | ;;
108 | *)
109 | echo "no install package(s) found"
110 | exit 1
111 | ;;
112 | esac
113 |
114 | if [ "$container_json_file" ]; then
115 | ln -sf "$container_json_file" /etc/samba/container.json
116 | fi
117 | }
118 |
--------------------------------------------------------------------------------
/images/server/Containerfile.centos:
--------------------------------------------------------------------------------
1 | FROM quay.io/centos/centos:stream9
2 | ARG INSTALL_PACKAGES_FROM=default
3 | ARG SAMBA_VERSION_SUFFIX=""
4 | ARG SAMBACC_VERSION_SUFFIX=""
5 | ARG SAMBA_SPECIFICS=daemon_cli_debug_output,ctdb_leader_admin_command
6 | ARG INSTALL_CUSTOM_REPO=
7 | ARG PACKAGE_SELECTION=
8 |
9 | MAINTAINER John Mulligan
10 |
11 | LABEL org.opencontainers.image.title="Samba container"
12 | LABEL org.opencontainers.image.description="Samba container"
13 | LABEL org.opencontainers.image.vendor="Samba in Kubernetes"
14 | LABEL org.opencontainers.image.url="https://github.com/samba-in-kubernetes/samba-container"
15 |
16 |
17 | COPY smb.conf /etc/samba/smb.conf
18 | COPY install-packages.sh /usr/local/bin/install-packages.sh
19 | RUN /usr/local/bin/install-packages.sh \
20 | "${INSTALL_PACKAGES_FROM}" \
21 | "${SAMBA_VERSION_SUFFIX}" \
22 | "${INSTALL_CUSTOM_REPO}" \
23 | "${PACKAGE_SELECTION}"
24 |
25 | # If you want to install a custom version of sambacc into this image mount
26 | # a directory containing a sambacc RPM, or a sambacc wheel, or a .repo
27 | # file at /tmp/sambacc-dist-latest
28 | # If the directory is empty the script automatically falls back to using
29 | # the latest continuously built RPM from our sambacc COPR:
30 | # https://copr.fedorainfracloud.org/coprs/phlogistonjohn/sambacc
31 | COPY .common/install-sambacc-common.sh /usr/local/bin/install-sambacc-common.sh
32 | COPY install-sambacc.sh /usr/local/bin/install-sambacc.sh
33 | RUN /usr/local/bin/install-sambacc.sh \
34 | "/tmp/sambacc-dist-latest" \
35 | "${SAMBACC_VERSION_SUFFIX}"
36 |
37 |
38 | VOLUME ["/share"]
39 |
40 | EXPOSE 445
41 |
42 | ENV SAMBACC_CONFIG="/etc/samba/container.json:/etc/samba/users.json"
43 | ENV SAMBA_CONTAINER_ID="demo"
44 | ENV SAMBA_SPECIFICS="$SAMBA_SPECIFICS"
45 | ENTRYPOINT ["samba-container"]
46 | CMD ["run", "smbd"]
47 |
48 | # vim:set syntax=dockerfile:
49 |
--------------------------------------------------------------------------------
/images/server/Containerfile.fedora:
--------------------------------------------------------------------------------
1 | FROM registry.fedoraproject.org/fedora:41
2 | ARG INSTALL_PACKAGES_FROM=default
3 | ARG SAMBA_VERSION_SUFFIX=""
4 | ARG SAMBACC_VERSION_SUFFIX=""
5 | ARG SAMBA_SPECIFICS=daemon_cli_debug_output,ctdb_leader_admin_command
6 | ARG INSTALL_CUSTOM_REPO=
7 | ARG PACKAGE_SELECTION=
8 |
9 | MAINTAINER John Mulligan
10 |
11 | LABEL org.opencontainers.image.title="Samba container"
12 | LABEL org.opencontainers.image.description="Samba container"
13 | LABEL org.opencontainers.image.vendor="Samba in Kubernetes"
14 | LABEL org.opencontainers.image.url="https://github.com/samba-in-kubernetes/samba-container"
15 |
16 | COPY smb.conf /etc/samba/smb.conf
17 | COPY install-packages.sh /usr/local/bin/install-packages.sh
18 | RUN /usr/local/bin/install-packages.sh \
19 | "${INSTALL_PACKAGES_FROM}" \
20 | "${SAMBA_VERSION_SUFFIX}" \
21 | "${INSTALL_CUSTOM_REPO}" \
22 | "${PACKAGE_SELECTION}"
23 |
24 | # If you want to install a custom version of sambacc into this image mount
25 | # a directory containing a sambacc RPM, or a sambacc wheel, or a .repo
26 | # file at /tmp/sambacc-dist-latest
27 | # If the directory is empty the script automatically falls back to using
28 | # the latest continuously built RPM from our sambacc COPR:
29 | # https://copr.fedorainfracloud.org/coprs/phlogistonjohn/sambacc
30 | COPY .common/install-sambacc-common.sh /usr/local/bin/install-sambacc-common.sh
31 | COPY install-sambacc.sh /usr/local/bin/install-sambacc.sh
32 | RUN /usr/local/bin/install-sambacc.sh \
33 | "/tmp/sambacc-dist-latest" \
34 | "${SAMBACC_VERSION_SUFFIX}"
35 |
36 |
37 | VOLUME ["/share"]
38 |
39 | EXPOSE 445
40 |
41 | ENV SAMBACC_CONFIG="/etc/samba/container.json:/etc/samba/users.json"
42 | ENV SAMBA_CONTAINER_ID="demo"
43 | ENV SAMBA_SPECIFICS="$SAMBA_SPECIFICS"
44 | ENTRYPOINT ["samba-container"]
45 | CMD ["run", "smbd"]
46 |
47 | # vim:set syntax=dockerfile:
48 |
--------------------------------------------------------------------------------
/images/server/Containerfile.opensuse:
--------------------------------------------------------------------------------
1 | # Defines the tag for OBS and build script builds:
2 | #!BuildTag: opensuse/samba-server:latest
3 | #!BuildTag: opensuse/samba-server:%%MINOR%%
4 | #!BuildTag: opensuse/samba-server:%%PKG_VERSION%%
5 | #!BuildTag: opensuse/samba-server:%%PKG_VERSION%%-%RELEASE%
6 |
7 | # OBS doesn't allow a fully qualified image registry name for the offline build
8 | FROM opensuse/tumbleweed
9 | ARG SAMBA_SPECIFICS=daemon_cli_debug_output,ctdb_leader_admin_command
10 |
11 | MAINTAINER David Mulder
12 |
13 | # labelprefix=org.opensuse.samba-server
14 | LABEL org.opencontainers.image.title="Samba container"
15 | LABEL org.opencontainers.image.description="Samba container"
16 | LABEL org.opencontainers.image.created="%BUILDTIME%"
17 | LABEL org.opencontainers.image.version="%%PKG_VERSION%%-%RELEASE%"
18 | LABEL org.opencontainers.image.vendor="Samba in Kubernetes"
19 | LABEL org.openbuildservice.disturl="%DISTURL%"
20 | LABEL org.opensuse.reference="registry.opensuse.org/opensuse/samba-server:%%PKG_VERSION%%-%RELEASE%"
21 | # endlabelprefix
22 |
23 | COPY smb.conf /etc/samba/smb.conf
24 | RUN zypper --non-interactive install --no-recommends \
25 | findutils \
26 | python3-pip \
27 | python3-jsonschema \
28 | samba-python3 \
29 | python3-pyxattr \
30 | samba \
31 | samba-winbind \
32 | tdb-tools \
33 | ctdb \
34 | glibc \
35 | sambacc && \
36 | zypper clean;
37 | RUN ln -sf /usr/share/sambacc/examples/minimal.json /etc/samba/container.json
38 | RUN cp /usr/etc/nsswitch.conf /etc/nsswitch.conf
39 |
40 |
41 |
42 |
43 | VOLUME ["/share"]
44 |
45 | EXPOSE 445
46 |
47 | ENV SAMBACC_CONFIG="/etc/samba/container.json:/etc/samba/users.json"
48 | ENV SAMBA_CONTAINER_ID="demo"
49 | ENV SAMBA_SPECIFICS="$SAMBA_SPECIFICS"
50 | ENTRYPOINT ["samba-container"]
51 | CMD ["run", "smbd"]
52 |
53 | # vim:set syntax=dockerfile:
54 |
--------------------------------------------------------------------------------
/images/server/install-packages.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -ex
4 |
5 |
6 | need_curl() {
7 | if command -v curl >/dev/null ; then
8 | return 0
9 | fi
10 | dnf install --setopt=install_weak_deps=False -y /usr/bin/curl
11 | }
12 |
13 | get_custom_repo() {
14 | url="$1"
15 | fname="$(basename "$url")"
16 | dest="/etc/yum.repos.d/${fname}"
17 | need_curl
18 | curl -L "$url" -o "$dest"
19 | }
20 |
21 | generate_repo_from_shaman() {
22 | url="$1"
23 | dest="/etc/yum.repos.d/$2"
24 | need_curl
25 | tmpfile=/tmp/shaman.json
26 | curl -L "$url" -o "${tmpfile}" && python3 <
8 |
9 | LABEL org.opencontainers.image.title="Samba Toolbox container"
10 | LABEL org.opencontainers.image.description="Samba Toolbox container"
11 | LABEL org.opencontainers.image.vendor="Samba in Kubernetes"
12 | LABEL org.opencontainers.image.url="https://github.com/samba-in-kubernetes/samba-container"
13 |
14 | RUN dnf install --enablerepo=crb -y \
15 | samba-test \
16 | tdb-tools \
17 | && dnf clean all
18 |
--------------------------------------------------------------------------------
/images/toolbox/Containerfile.fedora:
--------------------------------------------------------------------------------
1 | FROM quay.io/samba.org/samba-client:latest
2 | MAINTAINER Shachar Sharon
3 |
4 | LABEL org.opencontainers.image.title="Samba Toolbox container"
5 | LABEL org.opencontainers.image.description="Samba Toolbox container"
6 | LABEL org.opencontainers.image.vendor="Samba in Kubernetes"
7 | LABEL org.opencontainers.image.url="https://github.com/samba-in-kubernetes/samba-container"
8 |
9 |
10 | RUN dnf -y install samba-test \
11 | tdb-tools \
12 | && dnf clean all
13 |
--------------------------------------------------------------------------------
/images/toolbox/Containerfile.opensuse:
--------------------------------------------------------------------------------
1 | # Defines the tag for OBS and build script builds:
2 | #!BuildTag: opensuse/samba-toolbox:latest
3 | #!BuildTag: opensuse/samba-toolbox:%%MINOR%%
4 | #!BuildTag: opensuse/samba-toolbox:%%PKG_VERSION%%
5 | #!BuildTag: opensuse/samba-toolbox:%%PKG_VERSION%%-%RELEASE%
6 |
7 | # OBS doesn't allow a fully qualified image registry name for the offline build
8 | FROM opensuse/tumbleweed
9 | MAINTAINER David Mulder
10 |
11 | # labelprefix=org.opensuse.samba-toolbox
12 | LABEL org.opencontainers.image.title="Samba Toolbox container"
13 | LABEL org.opencontainers.image.description="Samba Toolbox container"
14 | LABEL org.opencontainers.image.created="%BUILDTIME%"
15 | LABEL org.opencontainers.image.version="%%PKG_VERSION%%-%RELEASE%"
16 | LABEL org.opencontainers.image.vendor="Samba in Kubernetes"
17 | LABEL org.openbuildservice.disturl="%DISTURL%"
18 | LABEL org.opensuse.reference="registry.opensuse.org/opensuse/samba-toolbox:%%PKG_VERSION%%-%RELEASE%"
19 | # endlabelprefix
20 |
21 | RUN zypper --non-interactive install --no-recommends samba-client samba-test tdb-tools && zypper clean
22 |
--------------------------------------------------------------------------------
/tests/common.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | SCRIPT_DIR="$(cd "$(dirname "${0}")" && pwd)"
4 |
5 | export AD_DEPLOYMENT_YAML="${SCRIPT_DIR}/files/samba-ad-server-deployment.yml"
6 | export AD_DEPLOYMENT_NAME="samba-ad-server"
7 | export MEMBER_POD_YAML="${SCRIPT_DIR}/files/samba-domain-member-pod.yml"
8 | export MEMBER_POD_NAME="samba-dm"
9 | export MEMBER_CM_NAME="samba-container-config"
10 | export MEMBER_SECRET_NAME="ad-join-secret"
11 |
12 | export KEEP=${KEEP:-0}
13 |
14 | _error() {
15 | echo "$@"
16 | exit 1
17 | }
18 |
19 | _errordbg() {
20 | local errmsg="$1"
21 | shift
22 | echo ERROR: "$errmsg"
23 | for resource in "$@"; do
24 | echo "---------"
25 | dcmd=(kubectl get -o yaml "${resource}")
26 | echo ">" "${dcmd[@]}"
27 | ! "${dcmd[@]}"
28 | echo "---------"
29 | dcmd=(kubectl describe "${resource}")
30 | echo ">" "${dcmd[@]}"
31 | ! "${dcmd[@]}"
32 | done
33 | echo "---------"
34 | _error "$errmsg"
35 | }
36 |
--------------------------------------------------------------------------------
/tests/files/coredns-snippet.template:
--------------------------------------------------------------------------------
1 | domain1.sink.test:53 {
2 | errors
3 | cache 30
4 | forward . AD_SERVER_IP
5 | }
6 |
--------------------------------------------------------------------------------
/tests/files/samba-ad-server-deployment.yml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: samba-ad-server
5 | labels:
6 | app: samba-ad
7 | spec:
8 | replicas: 1
9 | selector:
10 | matchLabels:
11 | app: samba-ad
12 | template:
13 | metadata:
14 | labels:
15 | app: samba-ad
16 | spec:
17 | containers:
18 | - name: samba
19 | # Pointing to locally built image,
20 | # change here to use a registry.
21 | image: samba-ad-server:$IMG_TAG
22 | # Need imagePullPolicy Never for working with local images.
23 | # Otherwise we get "ErrImagePull".
24 | imagePullPolicy: Never
25 | securityContext:
26 | capabilities:
27 | add: ["SYS_ADMIN"]
28 | ports:
29 | # https://wiki.samba.org/index.php/Samba_AD_DC_Port_Usage
30 | - containerPort: 53
31 | name: dns
32 | - containerPort: 135
33 | name: epm
34 | protocol: TCP
35 | - containerPort: 137
36 | name: netbios-ns
37 | protocol: UDP
38 | - containerPort: 138
39 | name: netbios-dgram
40 | protocol: UDP
41 | - containerPort: 139
42 | name: netbios-session
43 | protocol: TCP
44 | - containerPort: 389
45 | name: ldap
46 | - containerPort: 445
47 | name: smb
48 | protocol: TCP
49 | - containerPort: 464
50 | name: kerberos
51 | - containerPort: 636
52 | name: ldaps
53 | protocol: TCP
54 | - containerPort: 3268
55 | name: gc
56 | protocol: TCP
57 | - containerPort: 3269
58 | name: gc-ssl
59 | protocol: TCP
60 | # need 49152-65535 for dynamic RPC ports
61 | # but currently not possible to specify ranges
62 |
--------------------------------------------------------------------------------
/tests/files/samba-domain-member-pod.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Configuration for the samba domain member pod.
3 | apiVersion: v1
4 | kind: ConfigMap
5 | metadata:
6 | name: samba-container-config
7 | data:
8 | config.json: |
9 | {
10 | "samba-container-config": "v0",
11 | "configs": {
12 | "sambadm1": {
13 | "shares": [
14 | "share"
15 | ],
16 | "globals": [
17 | "noprinting",
18 | "sambadm1"
19 | ],
20 | "instance_name": "SMBDM1"
21 | }
22 | },
23 | "shares": {
24 | "share": {
25 | "options": {
26 | "path": "/share",
27 | "read only": "no"
28 | }
29 | }
30 | },
31 | "_NOTE": "Change the security and workgroup keys to match your domain.",
32 | "globals": {
33 | "noprinting": {
34 | "options": {
35 | "load printers": "no",
36 | "printing": "bsd",
37 | "printcap name": "/dev/null",
38 | "disable spoolss": "yes"
39 | }
40 | },
41 | "sambadm1": {
42 | "options": {
43 | "log level": "10",
44 | "security": "ads",
45 | "workgroup": "DOMAIN1",
46 | "realm": "DOMAIN1.SINK.TEST",
47 | "server min protocol": "SMB2",
48 | "idmap config * : backend": "autorid",
49 | "idmap config * : range": "2000-9999999"
50 | }
51 | }
52 | }
53 | }
54 | ---
55 | # Secret used to pass a AD join password to the winbind pod.
56 | apiVersion: v1
57 | kind: Secret
58 | metadata:
59 | name: ad-join-secret
60 | type: Opaque
61 | stringData:
62 | # Change the value below to match the username and password for a user that
63 | # can join systems your test AD Domain
64 | join.json: |
65 | {"username": "Administrator", "password": "Passw0rd"}
66 | ---
67 | # The pod itself.
68 | apiVersion: v1
69 | kind: Pod
70 | metadata:
71 | labels:
72 | app: samba-dm-example
73 | name: samba-dm
74 | spec:
75 | shareProcessNamespace: true
76 | containers:
77 | - image: $IMG_NAME
78 | # Need imagePullPolicy Never for working with local images.
79 | # Otherwise we get "ErrImagePull".
80 | imagePullPolicy: $IMG_PULL_POLICY
81 | name: smb
82 | command:
83 | - "samba-container"
84 | - "--debug-delay=1"
85 | - "run"
86 | - "smbd"
87 | env:
88 | - name: SAMBACC_CONFIG
89 | value: /etc/samba-container/config.json
90 | - name: SAMBA_CONTAINER_ID
91 | value: sambadm1
92 | - name: SAMBACC_VERSION
93 | value: "0.1"
94 | - name: HOSTNAME
95 | value: sambadm1
96 | ports:
97 | - containerPort: 445
98 | hostPort: 455
99 | protocol: TCP
100 | name: "smb"
101 | securityContext:
102 | allowPrivilegeEscalation: true
103 | volumeMounts:
104 | - mountPath: "/share"
105 | name: samba-sharedir
106 | - mountPath: "/etc/samba-container"
107 | name: samba-container-config
108 | - mountPath: "/var/lib/samba"
109 | name: samba-state-dir
110 | - mountPath: "/run/samba/winbindd"
111 | name: samba-sockets-dir
112 | - image: $IMG_NAME
113 | imagePullPolicy: $IMG_PULL_POLICY
114 | name: winbind
115 | command:
116 | - "samba-container"
117 | - "run"
118 | - "winbindd"
119 | env:
120 | - name: SAMBACC_VERSION
121 | value: "0.1"
122 | - name: SAMBACC_CONFIG
123 | value: /etc/samba-container/config.json
124 | - name: SAMBA_CONTAINER_ID
125 | value: sambadm1
126 | - name: HOSTNAME
127 | value: sambadm1
128 | securityContext:
129 | allowPrivilegeEscalation: true
130 | volumeMounts:
131 | - mountPath: "/etc/samba-container"
132 | name: samba-container-config
133 | - mountPath: "/var/lib/samba"
134 | name: samba-state-dir
135 | - mountPath: "/run/samba/winbindd"
136 | name: samba-sockets-dir
137 | initContainers:
138 | - image: $IMG_NAME
139 | imagePullPolicy: $IMG_PULL_POLICY
140 | name: init
141 | args:
142 | - "init"
143 | env:
144 | - name: SAMBACC_VERSION
145 | value: "0.1"
146 | - name: SAMBACC_CONFIG
147 | value: /etc/samba-container/config.json
148 | - name: SAMBA_CONTAINER_ID
149 | value: sambadm1
150 | - name: HOSTNAME
151 | value: sambadm1
152 | securityContext:
153 | allowPrivilegeEscalation: true
154 | volumeMounts:
155 | - mountPath: "/etc/samba-container"
156 | name: samba-container-config
157 | - mountPath: "/var/lib/samba"
158 | name: samba-state-dir
159 | - image: $IMG_NAME
160 | imagePullPolicy: $IMG_PULL_POLICY
161 | name: must-join
162 | args:
163 | - "must-join"
164 | - "--files"
165 | - "--join-file=/etc/join-data/join.json"
166 | env:
167 | - name: SAMBACC_VERSION
168 | value: "0.1"
169 | - name: SAMBACC_CONFIG
170 | value: /etc/samba-container/config.json
171 | - name: SAMBA_CONTAINER_ID
172 | value: sambadm1
173 | - name: HOSTNAME
174 | value: sambadm1
175 | securityContext:
176 | allowPrivilegeEscalation: true
177 | volumeMounts:
178 | - mountPath: "/etc/samba-container"
179 | name: samba-container-config
180 | - mountPath: "/var/lib/samba"
181 | name: samba-state-dir
182 | - mountPath: "/etc/join-data"
183 | name: samba-join-data
184 | readOnly: true
185 | volumes:
186 | - configMap:
187 | name: samba-container-config
188 | name: samba-container-config
189 | - secret:
190 | secretName: ad-join-secret
191 | items:
192 | - key: join.json
193 | path: join.json
194 | name: samba-join-data
195 | - emptyDir:
196 | medium: Memory
197 | name: samba-sockets-dir
198 | - emptyDir: {}
199 | name: samba-state-dir
200 | # Comment out the section below to skip using a PVC for the share
201 | # - persistentVolumeClaim:
202 | # claimName: mypvc
203 | # name: samba-sharedir
204 | # Uncomment the section below to use an empty dir for the share
205 | - emptyDir:
206 | medium: Memory
207 | name: samba-sharedir
208 |
--------------------------------------------------------------------------------
/tests/test-deploy-ad-member.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | SCRIPT_DIR="$(cd "$(dirname "${0}")" && pwd)"
4 | IMG_TAG=${IMG_TAG:-"latest"}
5 | IMG_NAME="${SERVER_IMG:-samba-server}:${IMG_TAG}"
6 | IMG_PULL_POLICY="${IMG_PULL_POLICY:-Never}"
7 |
8 | source "${SCRIPT_DIR}/common.sh"
9 |
10 | echo "Creating ad member pod..."
11 | ERROR_MSG=$(IMG_NAME="${IMG_NAME}" IMG_PULL_POLICY="${IMG_PULL_POLICY}" envsubst < "${MEMBER_POD_YAML}" | kubectl create -f - 2>&1 1>/dev/null)
12 | if [ $? -ne 0 ] ; then
13 | if [[ "${ERROR_MSG}" =~ "AlreadyExists" ]] ; then
14 | echo "pod exists already. Continuing."
15 | else
16 | _error "Error creating member pod."
17 | fi
18 | fi
19 |
20 | kubectl get pod
21 |
22 | podname="$(kubectl get pod | grep "${MEMBER_POD_NAME}" | awk '{ print $1 }')"
23 | [ $? -eq 0 ] || _error "Error getting podname"
24 |
25 | echo "Samba ad member pod is $podname"
26 |
27 | echo "waiting for pod to be in Running state"
28 | tries=0
29 | podstatus="none"
30 | until [ $tries -ge 120 ] || echo "$podstatus" | grep -q 'Running'; do
31 | sleep 1
32 | echo -n "."
33 | tries=$(( tries + 1 ))
34 | podstatus="$(kubectl get pod "$podname" -o go-template='{{.status.phase}}')"
35 | done
36 | echo
37 | kubectl get pod
38 | echo
39 | echo "$podstatus" | grep -q 'Running' || \
40 | _errordbg "Pod did not reach Running state" "pod/${podname}"
41 |
42 | echo "waiting for samba to become reachable"
43 | tries=0
44 | rc=1
45 | while [ $tries -lt 120 ] && [ $rc -ne 0 ]; do
46 | sleep 1
47 | tries=$(( tries + 1 ))
48 | kubectl exec "${podname}" -c "smb" -- smbclient -N -L 127.0.0.1 2>/dev/null 1>/dev/null
49 | rc=$?
50 | echo -n "."
51 | done
52 | echo
53 | [ $rc -eq 0 ] || _error "Error: samba ad did not become reachable"
54 |
55 | echo "member setup done"
56 |
--------------------------------------------------------------------------------
/tests/test-deploy-ad-server.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | SCRIPT_DIR="$(cd "$(dirname "${0}")" && pwd)"
4 | IMG_TAG=${IMG_TAG:-"latest"}
5 |
6 | source "${SCRIPT_DIR}/common.sh"
7 |
8 | echo "Creating ad server deployment..."
9 | ERROR_MSG=$(IMG_TAG=${IMG_TAG} envsubst < "${AD_DEPLOYMENT_YAML}" | kubectl create -f - 2>&1 1>/dev/null)
10 | if [ $? -ne 0 ] ; then
11 | if [[ "${ERROR_MSG}" =~ "AlreadyExists" ]] ; then
12 | echo "Deployment exists already. Continuing."
13 | else
14 | _error "Error creating ad server deployment."
15 | fi
16 | fi
17 |
18 | kubectl get deployment
19 |
20 | replicaset="$(kubectl describe deployment "${AD_DEPLOYMENT_NAME}" | grep -s "NewReplicaSet:" | awk '{ print $2 }')"
21 | [ $? -eq 0 ] || _error "Error getting replicaset"
22 |
23 | podname="$(kubectl get pod | grep "$replicaset" | awk '{ print $1 }')"
24 | [ $? -eq 0 ] || _error "Error getting podname"
25 |
26 | echo "Samba ad pod is $podname"
27 |
28 | echo "waiting for pod to be in Running state"
29 | tries=0
30 | podstatus="none"
31 | until [ $tries -ge 120 ] || echo "$podstatus" | grep -q 'Running'; do
32 | sleep 1
33 | echo -n "."
34 | tries=$(( tries + 1 ))
35 | podstatus="$(kubectl get pod "$podname" -o go-template='{{.status.phase}}')"
36 | done
37 | echo
38 | kubectl get pod
39 | echo
40 | echo "$podstatus" | grep -q 'Running' || \
41 | _errordbg "Pod did not reach Running state" "deployment/${AD_DEPLOYMENT_NAME}" "pod/${podname}"
42 |
43 | echo "waiting for samba to become reachable"
44 | tries=0
45 | rc=1
46 | while [ $tries -lt 120 ] && [ $rc -ne 0 ]; do
47 | sleep 1
48 | tries=$(( tries + 1 ))
49 | kubectl exec "${podname}" -- smbclient -N -L 127.0.0.1 2>/dev/null 1>/dev/null
50 | rc=$?
51 | echo -n "."
52 | done
53 | echo
54 | [ $rc -eq 0 ] || _error "Error: samba ad did not become reachable"
55 |
56 |
57 | echo "patching coredns zonefile"
58 |
59 | AD_POD_IP=$(kubectl get pod -o jsonpath='{ .items[*].status.podIP }')
60 | [ $? -eq 0 ] || _error "Error getting ad server pod IP"
61 |
62 | echo "AD pod IP: ${AD_POD_IP}"
63 |
64 | TMPFILE=$(mktemp)
65 |
66 | cat > "${TMPFILE}" <> "${TMPFILE}"
74 |
75 | echo >> "${TMPFILE}"
76 |
77 | # don't repeat an existing block for our domain
78 | FIRSTLINE="$(head -1 ./tests/files/coredns-snippet.template)"
79 | LASTLINE=" }"
80 |
81 | sed -i .backup -e "/$FIRSTLINE/,/$LASTLINE/d" "${TMPFILE}"
82 |
83 | sed -e "s/AD_SERVER_IP/${AD_POD_IP}/" \
84 | < tests/files/coredns-snippet.template \
85 | >> "${TMPFILE}"
86 |
87 | echo >> "${TMPFILE}"
88 |
89 | kubectl patch cm -n kube-system coredns -p "$(cat "${TMPFILE}")"
90 | [ $? -eq 0 ] || _error "Error patching coredns config map"
91 |
92 | echo "ad setup done"
93 |
--------------------------------------------------------------------------------
/tests/test-remove-ad-member.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | SCRIPT_DIR="$(cd "$(dirname "${0}")" && pwd)"
4 |
5 | source "${SCRIPT_DIR}/common.sh"
6 |
7 | if [ "${KEEP}" -eq 1 ]; then
8 | echo "keeping ad member pod (KEEP=1)"
9 | exit 0
10 | fi
11 |
12 | echo "removing ad member pod..."
13 | kubectl delete pod "${MEMBER_POD_NAME}"
14 | [ $? -eq 0 ] || _error "Error deleting pod"
15 | echo
16 |
17 | kubectl delete cm "${MEMBER_CM_NAME}"
18 | [ $? -eq 0 ] || _error "Error deleting configmap"
19 | echo
20 |
21 | kubectl delete secret "${MEMBER_SECRET_NAME}"
22 | [ $? -eq 0 ] || _error "Error deleting secret"
23 | echo
24 |
25 | echo "ad member pod removed"
26 |
--------------------------------------------------------------------------------
/tests/test-remove-ad-server.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | SCRIPT_DIR="$(cd "$(dirname "${0}")" && pwd)"
4 |
5 | source "${SCRIPT_DIR}/common.sh"
6 |
7 | if [ "${KEEP}" -eq 1 ]; then
8 | echo "keeping ad server deployment (KEEP=1)"
9 | exit 0
10 | fi
11 |
12 | echo "removing ad server deployment..."
13 | kubectl delete deployment "${AD_DEPLOYMENT_NAME}"
14 | [ $? -eq 0 ] || _error "Error deleting deployment"
15 | echo
16 | echo "ad server deployment removed"
17 |
--------------------------------------------------------------------------------
/tests/test-samba-ad-server-kubernetes.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | SCRIPT_DIR="$(cd "$(dirname "${0}")" && pwd)"
4 |
5 | source "${SCRIPT_DIR}/common.sh"
6 |
7 | source "${SCRIPT_DIR}/test-deploy-ad-server.sh"
8 |
9 | kubectl exec "${podname}" -- samba-tool domain info 127.0.0.1
10 | [ $? -eq 0 ] || _error "Error listing domain info"
11 | echo
12 |
13 | source "${SCRIPT_DIR}/test-deploy-ad-member.sh"
14 |
15 | kubectl exec "${podname}" -c "smb" -- smbclient -N -L 127.0.0.1
16 | kubectl exec "${podname}" -c "winbind" -- wbinfo -t
17 | # note: testing `wbinfo -t` from the smb container again
18 | # to make sure samba can communicate to winbindd
19 | kubectl exec "${podname}" -c "smb" -- wbinfo -t
20 |
21 | source "${SCRIPT_DIR}/test-remove-ad-member.sh"
22 |
23 | source "${SCRIPT_DIR}/test-remove-ad-server.sh"
24 |
25 | echo
26 | echo "Success"
27 | exit 0
28 |
--------------------------------------------------------------------------------
/tests/test-samba-container.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 |
4 |
5 | echo "determining container command."
6 | if [ -z "${CONTAINER_CMD}" ]; then
7 | CONTAINER_CMD=$(command -v docker || echo )
8 | fi
9 | if [ -z "${CONTAINER_CMD}" ]; then
10 | CONTAINER_CMD=$(command -v podman || echo )
11 | fi
12 | if [ -z "${CONTAINER_CMD}" ]; then
13 | echo "Error determining container command."
14 | exit 1
15 | fi
16 | echo "container command: '${CONTAINER_CMD}'."
17 | echo "creating temporary directory."
18 | TMPDIR="$(mktemp -d)"
19 | rc=$?
20 |
21 | if [ $rc -ne 0 ]; then
22 | echo "Error creating temporary directory."
23 | exit 1
24 | fi
25 | echo "temporary directory: '${TMPDIR}'"
26 | echo "starting Samba container."
27 | CONTAINER_ID="$(${CONTAINER_CMD} run --network=none --name samba \
28 | --volume="${TMPDIR}":/share:Z --rm -d "${LOCAL_TAG}")"
29 | rc=$?
30 |
31 | if [ $rc -ne 0 ]; then
32 | echo "Error running samba container"
33 | exit 1
34 | fi
35 | echo "Container started, ID: '${CONTAINER_ID}'"
36 |
37 | # give samba a second to come up
38 | sleep 1
39 |
40 | echo "Listing samba shares"
41 | ${CONTAINER_CMD} exec "${CONTAINER_ID}" smbclient -U% -L 127.0.0.1
42 | rc=$?
43 |
44 | if [ ${rc} -ne 0 ]; then
45 | echo "Error listing samba shares"
46 | exit 1
47 | fi
48 |
49 |
50 | echo "stopping samba container."
51 |
52 | ${CONTAINER_CMD} kill "${CONTAINER_ID}"
53 | rc=$?
54 |
55 | if [ $rc -ne 0 ]; then
56 | echo "Error stopping samba container"
57 | exit 1
58 | fi
59 |
60 | echo "samba container stopped."
61 |
62 |
63 |
64 |
65 | echo "removing temporary directory."
66 | rm -rf "${TMPDIR}"
67 | rc=$?
68 |
69 |
70 | if [ $rc -eq 0 ]; then
71 | echo "Success"
72 | fi
73 |
74 | exit $rc
75 |
--------------------------------------------------------------------------------