-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Expand file tree
/
Copy pathsnapcraft.yaml
More file actions
936 lines (882 loc) · 47.6 KB
/
Copy pathsnapcraft.yaml
File metadata and controls
936 lines (882 loc) · 47.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
# ─────────────────────────────────────────────────────────────────────────────
# snapcraft.yaml — the DEFAULT WeKan snap, built on `base: core24`.
#
# This is the file the release pipeline (.github/workflows/release-all.yml) and
# releases/snap-build.sh use, and `base: core24` is WHY: core24 is a released
# base, so a snap built on it may carry `grade: stable` and be published to ALL
# FOUR channels — stable, candidate, beta and edge. Every snap job does exactly
# that (snap-native, snap-launchpad and snap-variants all publish
# `stable,candidate,beta,edge`), for the default snap and for the wekan-ondra and
# wekan-gantt-gpl variants alike. It ships the newest WeKan (Meteor 3.5,
# Node.js 24, FerretDB v1, MongoDB 7, Caddy 2).
#
# snapcraft-core26.yaml is the SAME WeKan on `base: core26`, kept for testing the
# next base and NOT built by the release: core26 is still experimental, it
# requires `build-base: devel` and therefore `grade: devel`, and a devel-grade
# snap is refused by the stable and candidate channels — it can only go to beta
# and edge. That is the whole reason the release builds core24. Keep the two in
# sync — the only intended differences are:
# base: core24 (not core26) · no build-base: devel · grade: stable
# ─────────────────────────────────────────────────────────────────────────────
name: wekan
version: '11.02'
base: core24
confinement: strict
grade: stable
summary: Open Source kanban
description: |
WeKan ® is an Open Source and collaborative kanban board application.
Whether you're maintaining a personal todo list, planning your holidays with some friends,
or working in a team on your next revolutionary idea, Kanban boards are an unbeatable tool
to keep your things organized. They give you a visual overview of the current state of
your project, and make you productive by allowing you to focus on the few items that matter the most.
Depending on target environment, some configuration settings might need to be adjusted.
For full list of configuration options call:
$ wekan.help
# Metadata fields
title: Wekan
contact: https://github.com/wekan/wekan/issues
license: MIT
donation: https://wekan.fi/commercial-support/
issues: https://github.com/wekan/wekan/issues
source-code: https://github.com/wekan/wekan
website: https://wekan.fi
environment:
SNAP_DATA: "/var/snap/$SNAP_INSTANCE_NAME/$SNAP_REVISION"
SNAP_COMMON: "/var/snap/$SNAP_INSTANCE_NAME/common"
SNAP: "/snap/$SNAP_INSTANCE_NAME/$SNAP_REVISION"
# core24 uses the platforms: key (snapcraft 8), same as core26.
platforms:
amd64:
build-on: amd64
build-for: amd64
arm64:
build-on: arm64
build-for: arm64
# FerretDB-only arches: MongoDB ships no server for these, so the mongodb part
# produces no mongod and new installs default to FerretDB v1 (see snap/hooks/install
# and the mongodb part below). The MongoDB Database Tools (wekan/mongo-tools-patches) and
# FerretDB v1 are available for all of them.
s390x:
build-on: s390x
build-for: s390x
ppc64el:
build-on: ppc64el
build-for: ppc64el
riscv64:
build-on: riscv64
build-for: riscv64
# 32-bit, and FerretDB-only for the same reason: MongoDB ships no server for
# it. armhf's Node.js comes from the bundle like every other arch's does - the
# wekan-armhf.zip carries the right one already. For armhf that means
# wekan/node-patches, which is the only one of WeKan's three Node.js sources
# that builds 32-bit ARM; when it has none, there is no wekan-armhf.zip that
# release and so no armhf snap either.
#
# There is NO i386 entry: core24 (Ubuntu 24.04) has no i386 port, so snapcraft
# rejects `build-on: i386` with "trying to build snap in one of ['i386'], but
# none of these build architectures are supported" - and because that is a
# PARSE error it failed every snap build, not only i386's. i386 users are
# served by the .deb and AppImage instead; an i386 snap is not buildable on a
# modern base.
armhf:
build-on: armhf
build-for: armhf
plugs:
mongodb-plug:
interface: content
target: $SNAP_DATA/shared
hooks:
configure:
plugs:
- network
- network-bind
slots:
mongodb-slot:
interface: content
write:
- $SNAP_DATA/share
apps:
wekan:
command: ./bin/wekan-control
daemon: simple
plugs: [network, network-bind]
after: [mongodb, ferretdb]
mongodb:
command: ./bin/mongodb-control
daemon: simple
plugs: [network, network-bind]
# The database WeKan runs on: FerretDB v1 (the wekan/FerretDB fork) with its
# embedded SQLite backend. The mongodb service beside it runs only while a
# migration is still owed - it is the source that is READ - and bin/database-role
# says which of the two that is, from the data. Both bind the same port, so one
# runs at a time. The ferretdb binary is shipped inside the WeKan bundle
# (staged to $SNAP/ferretdb by the wekan part).
ferretdb:
command: ./bin/ferretdb-control
daemon: simple
plugs: [network, network-bind]
caddy:
command: ./bin/caddy-control
daemon: simple
plugs: [network, network-bind]
after: [mongodb]
# #6539: the snap installs a SERVER, so nothing appeared in the application
# menu and it looked like nothing had been installed. This is the menu entry
# (snap/gui/wekan.desktop): it opens the address WeKan is actually serving,
# read from the snap's own settings. `desktop` is what lets snapd's xdg-open
# shim hand the URL to the session's browser.
open:
command: ./bin/wekan-open
desktop: usr/share/applications/wekan.desktop
plugs: [desktop, network]
help:
command: ./bin/wekan-help
database-backup:
command: ./bin/mongodb-backup
plugs: [network, network-bind]
database-list-backups:
command: ./bin/database-list-backups
# #6583/#6585: when a migration re-ran or was interrupted, a snap can end up
# with two copies of its data and be serving the older one - "we just see the
# old data from a migration we did in july 2026". These two answer the only
# questions that follow: what does each copy hold, and bring the other one's
# missing documents into the one being served. Both read the databases
# themselves rather than their file timestamps; compare changes nothing, and
# merge only ever INSERTS what is absent.
database-compare:
command: ./bin/database-compare
plugs: [network, network-bind]
database-merge:
command: ./bin/database-merge
plugs: [network, network-bind]
database-restore:
command: ./bin/mongodb-restore
plugs: [network, network-bind]
migrate:
command: ./bin/wekan-force-migrate
plugs: [network, network-bind]
# #6473: incremental attachment/avatar repair (runs automatically in the
# background on every start; this command is for running it by hand, e.g.
# after deleting $SNAP_COMMON/.attachments-files-v2-done).
repair-attachments:
command: ./bin/attachment-repair
plugs: [network, network-bind]
maintenance:
command: ./bin/wekan-maintenance
plugs: [network, network-bind]
# Print the Admin Panel / Problems "Status" overview as text (problems,
# migrations and repairs in progress, plus the login-page "Must be logged in"
# checks) so an admin with only server (snap) access can see it WITHOUT Admin
# Panel access. Sub-commands: migrations | login | broken-cards | cpu | help.
problems:
command: ./bin/wekan-problems
plugs: [network, network-bind]
parts:
mongodb:
plugin: nil
#source: https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu2204-7.0.34.tgz
# The `t64` names are the real package names in Ubuntu 24.04 (noble), and
# they are spelled out here because the plain ones are not portable
# across its architectures. The 64-bit time_t transition renamed both of
# these; on the 64-bit arches the new package also PROVIDES the old name,
# so `libssl3` and `libgoogle-perftools4` resolve there and nobody
# noticed, but on armhf the ABI really changed, there is no such
# compatibility provide, and the build stops before it starts:
# Stage package not found in part 'mongodb': libssl3.
# Stage package not found in part 'mongodb': libgoogle-perftools4.
# which is how the v10.71 armhf snap failed all three attempts. Checked
# against the noble archive: libssl3t64 is published for amd64, arm64,
# armhf, i386, ppc64el, riscv64 and s390x, and libgoogle-perftools4t64
# for every one of those except i386 - which builds no snap.
#
# libcurl4 was the SAME transition, left behind when those two were
# renamed, and it failed the v10.77 armhf snap the same way and for the
# same reason:
# Stage package not found in part 'mongodb': libcurl4.
# while s390x, ppc64el and riscv64 all built on attempt 1. Checked
# against the noble indices the same way: `libcurl4` is not a real
# package on ANY architecture - the binary is `libcurl4t64` everywhere -
# and on amd64/arm64 it carries `Provides: libcurl4 (= 8.5.0-2ubuntu10)`
# so the old name resolves, while the armhf libcurl4t64 has no Provides
# line at all. That is what makes this class of bug reach exactly one
# architecture and look like flakiness on it.
#
# Every other stage-package below was checked against the noble armhf
# main+universe indices at the same time; libcurl4 was the only one that
# did not resolve.
stage-packages:
- libssl3t64
- libcurl4t64
- libstemmer0d
- zlib1g
- libsnappy1v5
- libyaml-cpp0.8
- libpcre2-8-0
- libpcre2-posix3
- libboost-system1.83.0
- libboost-iostreams1.83.0
- libboost-filesystem1.83.0
- libboost-program-options1.83.0
- libgoogle-perftools4t64
override-build: |
set -eu
case "${CRAFT_ARCH_BUILD_FOR}" in
amd64) MONGO_ARCH="x86_64" ;;
arm64) MONGO_ARCH="aarch64" ;;
# FerretDB-only arches: MongoDB ships no server, so build no mongod.
# New installs default to FerretDB v1 (snap/hooks/install), and
# mongodb-control disables the mongodb service when database=ferretdb.
*) echo "No MongoDB server for ${CRAFT_ARCH_BUILD_FOR}; FerretDB-only arch, skipping mongod."; exit 0 ;;
esac
MONGO_URL="https://fastdl.mongodb.org/linux/mongodb-linux-${MONGO_ARCH}-ubuntu2204-7.0.34.tgz"
bash "${CRAFT_PROJECT_DIR:-${SNAPCRAFT_PROJECT_DIR:-$PWD}}/releases/fetch.sh" -o mongodb.tgz "$MONGO_URL"
tar -xzf mongodb.tgz --strip-components=1
mkdir -p "$SNAPCRAFT_PART_INSTALL/bin"
cp -a bin/* "$SNAPCRAFT_PART_INSTALL/bin/"
# `bin` must be a real DIRECTORY when this part is staged, never a
# symlink - and on the FerretDB-only arches it is a symlink unless this
# says otherwise.
#
# The stage-packages above unpack an Ubuntu 24.04 merged-/usr layout,
# which puts everything in usr/ and leaves `bin` as a symlink to
# usr/bin. On amd64 and arm64 the build above then replaces it with a
# real directory when it copies mongod's binaries in. On s390x, ppc64el
# and riscv64 the build exits before that - MongoDB ships no server for
# them - so the symlink survives.
#
# Staging a `bin` that is NOT a real directory, on top of the real
# `stage/bin` DIRECTORY that an earlier part has already staged, is what
# killed the whole build:
# /build/.../stage/bin: Is a directory
# IsADirectoryError: filename: '/build/.../stage/bin'
# right after "Staging mongodb", which is staged last of the parts that
# carry a bin/. An empty real directory merges into it instead, and
# merging an empty directory changes nothing.
#
# This used to test for a symlink ONLY - `if [ -L ... ]` - and in v10.71
# that test came out FALSE on s390x, ppc64el and riscv64 and the build
# died in exactly the same way anyway; the job log records the test
# running and `craftctl default` failing right after it. So `bin` was
# something else that is not a directory, and the only way to know what
# is to look: the listing below prints it, and the normalisation covers
# every shape - symlink, regular file, or missing entirely - instead of
# the one shape that was guessed from the first failure. `rm -rf` on a
# symlink removes the LINK, not the directory it points at, and mkdir -p
# after it is what makes a real one; mkdir -p alone would follow the
# symlink and change nothing, which is the trap the earlier fix noted.
#
# Nothing is removed when mongod is really there (amd64, arm64): that
# `bin` is a real directory full of binaries and must stage as it is.
override-stage: |
echo "mongodb: bin before staging: $(ls -ld "${CRAFT_PART_INSTALL}/bin" 2>&1 || true)"
if [ ! -f "${CRAFT_PART_INSTALL}/bin/mongod" ]; then
echo "mongodb: no mongod in this part (FerretDB-only arch); making bin an empty real directory so it merges into stage/bin."
rm -rf "${CRAFT_PART_INSTALL}/bin"
mkdir -p "${CRAFT_PART_INSTALL}/bin"
fi
echo "mongodb: bin as staged: $(ls -ld "${CRAFT_PART_INSTALL}/bin" 2>&1 || true)"
craftctl default
stage:
- bin
- usr
prime:
- bin
- usr
# No mongosh part: WeKan no longer bundles the MongoDB Shell. All scripted DB
# access (readiness, replica-set init, schema migration) uses the bundled
# Node.js 24 + the `mongodb` driver via $SNAP/bin/db-eval (see snap-src/bin).
# No separate mongotools part: the per-arch MongoDB Database Tools are already
# embedded in the wekan-<arch>.zip bundle (built from wekan/mongo-tools-patches by
# release-all.yml) and the wekan part above moves them from the bundle into
# $SNAP/bin. This keeps the snap bundle-centric — every binary comes from the
# one wekan-<arch>.zip — and avoids downloading the tools twice.
# migratemongo: the WeKan 6.09 MongoDB 3.2 binaries (bin/), the old libraries
# they need (lib/x86_64-linux-gnu: libssl/libcrypto.so.1.0.0, libpng12,
# libexpat) and the AVX QEMU wrappers (avx/), from
# https://github.com/wekan/migratemongo . Staged at $SNAP/migratemongo — which
# mongodb-control / mongodb-backup / mongodb-restore already reference via
# $SNAP/migratemongo/avx, and which migration-control uses to read the 6.09
# MongoDB 3.2 data during the one-time migration to FerretDB (it runs
# $SNAP/migratemongo/bin/mongod with LD_LIBRARY_PATH set to the lib dir above,
# and the legacy $SNAP/migratemongo/bin/mongo shell for readiness — mongosh
# cannot talk to MongoDB 3.2).
#
# amd64 only: these are x86_64 MongoDB 3.2 binaries. arm64 snaps run newest
# WeKan on MongoDB 7, whose data mongod 7 reads directly.
migratemongo:
plugin: nil
build-packages:
- git
override-build: |
set -eu
case "${CRAFT_ARCH_BUILD_FOR}" in
amd64)
git clone --depth 1 https://github.com/wekan/migratemongo.git "$SNAPCRAFT_PART_INSTALL/migratemongo"
rm -rf "$SNAPCRAFT_PART_INSTALL/migratemongo/.git"
chmod +x "$SNAPCRAFT_PART_INSTALL/migratemongo/bin/"* \
"$SNAPCRAFT_PART_INSTALL/migratemongo/avx/"* 2>/dev/null || true
;;
*)
echo "migratemongo (MongoDB 3.2, x86_64) not staged for ${CRAFT_ARCH_BUILD_FOR}; arm64 uses MongoDB 7, other arches use FerretDB v1."
;;
esac
# mongo42: the THIRD reader, so a database from a MongoDB 4.x snap can be
# migrated instead of stranding the site (#6471).
#
# The snap could read exactly two kinds of database: whatever mongod 7 opens
# (its own, and 6.0), and MongoDB 3.2 through the migratemongo tools. A
# server only starts on data whose featureCompatibilityVersion is at most one
# major behind it, so everything in between - the 4.x and 5.x snaps WeKan
# shipped for years - could be opened by neither, and there was nothing to
# migrate FROM. The report is mongod 7's own words: "This version of MongoDB
# is too recent to start up on the existing data files. Try MongoDB 4.2 or
# earlier."
#
# mongod 4.2 is what that message asks for: it opens FCV 4.0 and 4.2, which
# is the vintage that was reported twice. It is used ONLY to read the old
# data during the migration - never as the running database - and the modern
# importer talks to it with the bundled driver, which supports servers from
# 4.2 up.
#
# WHY IT NEEDS ITS OWN LIBRARIES. MongoDB's 4.2 build links OpenSSL 1.1
# (libssl.so.1.1, libcrypto.so.1.1), and core24 is Ubuntu 24.04, which ships
# OpenSSL 3. Both come from one Debian libssl1.1 package, staged beside the
# binary; migration-control runs it with LD_LIBRARY_PATH pointing there, the
# same way it already runs the 3.2 tools. libcurl.so.4 it also needs is in
# the snap already (libcurl4t64 provides it).
#
# amd64 and arm64 ONLY: MongoDB publishes no 4.2 for the other architectures,
# and they never had a MongoDB to migrate from - they have been FerretDB from
# their first boot.
#
# OPTIONAL BY DESIGN: every failure here ends the part with a message and no
# binary, and migration-control simply does not find one. The snap still
# builds and behaves as it did before - the unreadable-database page - rather
# than a release failing over a migration aid.
# mongo50: the FOURTH reader, for the vintage BETWEEN the other three.
#
# A server starts only on data whose featureCompatibilityVersion is at most
# one major behind it, so the readers this snap had covered
#
# mongod 7 FCV 6.0, 7.0
# mongod 4.2 FCV 4.0, 4.2
# 3.2 tools 3.x (amd64 only)
#
# and NOTHING opened FCV 4.4 or 5.0. That is not a hypothetical rung: the
# WeKan snap shipped MongoDB 5 in February 2023 ("MongoDB 5 to Snap Beta
# Channel for Meridiana") and 6.0.6 only in May, so a site that sat on that
# snap has 5.0 data files - and every reader here refuses them. mongod 7
# says "too recent to start up on the existing data files. Try MongoDB 4.2
# or earlier", mongod 4.2 says the same about 5.0 data, and the snap writes
# .mongodb-data-too-old and serves the explanatory page instead of the
# boards. mongod 5.0 opens FCV 4.4 AND 5.0, which closes both.
#
# Same shape as mongo42 below in every other way: read-only, used for the
# one migration and never as the running database; the modern importer talks
# to it with the bundled driver; amd64 and arm64 only, because MongoDB
# publishes no other build and no other architecture ever had a MongoDB to
# migrate from; and OPTIONAL - any failure here leaves no binary and
# migration-control simply does not find one.
#
# AVX: MongoDB 5.0 and later REQUIRE it on x86_64. migration-control runs
# this reader through bin/cpu-exec with `x86_64=avx`, the same way it runs
# mongod 7, so a CPU without AVX reads the database under qemu-user
# emulation - slow, and a one-time read.
#
# The tarball is the ubuntu2004 build, not ubuntu1804: MongoDB published no
# 18.04 build of 5.0. 20.04 is still OpenSSL 1.1, so the libssl1.1 staging
# below is the same as 4.2's.
mongo50:
plugin: nil
build-packages:
- ca-certificates
- curl
- dpkg
override-build: |
set -eu
V=5.0.31
# The directory is created FIRST, before anything can decide to skip.
# `stage:` and `prime:` below name `mongo50` explicitly, and a filter
# that names a path the part did not produce is not ignored - snapcraft
# stops the whole build on it:
#
# Staging mongo50
# Failed to copy '/build/.../parts/mongo50/install/mongo50':
# no such file or directory.
# Build failed
#
# That is what failed EVERY Launchpad snap in v10.80 - armhf, s390x,
# ppc64el and riscv64, three attempts each - because this part is
# amd64/arm64 only and every other architecture took the `exit 0`
# below, leaving nothing to stage. The part was meant to be optional
# ("OPTIONAL BY DESIGN", above) and on those arches it silently was
# not: it took the entire snap down with it, on the four
# architectures that have no native runner and can only be built
# here.
#
# An empty directory stages fine and primes to a few bytes, and
# migration-control looks for the BINARY inside it, which is still
# not there - so "no MongoDB 5.0 to migrate from" stays exactly as
# true as it was, without being fatal.
dest="$SNAPCRAFT_PART_INSTALL/mongo50"
mkdir -p "$dest/bin" "$dest/lib"
case "${CRAFT_ARCH_BUILD_FOR}" in
amd64) MARCH=x86_64 ; DEBARCH=amd64 ;;
arm64) MARCH=aarch64 ; DEBARCH=arm64 ;;
*)
echo "mongo50: no MongoDB 5.0 for ${CRAFT_ARCH_BUILD_FOR}, and nothing to migrate from there; skipping."
exit 0
;;
esac
work="$(mktemp -d)"
trap 'rm -rf "$work"' EXIT
# ── the server, checked against the checksum MongoDB publishes ────
tgz="mongodb-linux-${MARCH}-ubuntu2004-${V}.tgz"
url="https://fastdl.mongodb.org/linux/${tgz}"
if ! bash "${CRAFT_PROJECT_DIR:-${SNAPCRAFT_PROJECT_DIR:-$PWD}}/releases/fetch.sh" -o "$work/$tgz" "$url"; then
echo "mongo50: could not download $url; skipping (the snap keeps working, that migration path is simply unavailable)."
exit 0
fi
if bash "${CRAFT_PROJECT_DIR:-${SNAPCRAFT_PROJECT_DIR:-$PWD}}/releases/fetch.sh" --optional -o "$work/$tgz.sha256" "$url.sha256"; then
want="$(cut -d' ' -f1 < "$work/$tgz.sha256")"
got="$(sha256sum "$work/$tgz" | cut -d' ' -f1)"
if [ "$want" != "$got" ]; then
echo "mongo50: checksum mismatch for $tgz - MongoDB says $want, the download is $got. Not staging it."
exit 0
fi
echo "mongo50: $tgz checksum verified."
else
echo "mongo50: MongoDB published no .sha256 for $tgz; staging it unverified."
fi
tar -xzf "$work/$tgz" -C "$work"
cp "$work/mongodb-linux-${MARCH}-ubuntu2004-${V}/bin/mongod" "$dest/bin/mongod"
chmod +x "$dest/bin/mongod"
# ── OpenSSL 1.1, which core24 does not have ──────────────────────
# Resolved by listing the pool rather than pinning a filename: the
# point releases roll, and a hardcoded version 404s the day they do.
# Debian security first (the patched 1.1.1w), then Debian main, then
# Ubuntu focal - amd64 lives on archive.ubuntu.com and arm64 on
# ports.ubuntu.com, which is why both are listed.
pools="https://security.debian.org/debian-security/pool/updates/main/o/openssl
https://deb.debian.org/debian/pool/main/o/openssl
http://archive.ubuntu.com/ubuntu/pool/main/o/openssl
http://ports.ubuntu.com/ubuntu-ports/pool/main/o/openssl"
got_ssl=no
for pool in $pools; do
deb="$(curl -fsSL "$pool/" 2>/dev/null | grep -o "libssl1\.1_[^\"]*_${DEBARCH}\.deb" | sort -V | tail -1 || true)"
[ -n "$deb" ] || continue
bash "${CRAFT_PROJECT_DIR:-${SNAPCRAFT_PROJECT_DIR:-$PWD}}/releases/fetch.sh" -o "$work/ssl.deb" "$pool/$deb" || continue
rm -rf "$work/sslx"; mkdir -p "$work/sslx"
dpkg-deb -x "$work/ssl.deb" "$work/sslx" 2>/dev/null || continue
found=0
for so in libssl.so.1.1 libcrypto.so.1.1; do
f="$(find "$work/sslx" -name "$so" -type f | head -1)"
[ -n "$f" ] && cp "$f" "$dest/lib/" && found=$((found + 1))
done
if [ "$found" = 2 ]; then
echo "mongo50: OpenSSL 1.1 taken from $deb ($pool)."
got_ssl=yes
break
fi
done
if [ "$got_ssl" != yes ]; then
echo "mongo50: could not obtain OpenSSL 1.1 for ${DEBARCH}; mongod 5.0 cannot run without it, so it is not staged."
# The CONTENTS go, the DIRECTORY stays - `stage: mongo50` below
# names it, and snapcraft ends the whole build on a filter whose
# path is missing (see the comment at the top of override-build).
# An empty directory stages to nothing and migration-control
# guards every use on `-x $M42/bin/mongod`, so "no 4.2 reader" is
# still exactly what this means.
rm -rf "${dest:?}"/* 2>/dev/null || true
exit 0
fi
# It has to RUN, not just exist. A staged binary that dies on a
# missing library would only be discovered by an admin whose site is
# already down, so the build asks it here.
if ! LD_LIBRARY_PATH="$dest/lib" "$dest/bin/mongod" --version >/dev/null 2>&1; then
echo "mongo50: the staged mongod 5.0 does not run in this environment; removing it rather than shipping something that cannot start."
# Contents only, directory kept - same reason as above.
rm -rf "${dest:?}"/* 2>/dev/null || true
exit 0
fi
echo "mongo50: staged $("$dest/bin/mongod" --version 2>/dev/null | head -1 || echo "mongod $V") for ${CRAFT_ARCH_BUILD_FOR}."
stage:
- mongo50
prime:
- mongo50
mongo42:
plugin: nil
build-packages:
- ca-certificates
- curl
- dpkg
override-build: |
set -eu
V=4.2.25
# The directory is created FIRST, before anything can decide to skip.
# `stage:` and `prime:` below name `mongo42` explicitly, and a filter
# that names a path the part did not produce is not ignored - snapcraft
# stops the whole build on it:
#
# Staging mongo42
# Failed to copy '/build/.../parts/mongo42/install/mongo42':
# no such file or directory.
# Build failed
#
# That is what failed EVERY Launchpad snap in v10.80 - armhf, s390x,
# ppc64el and riscv64, three attempts each - because this part is
# amd64/arm64 only and every other architecture took the `exit 0`
# below, leaving nothing to stage. The part was meant to be optional
# ("OPTIONAL BY DESIGN", above) and on those arches it silently was
# not: it took the entire snap down with it, on the four
# architectures that have no native runner and can only be built
# here.
#
# An empty directory stages fine and primes to a few bytes, and
# migration-control looks for the BINARY inside it, which is still
# not there - so "no MongoDB 4.2 to migrate from" stays exactly as
# true as it was, without being fatal.
dest="$SNAPCRAFT_PART_INSTALL/mongo42"
mkdir -p "$dest/bin" "$dest/lib"
case "${CRAFT_ARCH_BUILD_FOR}" in
amd64) MARCH=x86_64 ; DEBARCH=amd64 ;;
arm64) MARCH=aarch64 ; DEBARCH=arm64 ;;
*)
echo "mongo42: no MongoDB 4.2 for ${CRAFT_ARCH_BUILD_FOR}, and nothing to migrate from there; skipping."
exit 0
;;
esac
work="$(mktemp -d)"
trap 'rm -rf "$work"' EXIT
# ── the server, checked against the checksum MongoDB publishes ────
tgz="mongodb-linux-${MARCH}-ubuntu1804-${V}.tgz"
url="https://fastdl.mongodb.org/linux/${tgz}"
if ! bash "${CRAFT_PROJECT_DIR:-${SNAPCRAFT_PROJECT_DIR:-$PWD}}/releases/fetch.sh" -o "$work/$tgz" "$url"; then
echo "mongo42: could not download $url; skipping (the snap keeps working, that migration path is simply unavailable)."
exit 0
fi
if bash "${CRAFT_PROJECT_DIR:-${SNAPCRAFT_PROJECT_DIR:-$PWD}}/releases/fetch.sh" --optional -o "$work/$tgz.sha256" "$url.sha256"; then
want="$(cut -d' ' -f1 < "$work/$tgz.sha256")"
got="$(sha256sum "$work/$tgz" | cut -d' ' -f1)"
if [ "$want" != "$got" ]; then
echo "mongo42: checksum mismatch for $tgz - MongoDB says $want, the download is $got. Not staging it."
exit 0
fi
echo "mongo42: $tgz checksum verified."
else
echo "mongo42: MongoDB published no .sha256 for $tgz; staging it unverified."
fi
tar -xzf "$work/$tgz" -C "$work"
cp "$work/mongodb-linux-${MARCH}-ubuntu1804-${V}/bin/mongod" "$dest/bin/mongod"
chmod +x "$dest/bin/mongod"
# ── OpenSSL 1.1, which core24 does not have ──────────────────────
# Resolved by listing the pool rather than pinning a filename: the
# point releases roll, and a hardcoded version 404s the day they do.
# Debian security first (the patched 1.1.1w), then Debian main, then
# Ubuntu focal - amd64 lives on archive.ubuntu.com and arm64 on
# ports.ubuntu.com, which is why both are listed.
pools="https://security.debian.org/debian-security/pool/updates/main/o/openssl
https://deb.debian.org/debian/pool/main/o/openssl
http://archive.ubuntu.com/ubuntu/pool/main/o/openssl
http://ports.ubuntu.com/ubuntu-ports/pool/main/o/openssl"
got_ssl=no
for pool in $pools; do
deb="$(curl -fsSL "$pool/" 2>/dev/null | grep -o "libssl1\.1_[^\"]*_${DEBARCH}\.deb" | sort -V | tail -1 || true)"
[ -n "$deb" ] || continue
bash "${CRAFT_PROJECT_DIR:-${SNAPCRAFT_PROJECT_DIR:-$PWD}}/releases/fetch.sh" -o "$work/ssl.deb" "$pool/$deb" || continue
rm -rf "$work/sslx"; mkdir -p "$work/sslx"
dpkg-deb -x "$work/ssl.deb" "$work/sslx" 2>/dev/null || continue
found=0
for so in libssl.so.1.1 libcrypto.so.1.1; do
f="$(find "$work/sslx" -name "$so" -type f | head -1)"
[ -n "$f" ] && cp "$f" "$dest/lib/" && found=$((found + 1))
done
if [ "$found" = 2 ]; then
echo "mongo42: OpenSSL 1.1 taken from $deb ($pool)."
got_ssl=yes
break
fi
done
if [ "$got_ssl" != yes ]; then
echo "mongo42: could not obtain OpenSSL 1.1 for ${DEBARCH}; mongod 4.2 cannot run without it, so it is not staged."
# The CONTENTS go, the DIRECTORY stays - `stage: mongo42` below
# names it, and snapcraft ends the whole build on a filter whose
# path is missing (see the comment at the top of override-build).
# An empty directory stages to nothing and migration-control
# guards every use on `-x $M42/bin/mongod`, so "no 4.2 reader" is
# still exactly what this means.
rm -rf "${dest:?}"/* 2>/dev/null || true
exit 0
fi
# It has to RUN, not just exist. A staged binary that dies on a
# missing library would only be discovered by an admin whose site is
# already down, so the build asks it here.
if ! LD_LIBRARY_PATH="$dest/lib" "$dest/bin/mongod" --version >/dev/null 2>&1; then
echo "mongo42: the staged mongod 4.2 does not run in this environment; removing it rather than shipping something that cannot start."
# Contents only, directory kept - same reason as above.
rm -rf "${dest:?}"/* 2>/dev/null || true
exit 0
fi
echo "mongo42: staged $("$dest/bin/mongod" --version 2>/dev/null | head -1 || echo "mongod $V") for ${CRAFT_ARCH_BUILD_FOR}."
stage:
- mongo42
prime:
- mongo42
wekan:
source: .
plugin: npm
npm-node-version: 24.19.0
npm-include-node: true
build-packages:
- build-essential
- ca-certificates
- apt-utils
- python3
- g++
- capnproto
- curl
- wget
- unzip
- nodejs
- npm
stage-packages:
- libfontconfig1
override-build: |
set -eu
case "${CRAFT_ARCH_BUILD_FOR}" in
amd64) WEKAN_ARCH="amd64" ;;
arm64) WEKAN_ARCH="arm64" ;;
s390x) WEKAN_ARCH="s390x" ;;
ppc64el) WEKAN_ARCH="ppc64le" ;;
riscv64) WEKAN_ARCH="riscv64" ;;
i386) WEKAN_ARCH="i386" ;;
armhf) WEKAN_ARCH="armhf" ;;
*) echo "Unsupported architecture: ${CRAFT_ARCH_BUILD_FOR}"; exit 1 ;;
esac
WEKAN_ZIP="wekan-11.02-${WEKAN_ARCH}.zip"
echo "Cleaning environment first"
rm -rf .build
mkdir .build
cd .build
#wget https://github.com/wekan/wekan/releases/download/v11.02/wekan-11.02-amd64.zip
# Retry: a release asset can 404 for a short while right after it is
# uploaded (CDN/propagation lag), and a plain wget treated that as
# fatal. --retry-on-http-error covers the 404/5xx window; a genuinely
# missing bundle still fails after the tries are spent.
wget --tries=20 --waitretry=20 --retry-on-http-error=404,403,500,502,503 \
"https://github.com/wekan/wekan/releases/download/v11.02/${WEKAN_ZIP}"
unzip "${WEKAN_ZIP}"
rm "${WEKAN_ZIP}"
# Fix: bcrypt 5.0.1 (Meteor accounts-password) ships node-addon-api@3
# which fails to compile on Node.js 24. Replace with bcrypt 6.0.0.
BCRYPT_DIR="bundle/programs/server/npm/node_modules/meteor/accounts-password/node_modules/bcrypt"
if [ -d "$BCRYPT_DIR" ]; then
rm -rf "$BCRYPT_DIR"
TMP=$(mktemp -d)
pushd "$TMP" > /dev/null
npm pack bcrypt@6.0.0
mkdir bcrypt && tar xzf bcrypt-*.tgz --strip-components=1 -C bcrypt
cd bcrypt && npm install --ignore-scripts && cd ..
popd > /dev/null
cp -a "$TMP/bcrypt" "$BCRYPT_DIR"
rm -rf "$TMP"
fi
cd bundle/programs/server
rm -rf node_modules
# Retried, because on Launchpad this is the step that loses the race
# with the network. Every request goes through the build farm's proxy,
# and one tarball out of a couple of thousand can simply be cut:
#
# npm ERR! code ECONNRESET
# npm ERR! network request to https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz
# failed, reason: socket hang up
# 'override-build' in part 'wekan' failed with code 1.
#
# which is what ended the riscv64 snap in v10.80 after it had already
# built for half an hour. Nothing is wrong with the build when that
# happens and asking again fixes it; npm's own --fetch-retries only
# covers the request, not a socket dropped mid-stream. Three tries,
# then it is a real failure and the log says so.
for attempt in 1 2 3; do
if npm install; then
break
fi
if [ "$attempt" = 3 ]; then
echo "npm install failed three times in a row - this is not the network." >&2
exit 1
fi
echo "npm install failed (attempt ${attempt}/3); retrying in 15s."
sleep 15
done
cd ../../../..
# Copy to Snap. Use the bundle's OWN arch-correct Node.js: the
# wekan-<arch>.zip already ships the right node for this platform
# (nodejs.org for amd64/arm64/s390x/ppc64le, unofficial-builds.nodejs.org
# for riscv64), so the snap needs no separate node download and works on
# every arch the bundle is built for.
mkdir -p $SNAPCRAFT_PART_INSTALL/bin
cp -p .build/bundle/node $SNAPCRAFT_PART_INSTALL/bin/node
chmod +x $SNAPCRAFT_PART_INSTALL/bin/node
cp -r .build/bundle/* $SNAPCRAFT_PART_INSTALL/
cp .build/bundle/.node_version.txt $SNAPCRAFT_PART_INSTALL/
rm -f $SNAPCRAFT_PART_INSTALL/lib/node_modules/wekan
# The snap uses its own bin/node (copied from the bundle above) and
# wekan-control, so drop the bundle's root-level node + self-contained
# launchers. Keep the bundle's ferretdb (ferretdb-control runs
# $SNAP/ferretdb) and move the bundle's per-arch MongoDB Database Tools
# into bin/ so the backup/restore scripts (which use $SNAP/bin) find them.
rm -f $SNAPCRAFT_PART_INSTALL/node \
$SNAPCRAFT_PART_INSTALL/start-wekan.sh \
$SNAPCRAFT_PART_INSTALL/start-wekan.bat
for t in bsondump mongodump mongoexport mongofiles mongoimport mongorestore mongostat mongotop; do
[ -f "$SNAPCRAFT_PART_INSTALL/$t" ] && mv -f "$SNAPCRAFT_PART_INSTALL/$t" "$SNAPCRAFT_PART_INSTALL/bin/$t" || true
done
# Bundle the MongoDB -> FerretDB migrator (run by migration-control on
# first boot when upgrading from an old MongoDB-based snap).
cp releases/migrate-mongodb-to-ferretdb.mjs $SNAPCRAFT_PART_INSTALL/bin/
organize:
README: README.wekan
#prime:
# - -lib/node_modules/node-pre-gyp/node_modules/tar/lib/.unpack.js.swp
# - -lib/node_modules/weka*
helpers:
source: snap-src
plugin: dump
# #6539: the application-menu entry. snapcraft reads snap/gui/*.desktop for
# the .desktop file and snap/gui/icon.png for the icon; the desktop file has
# to end up where the `open` app's `desktop:` key points, so it is staged
# there rather than only living in snap/gui.
desktop-launcher:
source: snap/gui
plugin: dump
organize:
wekan.desktop: usr/share/applications/wekan.desktop
stage:
- usr/share/applications/wekan.desktop
caddy:
plugin: nil
build-packages:
- curl
override-build: |
set -eu
# Download the official prebuilt Caddy static binary from GitHub
# releases. WeKan uses only built-in Caddy directives (reverse_proxy,
# header, tls, redir, handle) — no third-party modules — so vanilla
# Caddy is sufficient and xcaddy is NOT needed. Fetched from GitHub
# because the Launchpad remote builders cannot reach the Cloudsmith
# apt repo (their network is restricted to a fetch proxy).
# Tracks the latest stable Caddy with a pinned fallback; set
# CADDY_VERSION explicitly for fully reproducible builds.
#
# The version is resolved WITHOUT api.github.com. That API rate-limits
# unauthenticated callers by IP, and a CI runner shares its address
# with every other job on the same host, so it answers 403 whenever
# the neighbours have been busy. In v10.71 that one line failed the
# whole wekan-gantt-gpl amd64 snap:
# curl: (22) The requested URL returned error: 403
# 'override-build' in part 'caddy' failed with code 22.
# and the pinned fallback that used to sit on the next line never
# ran - snapcraft executes a scriptlet under `set -o pipefail` as
# well, so the 403 failed the ASSIGNMENT and `set -e` ended the part
# one line before its own safety net. A fallback that the failure it
# covers skips over is not a fallback, so the lookup is now allowed
# to fail: `|| true` keeps the substitution's status 0, and an empty
# answer selects the pin.
#
# github.com/…/releases/latest is a REDIRECT to the newest tag, not an
# API call, so it is not rate-limited the same way and answers where
# the API will not. The tag is read out of the URL it lands on.
CADDY_PINNED_VERSION="2.11.4"
if [ -n "${CADDY_VERSION:-}" ]; then
echo "caddy: using CADDY_VERSION=${CADDY_VERSION} from the environment."
else
# Only a lookup: when it fails, the pinned version below is used,
# so this one stays a plain curl.
CADDY_LATEST_URL="$(curl -fsSLI -o /dev/null -w '%{url_effective}' \
https://github.com/caddyserver/caddy/releases/latest || true)"
CADDY_VERSION="$(printf '%s' "${CADDY_LATEST_URL}" | sed -n 's|.*/releases/tag/v\([0-9][0-9.]*\)$|\1|p')"
if [ -n "${CADDY_VERSION}" ]; then
echo "caddy: newest release is ${CADDY_VERSION}."
else
CADDY_VERSION="${CADDY_PINNED_VERSION}"
echo "caddy: could not resolve the newest release (landed on '${CADDY_LATEST_URL}'); using the pinned ${CADDY_VERSION}."
fi
fi
case "${CRAFT_ARCH_BUILD_FOR}" in
amd64) CADDY_ARCH=amd64 ;;
arm64) CADDY_ARCH=arm64 ;;
s390x) CADDY_ARCH=s390x ;;
ppc64el) CADDY_ARCH=ppc64le ;; # Caddy uses ppc64le, not Debian's ppc64el
riscv64) CADDY_ARCH=riscv64 ;;
# Caddy is built by Go and its release assets carry GO's names,
# not Debian's. There is no linux_armhf archive and there never
# has been; the 32-bit ARM ones are armv5, armv6 and armv7. With
# no branch here armhf fell through to the default below, asked
# for caddy_<v>_linux_armhf.tar.gz, and got
# curl: (22) The requested URL returned error: 404
# which failed the whole armhf snap in v10.78.
#
# armv7, not armv6: Debian armhf's baseline is ARMv7-A with
# VFPv3-D16 hard-float, and Go's armv7 build is GOARM=7, which
# is exactly that. Note this is NOT the armhf/armv7 distinction
# that matters for Node.js in wekan/node-patches - that one is
# about NEON, and Go's GOARM=7 does not use NEON.
armhf) CADDY_ARCH=armv7 ;;
*)
# An unmapped architecture used to become a URL that 404s,
# and the "fall back to the pinned version" path below then
# retried the same wrong name and failed too - so the error
# blamed the Caddy RELEASE for something this case statement
# got wrong. Say which it is.
echo "caddy: no Caddy architecture is mapped for '${CRAFT_ARCH_BUILD_FOR}'." >&2
echo " Caddy publishes linux_amd64, linux_arm64, linux_armv5, linux_armv6," >&2
echo " linux_armv7, linux_ppc64le, linux_riscv64 and linux_s390x - Go's names," >&2
echo " not Debian's. Add a branch above rather than guessing here." >&2
exit 1
;;
esac
echo "Downloading Caddy ${CADDY_VERSION} (linux/${CADDY_ARCH}) from GitHub releases..."
# The newest release does not have to publish every architecture -
# riscv64 and s390x are the ones that come and go - so a missing
# archive falls back to the pin rather than failing the snap.
caddy_url() {
echo "https://github.com/caddyserver/caddy/releases/download/v$1/caddy_$1_linux_${CADDY_ARCH}.tar.gz"
}
# --optional: a version that publishes no archive for this CPU is a 404,
# and that is the fallback below, not an outage. Everything else - the
# 503s and dropped connections that ended the v10.89 arm64 snap - is
# waited out by fetch.sh.
if ! bash "${CRAFT_PROJECT_DIR:-${SNAPCRAFT_PROJECT_DIR:-$PWD}}/releases/fetch.sh" --optional -o /tmp/caddy.tar.gz "$(caddy_url "${CADDY_VERSION}")"; then
if [ "${CADDY_VERSION}" = "${CADDY_PINNED_VERSION}" ]; then
echo "caddy: no linux/${CADDY_ARCH} archive in Caddy ${CADDY_VERSION}, and that is the pinned version - nothing left to try." >&2
exit 1
fi
echo "caddy: Caddy ${CADDY_VERSION} publishes no linux/${CADDY_ARCH} archive; falling back to the pinned ${CADDY_PINNED_VERSION}." >&2
CADDY_VERSION="${CADDY_PINNED_VERSION}"
bash "${CRAFT_PROJECT_DIR:-${SNAPCRAFT_PROJECT_DIR:-$PWD}}/releases/fetch.sh" -o /tmp/caddy.tar.gz "$(caddy_url "${CADDY_VERSION}")"
fi
mkdir -p /tmp/caddy-extract
tar -xzf /tmp/caddy.tar.gz -C /tmp/caddy-extract caddy
# Install the Caddy binary into the snap
mkdir -p $SNAPCRAFT_PART_INSTALL/bin
install -m 0755 /tmp/caddy-extract/caddy $SNAPCRAFT_PART_INSTALL/bin/caddy
# Display installed Caddy version for confirmation
echo "Installed Caddy version:"
$SNAPCRAFT_PART_INSTALL/bin/caddy version
# Create license files manually since they don't exist in the package
mkdir -p $SNAPCRAFT_PART_INSTALL/license
echo "Caddy is licensed under the Apache License 2.0. See https://github.com/caddyserver/caddy/blob/master/LICENSE" > $SNAPCRAFT_PART_INSTALL/license/CADDY_LICENSE
# Create a basic default Caddyfile for the snap
mkdir -p $SNAPCRAFT_PART_INSTALL/etc
cat > $SNAPCRAFT_PART_INSTALL/etc/Caddyfile << 'EOF'
# Default Caddyfile for Wekan
# This is loaded by caddy-control script if no other config is provided
:8080 {
reverse_proxy localhost:3000
}
EOF
stage:
- bin/caddy
- license/CADDY_LICENSE
- etc/Caddyfile