mirror of
https://github.com/mtan93/Installomator.git
synced 2026-03-10 13:21:51 +00:00
Compare commits
502 Commits
v0.7releas
...
FortiClien
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0b22cc2423 | ||
|
|
ad5ad5f408 | ||
|
|
69fbc31078 | ||
|
|
cd5a4b2b5e | ||
|
|
fca59f554b | ||
|
|
3ef215c22b | ||
|
|
20e87458ad | ||
|
|
1797bb645b | ||
|
|
38f2f45d97 | ||
|
|
f0f4ff5747 | ||
|
|
579862274a | ||
|
|
72fdc2365e | ||
|
|
ac042bc700 | ||
|
|
f001a829bd | ||
|
|
9736e1dbfa | ||
|
|
d78c6fdd5c | ||
|
|
65b16dc1ed | ||
|
|
9f5b89c37e | ||
|
|
05c1bf7cfc | ||
|
|
e07b4dd08f | ||
|
|
88da86d4f0 | ||
|
|
b512ae17a3 | ||
|
|
1787842366 | ||
|
|
3e0ad885d8 | ||
|
|
001cd592b0 | ||
|
|
de93df0f85 | ||
|
|
0d9628b587 | ||
|
|
41e828f87a | ||
|
|
eb25c271e3 | ||
|
|
25c419b50d | ||
|
|
7025efe566 | ||
|
|
22a34c45c9 | ||
|
|
cc06b77611 | ||
|
|
70c4d59df7 | ||
|
|
7fcba4cb6e | ||
|
|
00ebfa35fd | ||
|
|
2d813bce80 | ||
|
|
69e4cdd216 | ||
|
|
55eb9e2d89 | ||
|
|
2349f456bc | ||
|
|
8fd949a567 | ||
|
|
f9997623f1 | ||
|
|
4b14b31ff3 | ||
|
|
ed737510bb | ||
|
|
ec9f1bb9a2 | ||
|
|
9022d8e74d | ||
|
|
2a9b73dba7 | ||
|
|
40f20b3536 | ||
|
|
3a0c104f48 | ||
|
|
7629acf6a5 | ||
|
|
54070273bc | ||
|
|
3d84300665 | ||
|
|
bbae9356c4 | ||
|
|
57733423b1 | ||
|
|
c3f751bad8 | ||
|
|
56bf2a3dc4 | ||
|
|
28ddefbd57 | ||
|
|
3a0373af60 | ||
|
|
fb7d9c43a8 | ||
|
|
ebed623837 | ||
|
|
b18aac905e | ||
|
|
4f1c56177a | ||
|
|
0a3b7af338 | ||
|
|
9b6c337d7a | ||
|
|
9fd2b87e3c | ||
|
|
a16cd44b0e | ||
|
|
74f6b569dd | ||
|
|
d475b2b8ab | ||
|
|
d79886b88f | ||
|
|
56125c07b1 | ||
|
|
a3dbf75818 | ||
|
|
afbd1e363e | ||
|
|
22bc0ecbf6 | ||
|
|
24f729d357 | ||
|
|
81b02e3932 | ||
|
|
800912be0c | ||
|
|
1e3a50c07f | ||
|
|
693164c9a0 | ||
|
|
0c12343fbb | ||
|
|
cba0e8c766 | ||
|
|
a25c904ba7 | ||
|
|
d64c18df93 | ||
|
|
9afdc233f9 | ||
|
|
bc7d005fb9 | ||
|
|
175f682b43 | ||
|
|
ff8a9c2c3a | ||
|
|
bf740d1ffe | ||
|
|
1da37a13ca | ||
|
|
b30d4da703 | ||
|
|
c3714d855c | ||
|
|
dd83f6bd75 | ||
|
|
c55cc788bb | ||
|
|
df616d2f51 | ||
|
|
557d63a4f3 | ||
|
|
0432eb62d3 | ||
|
|
071586e43c | ||
|
|
aea7d282fe | ||
|
|
cd6b1397c8 | ||
|
|
1d405de70a | ||
|
|
0645ff6335 | ||
|
|
c9d1d458f3 | ||
|
|
19c1275f12 | ||
|
|
aa53b0be68 | ||
|
|
9b58f57ae1 | ||
|
|
806c87266b | ||
|
|
7d60f0a11f | ||
|
|
435a60ac9f | ||
|
|
cf414f7dc6 | ||
|
|
ae3f711738 | ||
|
|
c238f94a9b | ||
|
|
9275e0c045 | ||
|
|
b3d3f25e19 | ||
|
|
2a1176a947 | ||
|
|
842b1e19cb | ||
|
|
d34f3102fc | ||
|
|
d74036e853 | ||
|
|
bb4a396788 | ||
|
|
4bc67f3de3 | ||
|
|
08e9e63422 | ||
|
|
378b166164 | ||
|
|
83c1911248 | ||
|
|
ee9861c0f5 | ||
|
|
516f05a4cb | ||
|
|
e181a02838 | ||
|
|
f2782989ce | ||
|
|
36fc48682e | ||
|
|
890c26e2e1 | ||
|
|
f1616d0d02 | ||
|
|
0a05b533a5 | ||
|
|
d36b42acf4 | ||
|
|
434b755946 | ||
|
|
62734a2acc | ||
|
|
29fadb78b4 | ||
|
|
3a397c5881 | ||
|
|
bbf4b22296 | ||
|
|
790dabaa27 | ||
|
|
ded71fdf8d | ||
|
|
952683310a | ||
|
|
5991ce2287 | ||
|
|
19137f6d94 | ||
|
|
fe21c1395a | ||
|
|
5b54eb7674 | ||
|
|
6559d84075 | ||
|
|
168abdb32e | ||
|
|
f53e20e313 | ||
|
|
9416700da2 | ||
|
|
dd2af4a40e | ||
|
|
bc26aa0ca6 | ||
|
|
ec2debc9a8 | ||
|
|
1e68b7e501 | ||
|
|
64a33a7f6b | ||
|
|
3bf9299218 | ||
|
|
ac9c5096cd | ||
|
|
22395d00a5 | ||
|
|
a994a8497c | ||
|
|
e7f4f86b58 | ||
|
|
621d6df346 | ||
|
|
9bd11b6826 | ||
|
|
6e76685721 | ||
|
|
64a91bff36 | ||
|
|
7d02cf1da4 | ||
|
|
2baf2abb91 | ||
|
|
5068ebcfd0 | ||
|
|
2571744a65 | ||
|
|
f2354ec755 | ||
|
|
f218889f7c | ||
|
|
449f7e5261 | ||
|
|
197e07ed99 | ||
|
|
ad4692e9bf | ||
|
|
195b7df5f5 | ||
|
|
6f4d9b5e81 | ||
|
|
4745138258 | ||
|
|
c64dced024 | ||
|
|
dd7344b838 | ||
|
|
49337a4ae8 | ||
|
|
cfaa94c51f | ||
|
|
83459a83d6 | ||
|
|
08435381a1 | ||
|
|
df40501291 | ||
|
|
197b34fe02 | ||
|
|
0f448404e2 | ||
|
|
c98fd8f26c | ||
|
|
244e4bb25a | ||
|
|
c60999ac7d | ||
|
|
dc520726f8 | ||
|
|
c7165f2154 | ||
|
|
717d7f46a6 | ||
|
|
35921e5893 | ||
|
|
fb777c7038 | ||
|
|
c7eeaeee19 | ||
|
|
d470867c10 | ||
|
|
0916d618b6 | ||
|
|
e4a5f47272 | ||
|
|
fee9394751 | ||
|
|
d2381d2053 | ||
|
|
7f2bdfb1df | ||
|
|
69372e4929 | ||
|
|
b45bb0c39a | ||
|
|
e6b58010d5 | ||
|
|
82faf74eb3 | ||
|
|
f96cd178c6 | ||
|
|
99b908f646 | ||
|
|
59c7590107 | ||
|
|
180ca0952b | ||
|
|
c0ce59a1ec | ||
|
|
a36e9fce43 | ||
|
|
da21ea8582 | ||
|
|
c8071a2a63 | ||
|
|
0fc7761fb9 | ||
|
|
4df1a6dbaa | ||
|
|
cd0204bb04 | ||
|
|
901ea4babd | ||
|
|
504e8528ce | ||
|
|
6f229b0b8c | ||
|
|
36b7148e30 | ||
|
|
0cdc780a5f | ||
|
|
59eaff7d26 | ||
|
|
8532baf8a5 | ||
|
|
9d021e012c | ||
|
|
22129c7220 | ||
|
|
ca1759abd9 | ||
|
|
1360b51eae | ||
|
|
193d51d49f | ||
|
|
bd07ee6c76 | ||
|
|
01eabca204 | ||
|
|
732181c3a6 | ||
|
|
a8c9fdbab7 | ||
|
|
27fd0b0347 | ||
|
|
3c7d570249 | ||
|
|
fe4c8a96da | ||
|
|
9603ef3552 | ||
|
|
e41cf16945 | ||
|
|
d88712be1d | ||
|
|
bb6bf1c526 | ||
|
|
4e21a99fd7 | ||
|
|
320757c747 | ||
|
|
18e3024604 | ||
|
|
188689f1fd | ||
|
|
1b6d7929d3 | ||
|
|
b61f18e6f4 | ||
|
|
899dbaa6b3 | ||
|
|
cd91fd5b2f | ||
|
|
cd1d05b21f | ||
|
|
d74eab2ae7 | ||
|
|
88367cf6b2 | ||
|
|
cced10b1c6 | ||
|
|
79cdaa2b40 | ||
|
|
4d9348761b | ||
|
|
6e5a5d0a41 | ||
|
|
02b0829877 | ||
|
|
c1734bac7f | ||
|
|
31fe45e61a | ||
|
|
9711d53d5e | ||
|
|
7e059581ad | ||
|
|
294dd3c58f | ||
|
|
ea58d0e48b | ||
|
|
85a8fd09d9 | ||
|
|
67212af6d7 | ||
|
|
a78bd9a285 | ||
|
|
791fd45bae | ||
|
|
264dc99a97 | ||
|
|
aa2f4146f7 | ||
|
|
9b47ed2e3f | ||
|
|
130764696d | ||
|
|
6a9ffeb101 | ||
|
|
a1afc4727e | ||
|
|
d80c76a4d3 | ||
|
|
c3ddd4f8c7 | ||
|
|
75e550acfe | ||
|
|
6c498dbf31 | ||
|
|
21cee3a1ba | ||
|
|
3b6e27f1fa | ||
|
|
d645985184 | ||
|
|
85c8fecc35 | ||
|
|
c499327e7d | ||
|
|
61b05ff31e | ||
|
|
1fdbef74c1 | ||
|
|
bd261b1c63 | ||
|
|
1a1ad30b66 | ||
|
|
2c4bef3524 | ||
|
|
dac472f6d1 | ||
|
|
9797da6023 | ||
|
|
c302cf6376 | ||
|
|
ff621c7916 | ||
|
|
d135ca1c4d | ||
|
|
61196b3da6 | ||
|
|
9a9d0ca906 | ||
|
|
c635a05deb | ||
|
|
ce0f23ff16 | ||
|
|
6db60dd641 | ||
|
|
77bee0a88e | ||
|
|
a4fe0d65ec | ||
|
|
9178cf8fe5 | ||
|
|
c7b5f89a4c | ||
|
|
acb785bb29 | ||
|
|
f57d946410 | ||
|
|
f7846c71d2 | ||
|
|
fd4e00d1fd | ||
|
|
304df956b9 | ||
|
|
76ca386abc | ||
|
|
259df4aa55 | ||
|
|
b885fdb742 | ||
|
|
5a34a35e86 | ||
|
|
5bf24ab7b4 | ||
|
|
886ab1238a | ||
|
|
107f39599e | ||
|
|
2ba53683df | ||
|
|
49470cdfdd | ||
|
|
b80c33320f | ||
|
|
fd2ed3aa49 | ||
|
|
dd8b9b2b16 | ||
|
|
e622c6d434 | ||
|
|
f997c702dd | ||
|
|
f87540454b | ||
|
|
98c56d505b | ||
|
|
241df209b6 | ||
|
|
dda03ae9d5 | ||
|
|
cf42f1f8b7 | ||
|
|
0b3ab7b382 | ||
|
|
52f1371042 | ||
|
|
f73b1af054 | ||
|
|
4471169fe4 | ||
|
|
72257d21ae | ||
|
|
d8dbde032a | ||
|
|
9af3408da6 | ||
|
|
26b5956894 | ||
|
|
4adbd1fd2c | ||
|
|
3dd9818d9a | ||
|
|
d7042fce29 | ||
|
|
2178caae0e | ||
|
|
f718e60269 | ||
|
|
a54c9f0dbc | ||
|
|
89dffc5989 | ||
|
|
74ff5ecb08 | ||
|
|
9cc4972f62 | ||
|
|
b43ebe3483 | ||
|
|
5fcb4174f0 | ||
|
|
2a15a2142d | ||
|
|
ade237079c | ||
|
|
4117b687e8 | ||
|
|
c6237ca193 | ||
|
|
d6a9d6707e | ||
|
|
ccc58d9dc1 | ||
|
|
7ac31c00fc | ||
|
|
6da46f30a2 | ||
|
|
4b59622348 | ||
|
|
9c060635df | ||
|
|
87f4b4e967 | ||
|
|
9923a03a12 | ||
|
|
4b87ffd5df | ||
|
|
57c5113554 | ||
|
|
25fdfc38f9 | ||
|
|
19ac07ca77 | ||
|
|
1260d9b9d1 | ||
|
|
e5c25aa867 | ||
|
|
f621d36981 | ||
|
|
bf6fda07d6 | ||
|
|
80082691b9 | ||
|
|
d50a825482 | ||
|
|
6aa32cba1c | ||
|
|
cb45cab5c7 | ||
|
|
8089187598 | ||
|
|
e8f5fd0a2a | ||
|
|
7e56354cb1 | ||
|
|
5880124676 | ||
|
|
385f9c1a04 | ||
|
|
b1801dd561 | ||
|
|
6b7c01dbaa | ||
|
|
4d71a194a8 | ||
|
|
49917fd4aa | ||
|
|
5aeb5bcec0 | ||
|
|
5bb584a2d2 | ||
|
|
a1fe87c7f7 | ||
|
|
9ae8f3c11f | ||
|
|
28d2f78465 | ||
|
|
709ee18144 | ||
|
|
876c1e96c4 | ||
|
|
305987e54a | ||
|
|
a3fe713e55 | ||
|
|
9f42fb9501 | ||
|
|
b6f0afb8ba | ||
|
|
f5fcca7b89 | ||
|
|
f02bacc71a | ||
|
|
c1312e0d01 | ||
|
|
d2f39a3b87 | ||
|
|
3e6ef1a6ee | ||
|
|
b78bc12fff | ||
|
|
f062d49bfd | ||
|
|
333b03e110 | ||
|
|
2a8bd0d2e8 | ||
|
|
996e85ad24 | ||
|
|
85cb09df34 | ||
|
|
b0b1477989 | ||
|
|
c62707cd7d | ||
|
|
38bf480a2e | ||
|
|
9125dbc5d7 | ||
|
|
04151adbfd | ||
|
|
1bfe163dff | ||
|
|
289b72c5f1 | ||
|
|
0a5f667a4f | ||
|
|
c954dab309 | ||
|
|
53c629aa15 | ||
|
|
028ed10393 | ||
|
|
891dab08d4 | ||
|
|
7f96d78946 | ||
|
|
596b9c6e28 | ||
|
|
374a32be9a | ||
|
|
32353c3852 | ||
|
|
ba7fc6468f | ||
|
|
4e8db91ff0 | ||
|
|
28d5d1de0c | ||
|
|
168d19cd56 | ||
|
|
4aa7cd7793 | ||
|
|
855101a2cd | ||
|
|
b74a06f336 | ||
|
|
09b84945ed | ||
|
|
9f34df0b4e | ||
|
|
c20ba0274b | ||
|
|
3c1e6cdf37 | ||
|
|
ecb7b0416b | ||
|
|
6258de8bef | ||
|
|
15373a35f9 | ||
|
|
bf4e7d89ec | ||
|
|
800c356b01 | ||
|
|
638f7983dd | ||
|
|
3ef4f11025 | ||
|
|
a42c624a7c | ||
|
|
ca772a6d28 | ||
|
|
a2ee2ccdde | ||
|
|
7e75683d76 | ||
|
|
51ba24f5e2 | ||
|
|
b28072fe84 | ||
|
|
d1ae2f1899 | ||
|
|
39a212bee9 | ||
|
|
ecde31ee1b | ||
|
|
d8dcf785f0 | ||
|
|
c5a719b176 | ||
|
|
1931973b54 | ||
|
|
75addfe8ea | ||
|
|
15f2add5e1 | ||
|
|
76749bb518 | ||
|
|
ca6614f591 | ||
|
|
396dbd745a | ||
|
|
2d0b4992a0 | ||
|
|
f194e62d64 | ||
|
|
8bc22afe12 | ||
|
|
6875084ca3 | ||
|
|
1d5c6d1812 | ||
|
|
1b85882aa7 | ||
|
|
94ea6bb449 | ||
|
|
dfa5df4f50 | ||
|
|
819d1ec7c4 | ||
|
|
ecdf502ba8 | ||
|
|
32c3dff48d | ||
|
|
480b49adb8 | ||
|
|
2c9085c0c5 | ||
|
|
4aa7993dc2 | ||
|
|
b0ee820828 | ||
|
|
b017b7bae9 | ||
|
|
885dcf1622 | ||
|
|
272e2738b5 | ||
|
|
dfb7d42d95 | ||
|
|
bf00b864f0 | ||
|
|
77567cdf4e | ||
|
|
57f53c647e | ||
|
|
4abe614300 | ||
|
|
709a787805 | ||
|
|
b0963fdfb9 | ||
|
|
22499f5d98 | ||
|
|
503396597e | ||
|
|
df7e98e0f2 | ||
|
|
85800fc41f | ||
|
|
cfa0d90725 | ||
|
|
7e76913add | ||
|
|
4f8f69bf76 | ||
|
|
0d4344e655 | ||
|
|
316c223346 | ||
|
|
921ba0f79e | ||
|
|
98b93f1b61 | ||
|
|
b54313a4b2 | ||
|
|
3792d0d151 | ||
|
|
638dac575d | ||
|
|
9e1f8f491d | ||
|
|
4a79790d30 | ||
|
|
d49508284f | ||
|
|
cfdb884818 | ||
|
|
7d59b37bf3 | ||
|
|
d402f46c3c | ||
|
|
c85a7a1fba | ||
|
|
b6bc0b1269 | ||
|
|
cbb1e08e26 | ||
|
|
918005477b | ||
|
|
25af719e20 | ||
|
|
e46dbe7ad3 | ||
|
|
dfd9ab1071 | ||
|
|
ea9c77045f | ||
|
|
d0e0f3e060 | ||
|
|
e93ecb52de | ||
|
|
43aa0a835c | ||
|
|
7af1ce554e | ||
|
|
9e2fa65670 | ||
|
|
ce25012973 |
81
CHANGELOG.md
81
CHANGELOG.md
@@ -1,9 +1,88 @@
|
|||||||
|
## v9.1
|
||||||
|
|
||||||
|
**Note**: Both Google and Mozilla recommend using the pkg installers instead of the dmg downloads for managed deployments. So far, Installomator has provided labels for both. (`googlechrome` and `googlechromepkg` or `firefox` and `firefoxpkg`, respectively) Since there are problems with the dmg downloads, a future release of Installomator will _disable_ the `firefox` and `googlechrome` dmg labels. You should switch to using the respective pkg labels instead.
|
||||||
|
|
||||||
|
- added option for Microsoft Endpoint Manager (Intune) to `LOGO` (#446)
|
||||||
|
- minor fixes (#427, #434, #436)
|
||||||
|
- the `googlechrome` label now always downloads the universal version (#430)
|
||||||
|
- new labels:
|
||||||
|
- 1passwordcli (#429)
|
||||||
|
- amazoncorretto8jdk (#423)
|
||||||
|
- autodeskfusion360admininstall (#447)
|
||||||
|
- axurerp10 (#439)
|
||||||
|
- calcservice (#426)
|
||||||
|
- clipy (#412)
|
||||||
|
- dockutil (#432)
|
||||||
|
- easyfind (#426)
|
||||||
|
- grammarly (#444)
|
||||||
|
- houdahspot (#426)
|
||||||
|
- macadminspython (#431)
|
||||||
|
- microsoftazuredatastudio (#438)
|
||||||
|
- nanosaur (#426)
|
||||||
|
- tembo (#426)
|
||||||
|
- wordservice (#426)
|
||||||
|
- xmenu (#426)
|
||||||
|
- updated labels:
|
||||||
|
- appcleaner (#428)
|
||||||
|
- dialog (#435, #437)
|
||||||
|
- googlechrome (#430)
|
||||||
|
- microsoftdefender (#440)
|
||||||
|
- supportapp (#426)
|
||||||
|
- zoom and zoomgov (#426, #433)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## v9.0.1
|
||||||
|
|
||||||
|
- improved logging levels throughout the script #408
|
||||||
|
- fixed a bug for `pkgindmg` style labels #408
|
||||||
|
- changed the criteria used to locate an app in the case the it cannot be found in the default locations, this should help with some apps with similar name (Virtual Box and Box Drive, #401) #413
|
||||||
|
- new label: WhiteBox Packages (`packages`) #415
|
||||||
|
- modified label: `loom` (added Apple silicon download) #417
|
||||||
|
|
||||||
|
## v9
|
||||||
|
|
||||||
|
- We have moved the root check to the beginning of the script, and improved DEBUG handling with two different modes. `DEBUG=0` is still for production, and `1` is still for the DEBUG we previously knew downloading to the directory it is running from, but `2` will download to temporary folder, will detect updates, but will not install anything, but it will notify the user (almost as running the script without root before).
|
||||||
|
- Added option to not interrupt Do Not Disturb full screen apps like Keynote or Zoom with `INTERRUPT_DND="no"`. Default is `"yes"` which is how it has worked until now.
|
||||||
|
- `pkgName` in a label can now be searched for. An example is logitechoptions, where only the name of the pkg is given, and not the exact file path to it.
|
||||||
|
- `LSMinimumSystemVersion` will now be honered, if the `Info.plist` in the app is specifying this. That means that an app that has this parameter in that file and it shows that the app requires a newer version of the OS than is currently installed, then we will not install it.
|
||||||
|
- New variable `RETURN_LABEL_NAME`. If given the value `1`, like `RETURN_LABEL_NAME=1` then Installomator only returns the name of the label. It makes for a better user friendly message for displaying in DEPNotify if that is integrated.
|
||||||
|
- Changed logic if `IGNORE_APP_STORE_APPS=yes`. Before this version a label like `microsoftonedrive` that was installed from App Store, and that we want to replace with the “ordinary” version, Installomator would still use `updateTool`, even though `IGNORE_APP_STORE_APPS=yes`. So we would have to have `INSTALL=force` in order to have the app replaced, as `updateTool` would be used. But now if `IGNORE_APP_STORE_APPS=yes` then `updateTool` will be not set, and the App Store app will be replaced. BUT if the installed software was not from App Store, then `updateTool` will not be used, and it would be a kind of a forced install (in the example of `microsoftonedrive`), except if the version is the same (where installation is skipped).
|
||||||
|
- Added variable `SYSTEMOWNER` that is used when copying files when installing. Default `0` is to change owner of the app to the current user on the Mac, like this user was installing this app themselves. When using `1` we will put “root:wheel” on the app, which can be useful for shared machines.
|
||||||
|
- Added option `curlOptions` to the labels. It can be filled with extra headers need for downloading the specific software. It needs to be an array, like `curlOptions=( )`. See “mocha”-software-labels.
|
||||||
|
|
||||||
|
Big changes to logging:
|
||||||
|
- Introducing variable `LOGGING`, that can be either of the logging levels
|
||||||
|
- Logging levels:
|
||||||
|
0: DEBUG Everything is logged
|
||||||
|
1: INFO Normal logging behavior
|
||||||
|
2: WARN
|
||||||
|
3: ERROR
|
||||||
|
4: REQ
|
||||||
|
- External logging to Datadog
|
||||||
|
- A function to shorten duplicate lines in installation logs or output of longer commands
|
||||||
|
- Ability to extract install.log in the time when Installomator was running, if further investigations needs to be done to logs
|
||||||
|
|
||||||
|
Fixes:
|
||||||
|
- Fixed a problem with pkgs: If they were mounted with .pkg in the name, then we would find the directory and not the pkg file itself.
|
||||||
|
- Minor fix for a check for a pkgName on a DMG. We used `ls` that would throw an error when not found, so the check was corrected.
|
||||||
|
|
||||||
|
## v8.0
|
||||||
|
|
||||||
|
- removed leading `0` from the version because it has lost all meaning (thanks to @grahampugh for the inspiration)
|
||||||
|
- Installomator now detects when an app is already installed, and will display notifications correctly the user based on if the app was updated or installed for the first time.
|
||||||
|
- New variables for labels that should be installed using CLI: `CLIInstaller` and `CLIArguments`. When the installer app is named differently than the installed app, then the variable `installerTool` should be used to name the app that should be located in the DMG or zip. See the label __adobecreativeclouddesktop__ to see its use.
|
||||||
|
- `buildLabel.sh` has been improved to build GitHub software labels much easier. In essense if the URL contains github.com, then it will try to find if it's the latest version or if variable `archiveName` is needed for finding the software. Also improved messaging throughout the script, as well as handling a situation where a pkg does not include a “Distribution” file, but a “PackageInfo”.
|
||||||
|
- MDM script extended with `caffeinate` so Mac will not go to sleep during the time it takes installomator to run. Especially during setup, this can be useful.
|
||||||
|
- Microsoft labels with `updateTool` variable, is updated to run `msupdate --list` before running the updateTool directly. Problems have been reported that the update would fail if the `--list` parameter for the command was not run first. This should help with the Jamf agent stalling during installation.
|
||||||
|
- Added bunch of new labels, and improved others.
|
||||||
|
|
||||||
## v0.7
|
## v0.7
|
||||||
|
|
||||||
- default for `BLOCKING_PROCESS_ACTION`is now `BLOCKING_PROCESS_ACTION=tell_user` and not `prompt_user`. It will demand the user to quit the app to get it updated, and not present any option to skip it. In considering various use cases in different MDM solutions this is the best option going forward. Users usually choose to update, and is most often not bothered much with this information. If it's absoultely a bad time, then they can move the dialog box to the side, and click it when ready.
|
- default for `BLOCKING_PROCESS_ACTION`is now `BLOCKING_PROCESS_ACTION=tell_user` and not `prompt_user`. It will demand the user to quit the app to get it updated, and not present any option to skip it. In considering various use cases in different MDM solutions this is the best option going forward. Users usually choose to update, and is most often not bothered much with this information. If it's absoultely a bad time, then they can move the dialog box to the side, and click it when ready.
|
||||||
- script is now assembled from fragments. This helps avoid merging conflicts on git and allows the core team to work on the script logic while also accepting new labels. See the "Assemble Script ReadMe" for details.
|
- script is now assembled from fragments. This helps avoid merging conflicts on git and allows the core team to work on the script logic while also accepting new labels. See the "Assemble Script ReadMe" for details.
|
||||||
- We now detect App Store installed apps, and we do not replace them automatically. An example is Slack that will loose all settings if it is suddenly changed from App Store version to the "web" version (they differ in the handling of settings files). If `INSTALL=force` then we will replace the App Store app. We log all this.
|
- We now detect App Store installed apps, and we do not replace them automatically. An example is Slack that will loose all settings if it is suddenly changed from App Store version to the "web" version (they differ in the handling of settings files). If `INSTALL=force` then we will replace the App Store app. We log all this.
|
||||||
- Change in finding installed apps. We now look in /Applications and /Applications/Utilities first. If not found there, we use spotligt to find it. (We discovered a problem when a user has Parallels Windows installed with Microsoft Edge in it. Then Installomator wanted to update the app all the time, becaus spotligt found that Windows version of the app that Parallels created.)
|
- Change in finding installed apps. We now look in /Applications and /Applications/Utilities first. If not found there, we use spotligt to find it. (We discovered a problem when a user has Parallels Windows installed with Microsoft Edge in it. Then Installomator wanted to update the app all the time, becaus spotlight found that Windows version of the app that Parallels created.)
|
||||||
- Added bunch of new labels, and improved others.
|
- Added bunch of new labels, and improved others.
|
||||||
- Renamed `buildCaseStatement.sh` to `buildLabel.sh` and improved it a lot. It is a great start when figuring out how to create a new label for an app, or a piece of software. Look at the tutorials in our wiki.
|
- Renamed `buildCaseStatement.sh` to `buildLabel.sh` and improved it a lot. It is a great start when figuring out how to create a new label for an app, or a piece of software. Look at the tutorials in our wiki.
|
||||||
- Mosyle changed their app name from Business to Self-Service
|
- Mosyle changed their app name from Business to Self-Service
|
||||||
|
|||||||
49
CONTRIBUTING.md
Normal file
49
CONTRIBUTING.md
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
# Contributing to Installomator
|
||||||
|
|
||||||
|
__Please note, that if you are contributing to this project with new labels or other suggestions in PRs, please put your changes in the files below `fragments`-folder. DO NOT edit the full `Installomator.sh` script. The full script is now a build of the fragments, and will be overwritten.__
|
||||||
|
|
||||||
|
We try to keep the script as short as possible, and with more than 300 labels, we can save 300 lines in the script, if we do not have credit lines on each of these. So we are thankful for your contribution, but we will be removing these lines in the coming releases.
|
||||||
|
|
||||||
|
## Branches
|
||||||
|
|
||||||
|
The branch list is as follows:
|
||||||
|
|
||||||
|
- `release`: this branch will have the latest released version
|
||||||
|
- `main`: (default) this branch will be the latest release plus new and updated app labels, and critical bug fixes
|
||||||
|
- `dev`: this will contain new and updated app labels, as well as any other code changes
|
||||||
|
there will be other branches for new features and testing
|
||||||
|
|
||||||
|
This should allow the contributing team to release minor updates for new and updated app labels while also work on new features for the next major release.
|
||||||
|
|
||||||
|
With all the new branches, your local repo may get confused. If you don’t have local changes, it is easiest to delete your local repo and re-clone it. If you have local changes you want to preserve, then you should commit those to a local branch, pull the latest changes `git pull --all`, then delete the old master branch: `git branch -d master`.
|
||||||
|
|
||||||
|
Make sure you branch off of main for new and updated labels and off of `dev` for other code changes. Thank you for contributing!
|
||||||
|
|
||||||
|
## Labels
|
||||||
|
|
||||||
|
If you need a new label for a piece of software, please take a look at the tutorials in the Wiki, if those can be helpful for starting out on the creation of the label.
|
||||||
|
|
||||||
|
We expect you to try out finding the __version__ of the software online, so that `appNewVersion` can be filled in the label. It helps a lot when the software needs update, and greatly improve user experience.
|
||||||
|
|
||||||
|
Please document what you found out about the __version__ of the software if it's not included. We will not accept a new label if this is not documented, we will ask about this if it was not included. This is very important for the quality and reliability of Installomator.
|
||||||
|
|
||||||
|
When creating a new label, please file a pull request (PR). And feel free to ask questions or make your comments about what else is needed, if we should take a look at the label, or help out in finding the version or isolating URLs or anything else.
|
||||||
|
|
||||||
|
Please include the log of installing this label in the description, like this:
|
||||||
|
```
|
||||||
|
% /Users/st/Documents/GitHub/Installomator/utils/assemble.sh software
|
||||||
|
2021-11-24 10:07:19 software ################## Start Installomator v. 0.8.0
|
||||||
|
2021-11-24 10:07:19 software ################## software
|
||||||
|
2021-11-24 10:07:19 software DEBUG mode 1 enabled.
|
||||||
|
```
|
||||||
|
|
||||||
|
Please have one label per PR, so we can separate these. Also if you change/fix a label.
|
||||||
|
|
||||||
|
Thank you very much for your contribution!
|
||||||
|
|
||||||
|
|
||||||
|
## Issues
|
||||||
|
|
||||||
|
Do not create an issue just when you have a questions, but do file an issue or pull request (PR) for bugs or wrong behavior. Include the full log and include the version of Installomator you're running.
|
||||||
|
|
||||||
|
When in doubt, use the MacAdmins.org Slack as described in [README.md](https://github.com/Installomator/Installomator/)
|
||||||
1954
Installomator.sh
1954
Installomator.sh
File diff suppressed because it is too large
Load Diff
84
Labels.txt
84
Labels.txt
@@ -1,9 +1,11 @@
|
|||||||
1password7
|
1password7
|
||||||
|
1passwordcli
|
||||||
4kvideodownloader
|
4kvideodownloader
|
||||||
8x8
|
8x8
|
||||||
abstract
|
abstract
|
||||||
adobebrackets
|
adobebrackets
|
||||||
adobeconnect
|
adobeconnect
|
||||||
|
adobecreativeclouddesktop
|
||||||
adobereaderdc
|
adobereaderdc
|
||||||
adobereaderdc-install
|
adobereaderdc-install
|
||||||
adobereaderdc-update
|
adobereaderdc-update
|
||||||
@@ -11,15 +13,18 @@ aircall
|
|||||||
airserver
|
airserver
|
||||||
airtame
|
airtame
|
||||||
aldente
|
aldente
|
||||||
|
alephone
|
||||||
alfred
|
alfred
|
||||||
alttab
|
alttab
|
||||||
amazonchime
|
amazonchime
|
||||||
|
amazoncorretto8jdk
|
||||||
amazonworkspaces
|
amazonworkspaces
|
||||||
androidfiletransfer
|
androidfiletransfer
|
||||||
anydesk
|
anydesk
|
||||||
apparency
|
apparency
|
||||||
appcleaner
|
appcleaner
|
||||||
applenyfonts
|
applenyfonts
|
||||||
|
applesfarabic
|
||||||
applesfcompact
|
applesfcompact
|
||||||
applesfmono
|
applesfmono
|
||||||
applesfpro
|
applesfpro
|
||||||
@@ -31,11 +36,14 @@ atext
|
|||||||
atom
|
atom
|
||||||
audacity
|
audacity
|
||||||
authydesktop
|
authydesktop
|
||||||
|
autodeskfusion360admininstall
|
||||||
autodmg
|
autodmg
|
||||||
autopkgr
|
autopkgr
|
||||||
aviatrix
|
aviatrix
|
||||||
awscli2
|
awscli2
|
||||||
awsvpnclient
|
awsvpnclient
|
||||||
|
axurerp10
|
||||||
|
azuredatastudio
|
||||||
balenaetcher
|
balenaetcher
|
||||||
balsamiqwireframes
|
balsamiqwireframes
|
||||||
bartender
|
bartender
|
||||||
@@ -49,15 +57,21 @@ boxdrive
|
|||||||
boxsync
|
boxsync
|
||||||
boxtools
|
boxtools
|
||||||
brave
|
brave
|
||||||
|
bugdom
|
||||||
caffeine
|
caffeine
|
||||||
cakebrew
|
cakebrew
|
||||||
|
calcservice
|
||||||
calibre
|
calibre
|
||||||
camostudio
|
camostudio
|
||||||
camtasia
|
camtasia
|
||||||
|
canva
|
||||||
|
chatwork
|
||||||
cisdem-documentreader
|
cisdem-documentreader
|
||||||
citrixworkspace
|
citrixworkspace
|
||||||
clevershare2
|
clevershare2
|
||||||
clickshare
|
clickshare
|
||||||
|
clipy
|
||||||
|
closeio
|
||||||
cloudya
|
cloudya
|
||||||
code42
|
code42
|
||||||
coderunner
|
coderunner
|
||||||
@@ -66,6 +80,7 @@ cormorant
|
|||||||
craftmanager
|
craftmanager
|
||||||
cryptomator
|
cryptomator
|
||||||
cyberduck
|
cyberduck
|
||||||
|
daisydisk
|
||||||
dangerzone
|
dangerzone
|
||||||
darktable
|
darktable
|
||||||
dbeaverce
|
dbeaverce
|
||||||
@@ -76,21 +91,29 @@ desktoppr
|
|||||||
detectxswift
|
detectxswift
|
||||||
devonthink
|
devonthink
|
||||||
dialog
|
dialog
|
||||||
|
dialpad
|
||||||
discord
|
discord
|
||||||
|
diskspace
|
||||||
docker
|
docker
|
||||||
|
dockutil
|
||||||
drift
|
drift
|
||||||
dropbox
|
dropbox
|
||||||
easeusdatarecoverywizard
|
easeusdatarecoverywizard
|
||||||
|
easyfind
|
||||||
egnyte
|
egnyte
|
||||||
element
|
element
|
||||||
eraseinstall
|
eraseinstall
|
||||||
|
eshareosx
|
||||||
etrecheck
|
etrecheck
|
||||||
evernote
|
evernote
|
||||||
exelbanstats
|
exelbanstats
|
||||||
|
exifrenamer
|
||||||
fantastical
|
fantastical
|
||||||
|
fastscripts
|
||||||
favro
|
favro
|
||||||
ferdi
|
ferdi
|
||||||
figma
|
figma
|
||||||
|
findanyfile
|
||||||
firefox
|
firefox
|
||||||
firefox_da
|
firefox_da
|
||||||
firefox_intl
|
firefox_intl
|
||||||
@@ -99,6 +122,7 @@ firefoxesr_intl
|
|||||||
firefoxesrpkg
|
firefoxesrpkg
|
||||||
firefoxpkg
|
firefoxpkg
|
||||||
flowjo
|
flowjo
|
||||||
|
flux
|
||||||
front
|
front
|
||||||
fsmonitor
|
fsmonitor
|
||||||
gimp
|
gimp
|
||||||
@@ -115,6 +139,7 @@ googlesoftwareupdate
|
|||||||
gotomeeting
|
gotomeeting
|
||||||
gpgsuite
|
gpgsuite
|
||||||
gpgsync
|
gpgsync
|
||||||
|
grammarly
|
||||||
grandperspective
|
grandperspective
|
||||||
grasshopper
|
grasshopper
|
||||||
gyazo
|
gyazo
|
||||||
@@ -122,17 +147,22 @@ gyazogif
|
|||||||
hancock
|
hancock
|
||||||
handbrake
|
handbrake
|
||||||
hazel
|
hazel
|
||||||
|
houdahspot
|
||||||
hpeasyadmin
|
hpeasyadmin
|
||||||
hpeasystart
|
hpeasystart
|
||||||
hyper
|
hyper
|
||||||
|
ibarcoder
|
||||||
icons
|
icons
|
||||||
|
iina
|
||||||
imazingprofileeditor
|
imazingprofileeditor
|
||||||
inkscape
|
inkscape
|
||||||
insomnia
|
insomnia
|
||||||
|
installomator
|
||||||
installomator_theile
|
installomator_theile
|
||||||
intellijideace
|
intellijideace
|
||||||
istatmenus
|
istatmenus
|
||||||
iterm2
|
iterm2
|
||||||
|
itsycal
|
||||||
jabradirect
|
jabradirect
|
||||||
jamfconnect
|
jamfconnect
|
||||||
jamfconnectconfiguration
|
jamfconnectconfiguration
|
||||||
@@ -146,6 +176,7 @@ jetbrainsintellijideace
|
|||||||
jetbrainsphpstorm
|
jetbrainsphpstorm
|
||||||
jetbrainspycharm
|
jetbrainspycharm
|
||||||
jetbrainspycharmce
|
jetbrainspycharmce
|
||||||
|
jetbrainsrubymine
|
||||||
jetbrainstoolbox
|
jetbrainstoolbox
|
||||||
jetbrainswebstorm
|
jetbrainswebstorm
|
||||||
karabinerelements
|
karabinerelements
|
||||||
@@ -162,16 +193,26 @@ launchbar
|
|||||||
lexarrecoverytool
|
lexarrecoverytool
|
||||||
libreoffice
|
libreoffice
|
||||||
logitechoptions
|
logitechoptions
|
||||||
|
logseq
|
||||||
loom
|
loom
|
||||||
|
lowprofile
|
||||||
lucifer
|
lucifer
|
||||||
lulu
|
lulu
|
||||||
|
macadminspython
|
||||||
|
maccyapp
|
||||||
macfuse
|
macfuse
|
||||||
|
macports
|
||||||
malwarebytes
|
malwarebytes
|
||||||
|
marathon
|
||||||
|
marathon2
|
||||||
|
marathoninfinity
|
||||||
mattermost
|
mattermost
|
||||||
menumeters
|
menumeters
|
||||||
microsoftautoupdate
|
microsoftautoupdate
|
||||||
|
microsoftazuredatastudio
|
||||||
microsoftazurestorageexplorer
|
microsoftazurestorageexplorer
|
||||||
microsoftcompanyportal
|
microsoftcompanyportal
|
||||||
|
microsoftdefender
|
||||||
microsoftdefenderatp
|
microsoftdefenderatp
|
||||||
microsoftedge
|
microsoftedge
|
||||||
microsoftedgeconsumerstable
|
microsoftedgeconsumerstable
|
||||||
@@ -192,14 +233,23 @@ microsoftvisualstudiocode
|
|||||||
microsoftword
|
microsoftword
|
||||||
microsoftyammer
|
microsoftyammer
|
||||||
miro
|
miro
|
||||||
|
mobikinassistantforandroid
|
||||||
|
mochakeyboard
|
||||||
|
mochatelnet
|
||||||
|
mochatn3270
|
||||||
|
mochatn3812
|
||||||
|
mochatn5250
|
||||||
montereyblocker
|
montereyblocker
|
||||||
|
mowgliiitsycal
|
||||||
musescore
|
musescore
|
||||||
muzzle
|
muzzle
|
||||||
|
nanosaur
|
||||||
netnewswire
|
netnewswire
|
||||||
nextcloud
|
nextcloud
|
||||||
nomad
|
nomad
|
||||||
nomadlogin
|
nomadlogin
|
||||||
notion
|
notion
|
||||||
|
nudge
|
||||||
nvivo
|
nvivo
|
||||||
obs
|
obs
|
||||||
obsidian
|
obsidian
|
||||||
@@ -217,7 +267,12 @@ onlyofficedesktop
|
|||||||
openvpnconnect
|
openvpnconnect
|
||||||
openvpnconnectv3
|
openvpnconnectv3
|
||||||
opera
|
opera
|
||||||
|
ottomatic
|
||||||
|
overflow
|
||||||
pacifist
|
pacifist
|
||||||
|
packages
|
||||||
|
pandoc
|
||||||
|
paretosecurity
|
||||||
parsec
|
parsec
|
||||||
pdfsam
|
pdfsam
|
||||||
perimeter81
|
perimeter81
|
||||||
@@ -227,16 +282,24 @@ platypus
|
|||||||
plisteditpro
|
plisteditpro
|
||||||
postman
|
postman
|
||||||
prism9
|
prism9
|
||||||
|
pritunl
|
||||||
privileges
|
privileges
|
||||||
proctortrack
|
proctortrack
|
||||||
|
promiseutility
|
||||||
promiseutilityr
|
promiseutilityr
|
||||||
|
protonvpn
|
||||||
proxyman
|
proxyman
|
||||||
pycharmce
|
pycharmce
|
||||||
pymol
|
pymol
|
||||||
r
|
r
|
||||||
ramboxce
|
ramboxce
|
||||||
|
rancherdesktop
|
||||||
rectangle
|
rectangle
|
||||||
redeye
|
redeye
|
||||||
|
remotedesktopmanagerenterprise
|
||||||
|
remotedesktopmanagerfree
|
||||||
|
remotix
|
||||||
|
remotixagent
|
||||||
resiliosynchome
|
resiliosynchome
|
||||||
retrobatch
|
retrobatch
|
||||||
ricohpsprinters
|
ricohpsprinters
|
||||||
@@ -254,6 +317,9 @@ scaleft
|
|||||||
screamingfrogseospider
|
screamingfrogseospider
|
||||||
screencloudplayer
|
screencloudplayer
|
||||||
screenflick
|
screenflick
|
||||||
|
sdnotary
|
||||||
|
secretive
|
||||||
|
sequelpro
|
||||||
sfsymbols
|
sfsymbols
|
||||||
shield
|
shield
|
||||||
sidekick
|
sidekick
|
||||||
@@ -262,6 +328,7 @@ silnite
|
|||||||
sirimote
|
sirimote
|
||||||
sizeup
|
sizeup
|
||||||
sketch
|
sketch
|
||||||
|
sketchupviewer
|
||||||
skype
|
skype
|
||||||
slack
|
slack
|
||||||
smartgit
|
smartgit
|
||||||
@@ -275,31 +342,42 @@ sonoss2
|
|||||||
sourcetree
|
sourcetree
|
||||||
splashtopsos
|
splashtopsos
|
||||||
spotify
|
spotify
|
||||||
|
sqlpropostgres
|
||||||
|
sqlprostudio
|
||||||
|
steelseriesengine
|
||||||
|
strongsync
|
||||||
sublimetext
|
sublimetext
|
||||||
|
superhuman
|
||||||
supportapp
|
supportapp
|
||||||
suspiciouspackage
|
suspiciouspackage
|
||||||
|
swiftdialog
|
||||||
swiftruntimeforcommandlinetools
|
swiftruntimeforcommandlinetools
|
||||||
sync
|
sync
|
||||||
tableaudesktop
|
tableaudesktop
|
||||||
|
tableaupublic
|
||||||
tableaureader
|
tableaureader
|
||||||
tageditor
|
tageditor
|
||||||
|
talkdeskcallbar
|
||||||
taskpaper
|
taskpaper
|
||||||
teamviewer
|
teamviewer
|
||||||
teamviewerhost
|
teamviewerhost
|
||||||
teamviewerqs
|
teamviewerqs
|
||||||
techsmithcapture
|
techsmithcapture
|
||||||
telegram
|
telegram
|
||||||
|
tembo
|
||||||
textexpander
|
textexpander
|
||||||
textmate
|
textmate
|
||||||
theunarchiver
|
theunarchiver
|
||||||
things
|
things
|
||||||
thunderbird
|
thunderbird
|
||||||
|
tidal
|
||||||
toggltrack
|
toggltrack
|
||||||
tom4aconverter
|
tom4aconverter
|
||||||
torbrowser
|
torbrowser
|
||||||
trex
|
trex
|
||||||
tunnelbear
|
tunnelbear
|
||||||
tunnelblick
|
tunnelblick
|
||||||
|
typora
|
||||||
umbrellaroamingclient
|
umbrellaroamingclient
|
||||||
uniconverter
|
uniconverter
|
||||||
universaltypeclient
|
universaltypeclient
|
||||||
@@ -307,6 +385,7 @@ utm
|
|||||||
vagrant
|
vagrant
|
||||||
vanilla
|
vanilla
|
||||||
veracrypt
|
veracrypt
|
||||||
|
vimac
|
||||||
virtualbox
|
virtualbox
|
||||||
viscosity
|
viscosity
|
||||||
visualstudiocode
|
visualstudiocode
|
||||||
@@ -314,6 +393,7 @@ vivaldi
|
|||||||
vlc
|
vlc
|
||||||
vmwarehorizonclient
|
vmwarehorizonclient
|
||||||
vscodium
|
vscodium
|
||||||
|
wacomdrivers
|
||||||
wallyezflash
|
wallyezflash
|
||||||
webex
|
webex
|
||||||
webexmeetings
|
webexmeetings
|
||||||
@@ -322,15 +402,18 @@ whatsapp
|
|||||||
wickrme
|
wickrme
|
||||||
wickrpro
|
wickrpro
|
||||||
wireshark
|
wireshark
|
||||||
|
wordservice
|
||||||
wwdc
|
wwdc
|
||||||
xeroxphaser7800
|
xeroxphaser7800
|
||||||
xink
|
xink
|
||||||
|
xmenu
|
||||||
xquartz
|
xquartz
|
||||||
yed
|
yed
|
||||||
yubikeymanagerqt
|
yubikeymanagerqt
|
||||||
zappy
|
zappy
|
||||||
zeplin
|
zeplin
|
||||||
zohoworkdrive
|
zohoworkdrive
|
||||||
|
zohoworkdrivetruesync
|
||||||
zoom
|
zoom
|
||||||
zoomclient
|
zoomclient
|
||||||
zoomgov
|
zoomgov
|
||||||
@@ -338,4 +421,5 @@ zoomrooms
|
|||||||
zulujdk11
|
zulujdk11
|
||||||
zulujdk13
|
zulujdk13
|
||||||
zulujdk15
|
zulujdk15
|
||||||
|
zulujdk17
|
||||||
zulujdk8
|
zulujdk8
|
||||||
|
|||||||
169
MDM/App script.sh
Executable file
169
MDM/App script.sh
Executable file
@@ -0,0 +1,169 @@
|
|||||||
|
#!/bin/zsh
|
||||||
|
# Installation using Installomator
|
||||||
|
what="brave" # enter the software to install
|
||||||
|
|
||||||
|
# To be used as a script sent out from a MDM.
|
||||||
|
# Fill the variable "what" above with a label.
|
||||||
|
# Script will run this label.
|
||||||
|
###############################################
|
||||||
|
|
||||||
|
# No sleeping
|
||||||
|
/usr/bin/caffeinate -d -i -m -u &
|
||||||
|
caffeinatepid=$!
|
||||||
|
caffexit () {
|
||||||
|
kill "$caffeinatepid"
|
||||||
|
pkill caffeinate
|
||||||
|
exit $1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Verify that Installomator has been installed
|
||||||
|
destFile="/usr/local/Installomator/Installomator.sh"
|
||||||
|
if [ ! -e "${destFile}" ]; then
|
||||||
|
echo "Installomator not found here:"
|
||||||
|
echo "${destFile}"
|
||||||
|
echo "Exiting."
|
||||||
|
caffexit 99
|
||||||
|
fi
|
||||||
|
|
||||||
|
${destFile} ${what} LOGO=mosyleb BLOCKING_PROCESS_ACTION=tell_user #NOTIFY=all #INSTALL=force
|
||||||
|
if [ $? != 0 ]; then
|
||||||
|
# This is currently not working in Mosyle, that will ignore script errors. Please request support for this from Mosyle!
|
||||||
|
echo "Error installing ${what}. Exit code $?"
|
||||||
|
caffexit $?
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[$(DATE)][LOG-END]"
|
||||||
|
|
||||||
|
caffexit 0
|
||||||
|
|
||||||
|
# notify behavior
|
||||||
|
# NOTIFY=success
|
||||||
|
# options:
|
||||||
|
# - success notify the user on success
|
||||||
|
# - silent no notifications
|
||||||
|
# - all all notifications (great for Self Service installation)
|
||||||
|
|
||||||
|
|
||||||
|
# behavior when blocking processes are found
|
||||||
|
# BLOCKING_PROCESS_ACTION=tell_user
|
||||||
|
# options:
|
||||||
|
# - ignore continue even when blocking processes are found
|
||||||
|
# - quit app will be told to quit nicely, if running
|
||||||
|
# - quit_kill told to quit twice, then it will be killed
|
||||||
|
# Could be great for service apps, if they do not respawn
|
||||||
|
# - silent_fail exit script without prompt or installation
|
||||||
|
# - prompt_user show a user dialog for each blocking process found
|
||||||
|
# abort after three attempts to quit
|
||||||
|
# (only if user accepts to quit the apps, otherwise
|
||||||
|
# the update is cancelled).
|
||||||
|
# - prompt_user_then_kill
|
||||||
|
# show a user dialog for each blocking process found,
|
||||||
|
# attempt to quit two times, kill the process finally
|
||||||
|
# - prompt_user_loop
|
||||||
|
# Like prompt-user, but clicking "Not Now", will just wait an hour,
|
||||||
|
# and then it will ask again.
|
||||||
|
# WARNING! It might block the MDM agent on the machine, as
|
||||||
|
# the scripts gets stuct in waiting until the hour has passed,
|
||||||
|
# possibly blocking for other management actions in this time.
|
||||||
|
# - tell_user User will be showed a notification about the important update,
|
||||||
|
# but user is only allowed to quit and continue, and then we
|
||||||
|
# ask the app to quit.
|
||||||
|
# - tell_user_then_kill
|
||||||
|
# Show dialog 2 times, and if the quitting fails, the
|
||||||
|
# blocking processes will be killed.
|
||||||
|
# - kill kill process without prompting or giving the user a chance to save
|
||||||
|
|
||||||
|
|
||||||
|
# logo-icon used in dialog boxes if app is blocking
|
||||||
|
# LOGO=appstore
|
||||||
|
# options:
|
||||||
|
# - appstore Icon is Apple App Store (default)
|
||||||
|
# - jamf JAMF Pro
|
||||||
|
# - mosyleb Mosyle Business
|
||||||
|
# - mosylem Mosyle Manager (Education)
|
||||||
|
# - addigy Addigy
|
||||||
|
# path can also be set in the command call, and if file exists, it will be used.
|
||||||
|
# Like 'LOGO="/System/Applications/App\ Store.app/Contents/Resources/AppIcon.icns"'
|
||||||
|
# (spaces have to be escaped).
|
||||||
|
|
||||||
|
|
||||||
|
# App Store apps handling
|
||||||
|
# IGNORE_APP_STORE_APPS=no
|
||||||
|
# options:
|
||||||
|
# - no If installed app is from App Store (which include VPP installed apps)
|
||||||
|
# it will not be touched, no matter it's version (default)
|
||||||
|
# - yes Replace App Store (and VPP) version of app and handle future
|
||||||
|
# updates using Installomator, even if latest version.
|
||||||
|
# Shouldn’t give any problems for the user in most cases.
|
||||||
|
# Known bad example: Slack will loose all settings.
|
||||||
|
|
||||||
|
|
||||||
|
# install behavior
|
||||||
|
# INSTALL=""
|
||||||
|
# options:
|
||||||
|
# - When not set, software will only be installed
|
||||||
|
# if it is newer/different in version
|
||||||
|
# - force Install even if it’s the same version
|
||||||
|
|
||||||
|
|
||||||
|
# Re-opening of closed app
|
||||||
|
# REOPEN="yes"
|
||||||
|
# options:
|
||||||
|
# - yes App wil be reopened if it was closed
|
||||||
|
# - no App not reopened
|
||||||
|
|
||||||
|
|
||||||
|
########################
|
||||||
|
# Often used labels:
|
||||||
|
########################
|
||||||
|
|
||||||
|
# firefox
|
||||||
|
# firefox_intl
|
||||||
|
# brave
|
||||||
|
# torbrowser
|
||||||
|
# googlechrome
|
||||||
|
# netnewswire
|
||||||
|
|
||||||
|
# adobereaderdc
|
||||||
|
# textmate
|
||||||
|
|
||||||
|
# cyberduck
|
||||||
|
# keka
|
||||||
|
# theunarchiver
|
||||||
|
|
||||||
|
# vlc
|
||||||
|
# handbrake
|
||||||
|
|
||||||
|
# inkscape
|
||||||
|
|
||||||
|
# signal
|
||||||
|
# telegram
|
||||||
|
# whatsapp
|
||||||
|
|
||||||
|
# hazel
|
||||||
|
# devonthink
|
||||||
|
|
||||||
|
# teamviewerqs
|
||||||
|
# zoom
|
||||||
|
|
||||||
|
# malwarebytes
|
||||||
|
# githubdesktop
|
||||||
|
# sublimetext
|
||||||
|
# textmate
|
||||||
|
# visualstudiocode
|
||||||
|
|
||||||
|
# microsoftskypeforbusiness
|
||||||
|
# microsoftteams
|
||||||
|
# microsoftyammer
|
||||||
|
# microsoftedgeenterprisestable
|
||||||
|
# microsoftedgeconsumerstable
|
||||||
|
# microsoftsharepointplugin
|
||||||
|
# microsoftdefenderatp
|
||||||
|
|
||||||
|
# googledrivefilestream
|
||||||
|
|
||||||
|
# cdef
|
||||||
|
# desktoppr
|
||||||
|
# supportapp
|
||||||
|
# xink
|
||||||
|
# wwdc
|
||||||
177
MDM/App-loop script.sh
Executable file
177
MDM/App-loop script.sh
Executable file
@@ -0,0 +1,177 @@
|
|||||||
|
#!/bin/zsh
|
||||||
|
# Installation using Installomator
|
||||||
|
what="microsoftteams microsoftyammer firefox bravebrowser cyberduck vlc signal" # enter the software to install separated with spaces
|
||||||
|
|
||||||
|
# To be used as a script sent out from a MDM.
|
||||||
|
# Fill the variable "what" above with labels separated by space " ".
|
||||||
|
# Script will loop through these labels.
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
# No sleeping
|
||||||
|
/usr/bin/caffeinate -d -i -m -u &
|
||||||
|
caffeinatepid=$!
|
||||||
|
caffexit () {
|
||||||
|
kill "$caffeinatepid"
|
||||||
|
pkill caffeinate
|
||||||
|
exit $1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Count errors
|
||||||
|
errorCount=0
|
||||||
|
|
||||||
|
# Verify that Installomator has been installed
|
||||||
|
destFile="/usr/local/Installomator/Installomator.sh"
|
||||||
|
if [ ! -e "${destFile}" ]; then
|
||||||
|
echo "Installomator not found here:"
|
||||||
|
echo "${destFile}"
|
||||||
|
echo "Exiting."
|
||||||
|
caffexit 99
|
||||||
|
fi
|
||||||
|
|
||||||
|
for item in $what; do
|
||||||
|
#echo $item
|
||||||
|
${destFile} ${item} LOGO=mosyleb BLOCKING_PROCESS_ACTION=tell_user #NOTIFY=all #INSTALL=force
|
||||||
|
if [ $? != 0 ]; then
|
||||||
|
# This is currently not working in Mosyle, that will ignore script errors. Please request support for this from Mosyle!
|
||||||
|
echo "[$(DATE)] Error installing ${item}. Exit code $?"
|
||||||
|
let errorCount++
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "Errors: $errorCount"
|
||||||
|
echo "[$(DATE)][LOG-END]"
|
||||||
|
|
||||||
|
caffexit $errorCount
|
||||||
|
|
||||||
|
# notify behavior
|
||||||
|
# NOTIFY=success
|
||||||
|
# options:
|
||||||
|
# - success notify the user on success
|
||||||
|
# - silent no notifications
|
||||||
|
# - all all notifications (great for Self Service installation)
|
||||||
|
|
||||||
|
|
||||||
|
# behavior when blocking processes are found
|
||||||
|
# BLOCKING_PROCESS_ACTION=tell_user
|
||||||
|
# options:
|
||||||
|
# - ignore continue even when blocking processes are found
|
||||||
|
# - quit app will be told to quit nicely, if running
|
||||||
|
# - quit_kill told to quit twice, then it will be killed
|
||||||
|
# Could be great for service apps, if they do not respawn
|
||||||
|
# - silent_fail exit script without prompt or installation
|
||||||
|
# - prompt_user show a user dialog for each blocking process found
|
||||||
|
# abort after three attempts to quit
|
||||||
|
# (only if user accepts to quit the apps, otherwise
|
||||||
|
# the update is cancelled).
|
||||||
|
# - prompt_user_then_kill
|
||||||
|
# show a user dialog for each blocking process found,
|
||||||
|
# attempt to quit two times, kill the process finally
|
||||||
|
# - prompt_user_loop
|
||||||
|
# Like prompt-user, but clicking "Not Now", will just wait an hour,
|
||||||
|
# and then it will ask again.
|
||||||
|
# WARNING! It might block the MDM agent on the machine, as
|
||||||
|
# the scripts gets stuct in waiting until the hour has passed,
|
||||||
|
# possibly blocking for other management actions in this time.
|
||||||
|
# - tell_user User will be showed a notification about the important update,
|
||||||
|
# but user is only allowed to quit and continue, and then we
|
||||||
|
# ask the app to quit.
|
||||||
|
# - tell_user_then_kill
|
||||||
|
# Show dialog 2 times, and if the quitting fails, the
|
||||||
|
# blocking processes will be killed.
|
||||||
|
# - kill kill process without prompting or giving the user a chance to save
|
||||||
|
|
||||||
|
|
||||||
|
# logo-icon used in dialog boxes if app is blocking
|
||||||
|
# LOGO=appstore
|
||||||
|
# options:
|
||||||
|
# - appstore Icon is Apple App Store (default)
|
||||||
|
# - jamf JAMF Pro
|
||||||
|
# - mosyleb Mosyle Business
|
||||||
|
# - mosylem Mosyle Manager (Education)
|
||||||
|
# - addigy Addigy
|
||||||
|
# path can also be set in the command call, and if file exists, it will be used.
|
||||||
|
# Like 'LOGO="/System/Applications/App\ Store.app/Contents/Resources/AppIcon.icns"'
|
||||||
|
# (spaces have to be escaped).
|
||||||
|
|
||||||
|
|
||||||
|
# App Store apps handling
|
||||||
|
# IGNORE_APP_STORE_APPS=no
|
||||||
|
# options:
|
||||||
|
# - no If installed app is from App Store (which include VPP installed apps)
|
||||||
|
# it will not be touched, no matter it's version (default)
|
||||||
|
# - yes Replace App Store (and VPP) version of app and handle future
|
||||||
|
# updates using Installomator, even if latest version.
|
||||||
|
# Shouldn’t give any problems for the user in most cases.
|
||||||
|
# Known bad example: Slack will loose all settings.
|
||||||
|
|
||||||
|
|
||||||
|
# install behavior
|
||||||
|
# INSTALL=""
|
||||||
|
# options:
|
||||||
|
# - When not set, software will only be installed
|
||||||
|
# if it is newer/different in version
|
||||||
|
# - force Install even if it’s the same version
|
||||||
|
|
||||||
|
|
||||||
|
# Re-opening of closed app
|
||||||
|
# REOPEN="yes"
|
||||||
|
# options:
|
||||||
|
# - yes App wil be reopened if it was closed
|
||||||
|
# - no App not reopened
|
||||||
|
|
||||||
|
|
||||||
|
########################
|
||||||
|
# Often used labels:
|
||||||
|
########################
|
||||||
|
|
||||||
|
# firefox
|
||||||
|
# firefox_intl
|
||||||
|
# brave
|
||||||
|
# torbrowser
|
||||||
|
# googlechrome
|
||||||
|
# netnewswire
|
||||||
|
|
||||||
|
# adobereaderdc
|
||||||
|
# textmate
|
||||||
|
|
||||||
|
# cyberduck
|
||||||
|
# keka
|
||||||
|
# theunarchiver
|
||||||
|
|
||||||
|
# vlc
|
||||||
|
# handbrake
|
||||||
|
|
||||||
|
# inkscape
|
||||||
|
|
||||||
|
# signal
|
||||||
|
# telegram
|
||||||
|
# whatsapp
|
||||||
|
|
||||||
|
# hazel
|
||||||
|
# devonthink
|
||||||
|
|
||||||
|
# teamviewerqs
|
||||||
|
# zoom
|
||||||
|
|
||||||
|
# malwarebytes
|
||||||
|
# githubdesktop
|
||||||
|
# sublimetext
|
||||||
|
# textmate
|
||||||
|
# visualstudiocode
|
||||||
|
|
||||||
|
# microsoftskypeforbusiness
|
||||||
|
# microsoftteams
|
||||||
|
# microsoftyammer
|
||||||
|
# microsoftedgeenterprisestable
|
||||||
|
# microsoftedgeconsumerstable
|
||||||
|
# microsoftsharepointplugin
|
||||||
|
# microsoftdefenderatp
|
||||||
|
|
||||||
|
# googledrivefilestream
|
||||||
|
|
||||||
|
# cdef
|
||||||
|
# desktoppr
|
||||||
|
# supportapp
|
||||||
|
# xink
|
||||||
|
# wwdc
|
||||||
44
MDM/Installomator update.sh
Executable file
44
MDM/Installomator update.sh
Executable file
@@ -0,0 +1,44 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Updating Installomator
|
||||||
|
# Usefull to push out after deployment if earlier version was deployed in DEP profile
|
||||||
|
# Currently script uses valuesfromarguments as a label is not included before next release, so this can be used to install to version 0.7
|
||||||
|
|
||||||
|
what="installomator" # enter the software to install
|
||||||
|
|
||||||
|
# No sleeping
|
||||||
|
/usr/bin/caffeinate -d -i -m -u &
|
||||||
|
caffeinatepid=$!
|
||||||
|
caffexit () {
|
||||||
|
kill "$caffeinatepid"
|
||||||
|
pkill caffeinate
|
||||||
|
exit $1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Verify that Installomator has been installed
|
||||||
|
destFile="/usr/local/Installomator/Installomator.sh"
|
||||||
|
if [ ! -e "${destFile}" ]; then
|
||||||
|
echo "Installomator not found here:"
|
||||||
|
echo "${destFile}"
|
||||||
|
echo "Exiting."
|
||||||
|
caffexit 99
|
||||||
|
fi
|
||||||
|
|
||||||
|
${destFile} valuesfromarguments\
|
||||||
|
name=Installomator \
|
||||||
|
type=pkg \
|
||||||
|
packageID=com.scriptingosx.Installomator \
|
||||||
|
downloadURL=https://github.com/Installomator/Installomator/releases/download/v0.7release/Installomator-0.7.0.pkg \
|
||||||
|
appNewVersion=0.7 \
|
||||||
|
expectedTeamID=JME5BW3F3R \
|
||||||
|
BLOCKING_PROCESS_ACTION=ignore \
|
||||||
|
NOTIFY=silent
|
||||||
|
|
||||||
|
# ${destFile} ${what} BLOCKING_PROCESS_ACTION=ignore NOTIFY=silent
|
||||||
|
if [ $? != 0 ]; then
|
||||||
|
# This is currently not working in Mosyle, that will ignore script errors. Please request support for this from Mosyle!
|
||||||
|
echo "Error installing ${what}. Exit code $?"
|
||||||
|
caffexit $?
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[$(DATE)][LOG-END]"
|
||||||
|
caffexit 0
|
||||||
100
MDM/MDMAddigy CustomSoftware.sh
Executable file
100
MDM/MDMAddigy CustomSoftware.sh
Executable file
@@ -0,0 +1,100 @@
|
|||||||
|
#!/bin/zsh
|
||||||
|
|
||||||
|
# Specific settings in Addigy to configure Custom Software for installomator.
|
||||||
|
# Addigy has 3 parts to fill out for this, Installation script, Condition, and Removal steps (see RemoveInstallomator.sh).
|
||||||
|
|
||||||
|
# Mark: Installation script
|
||||||
|
# Just click “Add” to autogenerate the installer script line by clicking the “Add”-button next to the Installer PKG, replace with first line below
|
||||||
|
/usr/sbin/installer -pkg "/Library/Addigy/ansible/packages/Installomator (0.7.0)/Installomator-0.7.0.pkg" -target /
|
||||||
|
|
||||||
|
# Installation using Installomator
|
||||||
|
what="supportapp xink textmate microsoftedge wwdc keka vlc " # enter the software to installed separated with spaces
|
||||||
|
|
||||||
|
# To be used as a script sent out from a MDM.
|
||||||
|
# Fill the variable "what" above with labels separated by space " ".
|
||||||
|
# Script will loop through these labels and exit with number of errors.
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
# No sleeping
|
||||||
|
/usr/bin/caffeinate -d -i -m -u &
|
||||||
|
caffeinatepid=$!
|
||||||
|
caffexit () {
|
||||||
|
kill "$caffeinatepid"
|
||||||
|
pkill caffeinate
|
||||||
|
exit $1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Count errors
|
||||||
|
errorCount=0
|
||||||
|
|
||||||
|
# Verify that Installomator has been installed
|
||||||
|
destFile="/usr/local/Installomator/Installomator.sh"
|
||||||
|
if [ ! -e "${destFile}" ]; then
|
||||||
|
echo "Installomator not found here:"
|
||||||
|
echo "${destFile}"
|
||||||
|
echo "Exiting."
|
||||||
|
caffexit 99
|
||||||
|
fi
|
||||||
|
|
||||||
|
for item in $what; do
|
||||||
|
#echo $item
|
||||||
|
${destFile} ${item} LOGO=addigy NOTIFY=silent BLOCKING_PROCESS_ACTION=quit_kill #INSTALL=force
|
||||||
|
if [ $? != 0 ]; then
|
||||||
|
# Error handling
|
||||||
|
echo "[$(DATE)] Error installing ${item}. Exit code $?"
|
||||||
|
let errorCount++
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "Errors: $errorCount"
|
||||||
|
echo "[$(DATE)][LOG-END]"
|
||||||
|
|
||||||
|
caffexit $errorCount
|
||||||
|
|
||||||
|
# Mark: Conditions
|
||||||
|
# Install on success
|
||||||
|
# Remember to fill out the correct “TARGET_VERSION” and “PKG_ID”, and click "Install on succes".
|
||||||
|
PKG_ID="com.scriptingosx.Installomator"
|
||||||
|
TARGET_VERSION="8.0"
|
||||||
|
|
||||||
|
vercomp () {
|
||||||
|
if [[ $1 == $2 ]]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
local IFS=.
|
||||||
|
local i ver1=($1) ver2=($2)
|
||||||
|
# fill empty fields in ver1 with zeros
|
||||||
|
for ((i=${#ver1[@]}; i<${#ver2[@]}; i++)); do
|
||||||
|
ver1[i]=0
|
||||||
|
done
|
||||||
|
for ((i=0; i<${#ver1[@]}; i++)); do
|
||||||
|
if [[ -z ${ver2[i]} ]]; then
|
||||||
|
# fill empty fields in ver2 with zeros
|
||||||
|
ver2[i]=0
|
||||||
|
fi
|
||||||
|
if ((10#${ver1[i]} > 10#${ver2[i]})); then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if ((10#${ver1[i]} < 10#${ver2[i]})); then
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
INSTALLED_VERSION="$(pkgutil --pkg-info $PKG_ID | grep -i "^version" | awk '{print $2}')"
|
||||||
|
|
||||||
|
echo "Current Version: ${INSTALLED_VERSION}"
|
||||||
|
|
||||||
|
vercomp ${TARGET_VERSION} ${INSTALLED_VERSION}
|
||||||
|
COMP=$? # 0 means the same, 1 means TARGET is newer, 2 means INSTALLED is newer
|
||||||
|
echo "COMPARISON: ${COMP}"
|
||||||
|
|
||||||
|
if [ "${COMP}" -eq 1 ]; then
|
||||||
|
echo "Installed version is older than ${TARGET_VERSION}."
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo "Installed version is the same or newer than ${TARGET_VERSION}."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
73
MDM/MDMMosyle install.sh
Normal file
73
MDM/MDMMosyle install.sh
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
PKG_ID="com.scriptingosx.Installomator"
|
||||||
|
TARGET_VERSION="8.0"
|
||||||
|
URLDOWNLOAD="%MosyleCDNFile:blah-blah-blah%"
|
||||||
|
######################################################################
|
||||||
|
# Installation using Installomator (enter the software to install separated with spaces in the "what"-variable)
|
||||||
|
what="handbrake theunarchiver microsoftoffice365"
|
||||||
|
# Covered by Mosyle Catalog: "brave firefox googlechrome microsoftedge microsoftteams signal sublimetext vlc webex zoom" among others
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
## Mark: Code here
|
||||||
|
|
||||||
|
# No sleeping
|
||||||
|
/usr/bin/caffeinate -d -i -m -u &
|
||||||
|
caffeinatepid=$!
|
||||||
|
caffexit () {
|
||||||
|
kill "$caffeinatepid"
|
||||||
|
pkill caffeinate
|
||||||
|
exit $1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Mark: Condition for Installomator installation
|
||||||
|
|
||||||
|
INSTALLED_VERSION="$(pkgutil --pkg-info $PKG_ID 2>/dev/null | grep -i "^version" | awk '{print $2}')"
|
||||||
|
|
||||||
|
echo "Current Version: ${INSTALLED_VERSION}"
|
||||||
|
|
||||||
|
if [[ "$TARGET_VERSION" != "$INSTALLED_VERSION" ]]; then
|
||||||
|
TMPDIR=$(mktemp -d )
|
||||||
|
if ! cd "$TMPDIR"; then
|
||||||
|
echo "error changing directory $TMPDIR"
|
||||||
|
caffexit 98
|
||||||
|
fi
|
||||||
|
NAME=$TMPDIR/$(date +%s).pkg
|
||||||
|
if ! curl -fsL "$URLDOWNLOAD" -o "$NAME"; then
|
||||||
|
echo "error downloading $URLDOWNLOAD to $NAME."
|
||||||
|
caffexit 97
|
||||||
|
fi
|
||||||
|
installer -pkg "$NAME" -target /
|
||||||
|
rm -rf "$TMPDIR"
|
||||||
|
else
|
||||||
|
echo "Installomator version $INSTALLED_VERSION already installed!"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Mark: Start Installomator label(s) installation
|
||||||
|
|
||||||
|
# Count errors
|
||||||
|
errorCount=0
|
||||||
|
|
||||||
|
# Verify that Installomator has been installed
|
||||||
|
destFile="/usr/local/Installomator/Installomator.sh"
|
||||||
|
if [ ! -e "${destFile}" ]; then
|
||||||
|
echo "Installomator not found here:"
|
||||||
|
echo "${destFile}"
|
||||||
|
echo "Exiting."
|
||||||
|
caffexit 99
|
||||||
|
fi
|
||||||
|
|
||||||
|
for item in $what; do
|
||||||
|
#echo $item
|
||||||
|
${destFile} ${item} LOGO=mosyle NOTIFY=all BLOCKING_PROCESS_ACTION=tell_user #NOTIFY=silent BLOCKING_PROCESS_ACTION=quit_kill #INSTALL=force
|
||||||
|
if [ $? != 0 ]; then
|
||||||
|
# Error handling
|
||||||
|
echo "[$(DATE)] Error installing ${item}. Exit code $?"
|
||||||
|
let errorCount++
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "Errors: $errorCount"
|
||||||
|
echo "[$(DATE)][LOG-END]"
|
||||||
|
|
||||||
|
caffexit $errorCount
|
||||||
42
MDM/Manual valuesfromarguments.sh
Executable file
42
MDM/Manual valuesfromarguments.sh
Executable file
@@ -0,0 +1,42 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Installation using Installomator
|
||||||
|
# Example of installing software using valuesfromarguments to install a custom software
|
||||||
|
|
||||||
|
what="valuesfromarguments" # enter the software to install
|
||||||
|
|
||||||
|
# No sleeping
|
||||||
|
/usr/bin/caffeinate -d -i -m -u &
|
||||||
|
caffeinatepid=$!
|
||||||
|
caffexit () {
|
||||||
|
kill "$caffeinatepid"
|
||||||
|
pkill caffeinate
|
||||||
|
exit $1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Verify that Installomator has been installed
|
||||||
|
destFile="/usr/local/Installomator/Installomator.sh"
|
||||||
|
if [ ! -e "${destFile}" ]; then
|
||||||
|
echo "Installomator not found here:"
|
||||||
|
echo "${destFile}"
|
||||||
|
echo "Exiting."
|
||||||
|
caffexit 99
|
||||||
|
fi
|
||||||
|
|
||||||
|
${destFile} valuesfromarguments \
|
||||||
|
name=\"Zoho\ WorkDrive\" \
|
||||||
|
type=dmg \
|
||||||
|
downloadURL=https://files-accl.zohopublic.com/public/wdbin/download/46f971e4fc4a32b68ad5d7dade38a7d2 \
|
||||||
|
appNewVersion=2.6.25 \
|
||||||
|
expectedTeamID=TZ824L8Y37 \
|
||||||
|
BLOCKING_PROCESS_ACTION=quit \
|
||||||
|
NOTIFY=all
|
||||||
|
|
||||||
|
# ${destFile} ${what} BLOCKING_PROCESS_ACTION=ignore NOTIFY=silent
|
||||||
|
if [ $? != 0 ]; then
|
||||||
|
# This is currently not working in Mosyle, that will ignore script errors. Please request support for this from Mosyle!
|
||||||
|
echo "Error installing ${what}. Exit code $?"
|
||||||
|
caffexit $?
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[$(DATE)][LOG-END]"
|
||||||
|
caffexit 0
|
||||||
13
MDM/RemoveInstallomator.sh
Normal file
13
MDM/RemoveInstallomator.sh
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#!/bin/zsh
|
||||||
|
|
||||||
|
# how to remove Installomator.
|
||||||
|
|
||||||
|
# Mark: This fork
|
||||||
|
pkgutil --forget "com.scriptingosx.Installomator"
|
||||||
|
rm /usr/local/Installomator/Installomator.sh
|
||||||
|
rmdir /usr/local/Installomator
|
||||||
|
|
||||||
|
# Mark: Theile fork
|
||||||
|
pkgutil --forget "dk.theilgaard.pkg.Installomator"
|
||||||
|
rm /usr/local/bin/Installomator.sh
|
||||||
|
rm /usr/local/bin/InstallomatorLabels.sh
|
||||||
214
README.md
214
README.md
@@ -8,47 +8,69 @@ This script is in the “we find it useful, it is working for us” stage.
|
|||||||
|
|
||||||
Your production and deployment environment will be different, please test thoroughly before rolling it out to your production.
|
Your production and deployment environment will be different, please test thoroughly before rolling it out to your production.
|
||||||
|
|
||||||
I have put a lot of work into making it stable and safe, but I cannot - of course - make _any_ promises that it won't break in some not yet encountered edge case.
|
We have put a lot of work into making it stable and safe, but we cannot - of course - make _any_ promises that it won't break in some not yet encountered edge case.
|
||||||
|
|
||||||
|
## Authors
|
||||||
|
|
||||||
|
Intallomator was originally inspired by the download scripts from William Smith and Sander Schram, and created by:
|
||||||
|
Armin Briegel - @scriptingosx
|
||||||
|
|
||||||
|
Later on a few more contributers came on the project:
|
||||||
|
Isaac Ordonez - @issacatmann
|
||||||
|
Søren Theilgaard - @Theile
|
||||||
|
Adam Codega - @acodega
|
||||||
|
|
||||||
|
And with numerous contributions from many others.
|
||||||
|
|
||||||
## Support and Contributing
|
## Support and Contributing
|
||||||
|
|
||||||
__Please note, that if you are contributing to this project with new labels or other suggestions in PRs, please put your changes in the fragmented files, not the full `Installomator.sh` script. The full script is now a build of the fragments, and will be overwritten. See the REAMDME.md file in the `utils` directory for detailed instructions.__
|
__Please note, that if you are contributing to this project with new labels or other suggestions in PRs, please put your changes in the files below `fragments`-folder. DO NOT edit the full `Installomator.sh` script. The full script is now a build of the fragments, and will be overwritten. See the [README.md](utils/README.md) file in the `utils` directory for detailed instructions.__
|
||||||
|
|
||||||
Discussion, support and advice around Installomator happens in the `#installomator` channel in the [MacAdmins.org Slack](https://macadmins.org). Go there for support questions.
|
Discussion, support and advice around Installomator happens in the `#installomator` channel in the [MacAdmins.org Slack](https://macadmins.org). Go there for support questions.
|
||||||
|
|
||||||
Do not create an issue just when you have a questions, but do file an issue or pull request for bugs or wrong behavior. When in doubt, ask in the above Slack channel.
|
Do not create an issue just when you have a questions, but do file an issue or pull request (PR) for bugs or wrong behavior. When in doubt, ask in the above Slack channel.
|
||||||
|
|
||||||
If you have added a new label, then please file a pull request. (and Thank you!)
|
Please see [CONTRIBUTING.md](https://github.com/Installomator/Installomator/blob/dev/CONTRIBUTING.md) for how to contribute.
|
||||||
|
|
||||||
We try to keep the script as short as possible, and with more than 300 labels, we can save 300 lines in the script, if we do not have credit lines on each of these. So we are thankful for your contribution, but we will be removing these lines in the coming releases.
|
|
||||||
|
|
||||||
## More reading
|
## More reading
|
||||||
|
|
||||||
There are a few interesting post on Installomator on my weblog:
|
Our wiki:
|
||||||
|
|
||||||
|
- [Wiki](https://github.com/Installomator/Installomator/wiki)
|
||||||
|
|
||||||
|
There are a few interesting post on Installomator on Armin’s weblog:
|
||||||
|
|
||||||
- [Introducing Installomator](https://scriptingosx.com/2020/05/introducing-installomator/)
|
- [Introducing Installomator](https://scriptingosx.com/2020/05/introducing-installomator/)
|
||||||
- [Using Installomator with Jamf Pro](https://scriptingosx.com/2020/06/using-installomator-with-jamf-pro/) by Mischa van der Bent
|
- [Using Installomator with Jamf Pro](https://scriptingosx.com/2020/06/using-installomator-with-jamf-pro/) by Mischa van der Bent
|
||||||
- [Using another MDM than Jamf and you might want a local installation](https://github.com/Theile/Installomator/) By Søren Theilgaard
|
|
||||||
|
|
||||||
## Background
|
## Background
|
||||||
|
|
||||||
As a system engineer at [an Apple Authorized Enterprise Reseller](https://prowarehouse.nl), we manage a lot of Jamf instances.
|
In the world of managing Apple Macs, organizations can have two different approaches to the management. Either the IT department will tightly manage and verify each piece of software, or they will just want the latest software to be deployed as fast as possible.
|
||||||
|
|
||||||
Some of these instances are tightly managed, i.e. the versions of the operating system and third party software are controlled and updates will only be pushed with the management system when the administration and security team went through an approval process and then the update is automated. This is an important and valid workflow and the right fit for many deployments.
|
OK, maybe some software should be tightly managed and others not, but you get the point.
|
||||||
|
|
||||||
|
### Tightly managed
|
||||||
|
|
||||||
|
If your solution needs to be tightly managed, i.e. the versions of the operating system and third party software are controlled and updates will only be pushed with the management system when the administration and security team went through an approval process and then the update is automated. This is an important and valid workflow and the right fit for many deployments.
|
||||||
|
|
||||||
Installomator was _not_ written for these kinds of deployment.
|
Installomator was _not_ written for these kinds of deployment.
|
||||||
|
|
||||||
If you are running this kind of deployment, you want to use [AutoPkg](https://github.com/autopkg/autopkg) and you can stop reading here.
|
If you are running this kind of deployment, you want to use [AutoPkg](https://github.com/autopkg/autopkg) and you can stop reading here.
|
||||||
|
|
||||||
There are other kinds of deployments, though. In these deployments the management system is merely used to "get the user ready" as quickly as possible when they set up a new machine, and to offer software from a self service portal. In these deployments, system and software installations are 'latest version available' and updates are user driven (though we do want to nag them).
|
### Latest version always
|
||||||
|
|
||||||
These deployments are
|
There are other kinds of deployments, though. In these deployments the management system is merely used to “get the user ready” as quickly as possible when they set up a new machine, and to offer software from a self service portal. In these deployments, system and software installations are ‘latest version available’ and updates are user driven (though we do want to nag them and push them).
|
||||||
|
|
||||||
|
Installomator can help with this.
|
||||||
|
|
||||||
|
These deployments can be
|
||||||
|
|
||||||
- user driven
|
- user driven
|
||||||
- low control
|
- low control
|
||||||
- minimal maintenance effort
|
- minimal maintenance effort
|
||||||
|
- latest version is best
|
||||||
|
|
||||||
These are mostly 'user controlled' Macs and we (the admins) just want to assist the user in doing the right thing. And the right thing is (often) to install the latest versions and updates when they are available.
|
These can be 'user controlled' Macs and we (the admins) just want to assist the user in doing the right thing. And the right thing is (often) to install the latest versions and updates when they are available.
|
||||||
|
|
||||||
The Mac App Store and software pushed through the Mac App Store follow this approach. When you manage and deploy software through the App Store — whether it is on iOS or macOS — neither the MacAdmin nor the user get a choice of the application version. They will get the latest version.
|
The Mac App Store and software pushed through the Mac App Store follow this approach. When you manage and deploy software through the App Store — whether it is on iOS or macOS — neither the MacAdmin nor the user get a choice of the application version. They will get the latest version.
|
||||||
|
|
||||||
@@ -65,16 +87,25 @@ Some of these disadvantages can be seen as advantages in different setups. When
|
|||||||
|
|
||||||
Because this is an attractive solution for _certain kinds_ of deployment, there are already many scripts out there that will download and install the latest version of a given software. And we have built and used quite a few in-house, as well. Most importantly, [William Smith has this script](https://gist.github.com/talkingmoose/a16ca849416ce5ce89316bacd75fc91a) which can be used to install several different Microsoft applications and bundles, because Microsoft has a nice unified URL scheme.
|
Because this is an attractive solution for _certain kinds_ of deployment, there are already many scripts out there that will download and install the latest version of a given software. And we have built and used quite a few in-house, as well. Most importantly, [William Smith has this script](https://gist.github.com/talkingmoose/a16ca849416ce5ce89316bacd75fc91a) which can be used to install several different Microsoft applications and bundles, because Microsoft has a nice unified URL scheme.
|
||||||
|
|
||||||
At some point, earlier this year, I got frustrated at the number of scripts we were maintaining (or failing to). Also, my concern that most of the scripts weren't doing _any_ verification of the download was getting unbearable. So, I set out to write the one install script to rule them all...
|
At some point, in 2018, Armin got frustrated at the number of scripts he was maintaining (or failing to). Also, his concern that most of the scripts weren’t doing _any_ verification of the download was getting unbearable. So, he set out to write _the one install script to rule them all…_
|
||||||
|
|
||||||
|
### Locally installed
|
||||||
|
|
||||||
|
So Armin made the version for Jamf Pro but universally for any MDM to adopt.
|
||||||
|
|
||||||
|
Søren looked at this, and wanted this approach to work in Mosyle and Addigy, and for these solutions we need Installomator to be locally installed on. the Mac, and then the MDM can call this script from their scripts features. For some time Søren had a version of Installomator that was supplied with a notarized pkg, so it could be deployed as part of DEP or however was needed.
|
||||||
|
|
||||||
|
This has now been merged into Installomator, and with contributions of Isaac and Adam, new features and labels have been added more frequently.
|
||||||
|
|
||||||
## Goals
|
## Goals
|
||||||
|
|
||||||
My goals for Installomator are:
|
The goals for Installomator are:
|
||||||
|
|
||||||
- work with various common archive types
|
- work with various common archive types
|
||||||
- verify the downloaded archive or application
|
- verify the downloaded archive or application
|
||||||
- have a simple 'interface' to the admin
|
- have a simple ‘interface’ to the admin
|
||||||
- single script file so it can 'easily' be copied into a management system
|
- single script file so it can ‘easily’ be copied into a management system
|
||||||
|
- signed and notarized pkg-installer for local installation
|
||||||
- extensible without deep scripting knowledge
|
- extensible without deep scripting knowledge
|
||||||
- work independently of a specific management system
|
- work independently of a specific management system
|
||||||
- no dependencies that may be removed from macOS in the future or are not pre-installed
|
- no dependencies that may be removed from macOS in the future or are not pre-installed
|
||||||
@@ -91,9 +122,9 @@ Installomator can work with the following common archive and installer types:
|
|||||||
|
|
||||||
When the download yields a pkg file, Installomator will run `installer` to install it on the current system.
|
When the download yields a pkg file, Installomator will run `installer` to install it on the current system.
|
||||||
|
|
||||||
Applications in dmgs or zips will be copied to `/Applications` and their owner will be set to the current user, so the install works like a standard drag'n drop installation.
|
Applications in dmgs or zips will be copied to `/Applications` and their owner will be set to the current user, so the install works like a standard drag'n drop installation. Owner can also be set to root/wheel.
|
||||||
|
|
||||||
(I consider it a disgrace, that Jamf, after nearly 20 years, _still_ cannot deal with 'drag'n drop installation dmgs' natively. It's not _that_ hard.)
|
(I consider it a disgrace, that Jamf, after nearly 20 years, _still_ cannot deal with ‘drag’n drop installation dmgs natively. It’s not _that_ hard.)
|
||||||
|
|
||||||
### Verify the download
|
### Verify the download
|
||||||
|
|
||||||
@@ -110,11 +141,11 @@ When used to install software, Installomator has a single argument: the label or
|
|||||||
./Installomator.sh firefox LOGO=jamf BLOCKING_PROCESS_ACTION=tell_user_then_kill NOTIFY=all
|
./Installomator.sh firefox LOGO=jamf BLOCKING_PROCESS_ACTION=tell_user_then_kill NOTIFY=all
|
||||||
```
|
```
|
||||||
|
|
||||||
There is a debug mode and one other setting that can be controlled with variables in the code. This simplifies the actual use of the script from within a management system.
|
There is a debug mode and other settings that can be controlled with variables in the code. This simplifies the actual use of the script from within a management system.
|
||||||
|
|
||||||
### Extensible
|
### Extensible
|
||||||
|
|
||||||
As of this writing, Installomator knows how to download and install more than 238 different applications. You can add more by adding a block to the _long_ `case` statement starting on line 758. Some of them are more elaborate, but most of them (just) need this information (not really "just" in this case, as we have to differentiate between arm64 and i386 versions for both `downloadURL` and `appNewVersion`):
|
As of this writing, Installomator knows how to download and install more than 364 different applications. You can add more by adding new labels to the `fragments`-folder. Below is an example of a label, and most of them (just) needs this information (not really "just" in this case, as we have to differentiate between arm64 and i386 versions for both `downloadURL` and `appNewVersion`):
|
||||||
|
|
||||||
```
|
```
|
||||||
googlechrome)
|
googlechrome)
|
||||||
@@ -123,11 +154,11 @@ googlechrome)
|
|||||||
if [[ $(arch) != "i386" ]]; then
|
if [[ $(arch) != "i386" ]]; then
|
||||||
printlog "Architecture: arm64 (not i386)"
|
printlog "Architecture: arm64 (not i386)"
|
||||||
downloadURL="https://dl.google.com/chrome/mac/universal/stable/GGRO/googlechrome.dmg"
|
downloadURL="https://dl.google.com/chrome/mac/universal/stable/GGRO/googlechrome.dmg"
|
||||||
appNewVersion=$(curl -s https://omahaproxy.appspot.com/history | awk -F',' '/mac_arm64,stable/{print $3; exit}') # Credit: William Smith (@meck)
|
appNewVersion=$(curl -s https://omahaproxy.appspot.com/history | awk -F',' '/mac_arm64,stable/{print $3; exit}')
|
||||||
else
|
else
|
||||||
printlog "Architecture: i386"
|
printlog "Architecture: i386"
|
||||||
downloadURL="https://dl.google.com/chrome/mac/stable/GGRO/googlechrome.dmg"
|
downloadURL="https://dl.google.com/chrome/mac/stable/GGRO/googlechrome.dmg"
|
||||||
appNewVersion=$(curl -s https://omahaproxy.appspot.com/history | awk -F',' '/mac,stable/{print $3; exit}') # Credit: William Smith (@meck)
|
appNewVersion=$(curl -s https://omahaproxy.appspot.com/history | awk -F',' '/mac,stable/{print $3; exit}')
|
||||||
fi
|
fi
|
||||||
expectedTeamID="EQHXZ8M8AV"
|
expectedTeamID="EQHXZ8M8AV"
|
||||||
;;
|
;;
|
||||||
@@ -135,19 +166,21 @@ googlechrome)
|
|||||||
|
|
||||||
When you know how to extract these pieces of information from the application and/or download, then you can add an application to Installomator.
|
When you know how to extract these pieces of information from the application and/or download, then you can add an application to Installomator.
|
||||||
|
|
||||||
The script `buildCaseStatement.sh` can help with the label creation.
|
The script `buildLabel.sh` can help with the label creation. Just server the URL to the script, and it will try to figure out things and write out a label as output. See [Wiki Tutorials](https://github.com/Installomator/Installomator/wiki#tutorials).
|
||||||
|
|
||||||
Please note: Labels should be named in small caps, numbers 0-9, “-”, and “_”. No other characters allowed.
|
Please note: Labels should be named in small caps, numbers 0-9, “-”, and “_”. No other characters allowed.
|
||||||
|
|
||||||
|
Actually labels are part of a case-statement, and must be formatted accordingly.
|
||||||
|
|
||||||
### Not specific to a management system
|
### Not specific to a management system
|
||||||
|
|
||||||
I wrote this script mainly for use with Jamf Pro, because that is what we use. For testing, you can run the script interactively from the command line. However, I have tried to keep anything that is specific to Jamf optional, or so flexible that it will work anywhere. Even if it does not work with your management system 'out of the box,' the adaptations should be straightforward.
|
Armin wrote this script mainly for use with Jamf Pro, because that is what he used. For testing, you can run the script interactively from the command line. However, we have tried to keep anything that is specific to Jamf optional, or so flexible that it will work anywhere. Even if it does not work with your management system ‘out of the box’, the adaptations should be straightforward.
|
||||||
|
|
||||||
Not all MDMs can include the full script, for those MDMs it might be more useful to install it on the client machines, and run it from there. See [Using another MDM than Jamf and you might want a local installation](https://github.com/Theile/Installomator/) By Søren Theilgaard.
|
Not all MDMs can include the full script, for those MDMs it might be more useful to install it on the client machines, and run it from there. So a PKG to be installed on client Macs is also provided here.
|
||||||
|
|
||||||
### No dependencies
|
### No dependencies
|
||||||
|
|
||||||
The script started out as a pure `sh` script, and when I needed arrays I 'switched' to `zsh`, because that is what [we can rely on being in macOS for the foreseeable future](https://scriptingosx.com/zsh). There are quite a few places where using python would have been easier and safer, but with the python 2 run-time being deprecated, that would have added a requirement for a Python 3 run-time to be installed. XML and JSON parsing would have been better with a tool like [scout](https://github.com/ABridoux/scout) or [jq](https://stedolan.github.io/jq/), but those would again require additional installations on the client before the script can run.
|
The script started out as a pure `sh` script, and when arrays was needed it was ‘switched’ to `zsh`, because that is what [we can rely on being in macOS for the foreseeable future](https://scriptingosx.com/zsh). There are quite a few places where using python would have been easier and safer, but with the python 2 run-time being deprecated, that would have added a requirement for a Python 3 run-time to be installed. XML and JSON parsing would have been better with a tool like [scout](https://github.com/ABridoux/scout) or [jq](https://stedolan.github.io/jq/), but those would again require additional installations on the client before the script can run.
|
||||||
|
|
||||||
Keeping the script as a `zsh` allows you to paste it into your management system's interface (and disable the DEBUG mode) and use it without requiring any other installations.
|
Keeping the script as a `zsh` allows you to paste it into your management system's interface (and disable the DEBUG mode) and use it without requiring any other installations.
|
||||||
|
|
||||||
@@ -180,19 +213,19 @@ Other than the version arguments, the argument can be any of the labels listed i
|
|||||||
|
|
||||||
### Debug mode
|
### Debug mode
|
||||||
|
|
||||||
There is a variable named `DEBUG` which is set in line 21 of the script. When `DEBUG` is set to `1` (default) no actions that would actually modify the current system are taken. This is useful for testing most of the actions in the script, but obviously not all of them.
|
There is a variable named `DEBUG` which is set in line 21 of the script. When `DEBUG` is set to `1` (default) or `2` for a variation of debug, no actions that would actually modify the current system are taken. This is useful for testing most of the actions in the script, but obviously not all of them.
|
||||||
|
|
||||||
Also when the `DEBUG` variable is `1`, downloaded archives and extracted files will be written to the script's directory, rather than a temporary directory, which can make debugging easier.
|
When the `DEBUG` variable is `1`, downloaded archives and extracted files will be written to the script's directory, rather than a temporary directory, which can make debugging easier.
|
||||||
|
|
||||||
_Always remember_ to change the `DEBUG` variable to `0` when deploying.
|
When `DEBUG` variable is `2`, the temporary folder is created and downloaded and extracted files goes to that folder, as if not in DEBUG mode, but installation is still not done. On the other hand blocking processes are checked, the app is reopened if closed, and the user is notified.
|
||||||
|
|
||||||
### Use Installomator with Jamf Pro
|
Debug mode 1 is useful to test the download and verification process without having to re-download and re-install an application or package on your system. Debug mode 2 is great for checking running processe and notifications.
|
||||||
|
|
||||||
In Jamf Pro, create a new 'Script' and paste the contents of `Installomator.sh` into the 'Script Contents' area. Under 'Options' you can change the parameter label for argument 4 to 'Application Label.'
|
_Always remember_ to change the `DEBUG` variable to `0` when deploying. The installer PKG we provide has `DEBUG=0`.
|
||||||
|
|
||||||
Remember to set `DEBUG` to `0`.
|
### Use Installomator with various MDM solutions
|
||||||
|
|
||||||
Then you can use the Installomator script in a policy and choose the application to install by setting the label for argument 4.
|
In the wiki we have provided documentation on how Installomator is used in various MDM solution, like [Jamf Pro](https://github.com/Installomator/Installomator/wiki/MDM:-Jamf-Pro), [Mosyle](https://github.com/Installomator/Installomator/wiki/MDM:-Mosyle-(Business,-Fuse,-and-Manager)), and [Addigy](https://github.com/Installomator/Installomator/wiki/MDM:-Addigy).
|
||||||
|
|
||||||
## What it does
|
## What it does
|
||||||
|
|
||||||
@@ -200,7 +233,7 @@ When it runs with a known label, the script will perform the following:
|
|||||||
|
|
||||||
- Check the version installed with the version online. Only continue if it's different
|
- Check the version installed with the version online. Only continue if it's different
|
||||||
- download the latest version from the vendor
|
- download the latest version from the vendor
|
||||||
- when the application is running, prompt the user to quit or cancel
|
- when the application is running, prompt the user to quit or cancel (customizable)
|
||||||
- dmg or zip archives:
|
- dmg or zip archives:
|
||||||
- extract the application and copy it to /Applications
|
- extract the application and copy it to /Applications
|
||||||
- change the owner of the application to the current user
|
- change the owner of the application to the current user
|
||||||
@@ -208,19 +241,11 @@ When it runs with a known label, the script will perform the following:
|
|||||||
- when necessary, extract the pkg from the enclosing archive
|
- when necessary, extract the pkg from the enclosing archive
|
||||||
- install the pkg with the `installer` tool
|
- install the pkg with the `installer` tool
|
||||||
- clean up the downloaded files
|
- clean up the downloaded files
|
||||||
- notify the user
|
- notify the user (also customizable)
|
||||||
|
|
||||||
## Configuring the script
|
## Configuring the script
|
||||||
|
|
||||||
As of now there are two settings that are meant to configured when deploying the script.
|
We have several default settings for certain behavior and notifications inside the script, but these can be customized when calling the script.
|
||||||
|
|
||||||
### Debug mode
|
|
||||||
|
|
||||||
The first is the `DEBUG` variable. When this is set to `1` the script will _not_ perform any changes to the current system. In other words, no application will be copied to the target directory and no `installer` command be performed.
|
|
||||||
|
|
||||||
In addition, files will be downloaded and extracted to the Installomator project folder instead of a temporary directory and _not_ deleted when the script exits. Also archives will _not_ be re-downloaded when they already exist in the project folder. The repository's `.gitignore` file is set up to ignore the archive file extensions.
|
|
||||||
|
|
||||||
Debug mode is useful to test the download and verification process without having to re-download and re-install an application or package on your system.
|
|
||||||
|
|
||||||
### Blocking Process actions
|
### Blocking Process actions
|
||||||
|
|
||||||
@@ -229,13 +254,13 @@ The `BLOCKING_PROCESS_ACTION` variable controls the behavior of the script when
|
|||||||
There are eight options:
|
There are eight options:
|
||||||
|
|
||||||
- `ignore`: continue even when blocking processes are found.
|
- `ignore`: continue even when blocking processes are found.
|
||||||
- `silent_fail`: exit script without prompt or installation.
|
- `silent_fail`: Exit script without prompt or installation.
|
||||||
- `prompt_user`: (default) show a user dialog for each blocking process found abort after three attempts to quit (only if user accepts to quit the apps, otherwise the update is cancelled).
|
- `prompt_user`: Show a user dialog for each blocking process found, user can choose "Quit and Update" or "Not Now". When "Quit and Update" is chosen, blocking process will be told to quit. Installomator will wait 30 seconds before checking again in case Save dialogs etc are being responded to. Installomator will abort if quitting after three tries does not succeed. "Not Now" will exit Installomator.
|
||||||
- `prompt_user_then_kill`: show a user dialog for each blocking process found, attempt to quit two times, kill the process finally.
|
- `prompt_user_then_kill`: show a user dialog for each blocking process found, user can choose "Quit and Update" or "Not Now". When "Quit and Update" is chosen, blocking process will be terminated. Installomator will abort if terminating after two tries does not succeed. "Not Now" will exit Installomator.
|
||||||
- `prompt_user_loop`: Like prompt-user, but clicking "Not Now", will just wait an hour, and then it will ask again.
|
- `prompt_user_loop`: Like prompt-user, but clicking "Not Now", will just wait an hour, and then it will ask again.
|
||||||
WARNING! It might block the MDM agent on the machine, as the scripts gets stuct in waiting until the hour has passed, possibly blocking for other management actions in this time.
|
WARNING! It might block the MDM agent on the machine, as the script will not exit, it will pause until the hour has passed, possibly blocking for other management actions in this time.
|
||||||
- `tell_user`: User will be showed a notification about the important update, but user is only allowed to quit and continue, and then we ask the app to quit.
|
- `tell_user`: (Default) User will be showed a notification about the important update, but user is only allowed to Quit and Continue, and then we ask the app to quit. This is default.
|
||||||
- `tell_user_then_kill`: Show dialog 2 times, and if the quitting fails, the blocking processes will be killed.
|
- `tell_user_then_kill`: User will be showed a notification about the important update, but user is only allowed to Quit and Continue. If the quitting fails, the blocking processes will be terminated.
|
||||||
- `kill`: kill process without prompting or giving the user a chance to save.
|
- `kill`: kill process without prompting or giving the user a chance to save.
|
||||||
|
|
||||||
If any process was closed, Installomator will try to open the app again, after the update process is done.
|
If any process was closed, Installomator will try to open the app again, after the update process is done.
|
||||||
@@ -265,11 +290,17 @@ __options:__
|
|||||||
- `no`: If installed app is from App Store (which include VPP installed apps) it will not be touched, no matter it's version (default)
|
- `no`: If installed app is from App Store (which include VPP installed apps) it will not be touched, no matter it's version (default)
|
||||||
- `yes`: Replace App Store (and VPP) version of app and handle future updates using Installomator, even if latest version. Shouldn’t give any problems for the user in most cases. Known bad example: Slack will loose all settings.
|
- `yes`: Replace App Store (and VPP) version of app and handle future updates using Installomator, even if latest version. Shouldn’t give any problems for the user in most cases. Known bad example: Slack will loose all settings.
|
||||||
|
|
||||||
|
### Owner of copied apps
|
||||||
|
Default is `SYSTEMOWNER=0`
|
||||||
|
__options:__
|
||||||
|
- `0`: Current user will be owner of copied apps, just like if they installed it themselves (default).
|
||||||
|
- `1`: root:wheel will be set on the copied app. Useful for shared machines.
|
||||||
|
|
||||||
### Install behavior (force installation)
|
### Install behavior (force installation)
|
||||||
|
|
||||||
Since we now make a version checking, and only installs the software if the version is different, an `INSTALL` variable can be used to force the installation:
|
Since we now make a version checking, and only installs the software if the version is different, an `INSTALL` variable can be used to force the installation:
|
||||||
|
|
||||||
- ``: When not set, software is only installed if it is newer/different in version (default)
|
- ` `: When not set, software is only installed if it is newer/different in version (default)
|
||||||
- `force`: Install even if it’s the same version
|
- `force`: Install even if it’s the same version
|
||||||
|
|
||||||
### Re-opening of closed app
|
### Re-opening of closed app
|
||||||
@@ -279,9 +310,29 @@ The `REOPEN` can be used to prevent the reopening of a closed app
|
|||||||
- `yes`: (default) app will be reopened if it was closed
|
- `yes`: (default) app will be reopened if it was closed
|
||||||
- `no`: app not reopened
|
- `no`: app not reopened
|
||||||
|
|
||||||
### Adding applications/label blocks
|
### Configuration from Arguments
|
||||||
|
|
||||||
#### Required Variables
|
You can provide a configuration variable, such as `DEBUG` or `NOTIFY` as an argument in the form `VAR=value`. For example:
|
||||||
|
|
||||||
|
```
|
||||||
|
./Installomator.sh desktoppr DEBUG=0 NOTIFY=silent
|
||||||
|
```
|
||||||
|
|
||||||
|
Providing variables this way will override any variables set in the script.
|
||||||
|
|
||||||
|
You can even provide _all_ the variables necessary for download and installation. Of course, without a label the argument parsing will fail, so I created a special label `valuesfromarguments` which only checks if the four required values are present:
|
||||||
|
|
||||||
|
```
|
||||||
|
./Installomator.sh name=desktoppr type=pkg downloadURL=https://github.com/scriptingosx/desktoppr/releases/download/v0.3/desktoppr-0.3.pkg expectedTeamID=JME5BW3F3R valuesfromarguments
|
||||||
|
```
|
||||||
|
|
||||||
|
The order of the variables and label is not relevant. But, when you provide more than one label, all but the _last_ label will be ignored.
|
||||||
|
|
||||||
|
Providing all the variables this way might be useful for certain downloads that have a customized URL for each vendor/customer (like customized TeamView or Watchman Monitoring) or are local downloads.
|
||||||
|
|
||||||
|
## Adding applications/label blocks
|
||||||
|
|
||||||
|
### Required Variables
|
||||||
|
|
||||||
The script requires four pieces of information to download and install an application:
|
The script requires four pieces of information to download and install an application:
|
||||||
|
|
||||||
@@ -314,6 +365,12 @@ The URL from which to download the archive.
|
|||||||
The URL can be generated by a series of commands, for example when you need to parse an xml file for the latest URL. (See `bbedit`, `desktoppr`, or `omnigraffle` for examples.)
|
The URL can be generated by a series of commands, for example when you need to parse an xml file for the latest URL. (See `bbedit`, `desktoppr`, or `omnigraffle` for examples.)
|
||||||
Sometimes version differs between Intel and Apple Silicon versions. (See `brave`, `obsidian`, `omnidisksweeper`, or `notion`).
|
Sometimes version differs between Intel and Apple Silicon versions. (See `brave`, `obsidian`, `omnidisksweeper`, or `notion`).
|
||||||
|
|
||||||
|
- `curlOptions`: (array, optional)
|
||||||
|
Options to the `curl` command, needed for `curl` to be able to download the software.
|
||||||
|
Usually used for adding extra headers that some servers need in order to serve the file.
|
||||||
|
`curlOptions=( -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Safari/605.1.15" )`
|
||||||
|
(See “mocha”-labels, for examples on labels, and `buildLabel.sh` for header-examples.)
|
||||||
|
|
||||||
- `appNewVersion` (optional, but recommended):
|
- `appNewVersion` (optional, but recommended):
|
||||||
Version of the downloaded software.
|
Version of the downloaded software.
|
||||||
If given, it will be compared to installed version, to see if download is different.
|
If given, it will be compared to installed version, to see if download is different.
|
||||||
@@ -334,8 +391,7 @@ The 10-character Developer Team ID with which the application or pkg is signed a
|
|||||||
- Installation Packages (pkg)
|
- Installation Packages (pkg)
|
||||||
`spctl -a -vv -t install ~/Downloads/desktoppr-0.2.pkg`
|
`spctl -a -vv -t install ~/Downloads/desktoppr-0.2.pkg`
|
||||||
|
|
||||||
|
### Optional Variables
|
||||||
#### Optional Variables
|
|
||||||
|
|
||||||
Depending on the application or pkg there are a few more variables you can or need to set. Many of these are derived from the required variables, but may need to be set manually if those derived values do not work.
|
Depending on the application or pkg there are a few more variables you can or need to set. Many of these are derived from the required variables, but may need to be set manually if those derived values do not work.
|
||||||
|
|
||||||
@@ -374,47 +430,35 @@ Depending on the application or pkg there are a few more variables you can or ne
|
|||||||
`$updateTool $updateArguments`
|
`$updateTool $updateArguments`
|
||||||
Will be run instead of of downloading and installing a complete new version.
|
Will be run instead of of downloading and installing a complete new version.
|
||||||
Use this when the `updateTool` does differential and optimized downloads.
|
Use this when the `updateTool` does differential and optimized downloads.
|
||||||
e.g. `msupdate` (see microsoft installations)
|
e.g. `msupdate` (see various Microsoft installations).
|
||||||
|
|
||||||
- `updateToolRunAsCurrentUser`:
|
- `updateToolRunAsCurrentUser`:
|
||||||
When this variable is set (any value), `$updateTool` will be run as the current user. Default is unset and
|
When this variable is set (any value), `$updateTool` will be run as the current user. Default is unset and
|
||||||
|
|
||||||
### Configuration from Arguments
|
- `CLIInstaller`:
|
||||||
|
- `CLIArguments`:
|
||||||
You can provide a configuration variable, such as `DEBUG` or `NOTIFY` as an argument in the form `VAR=value`. For example:
|
If the downloaded dmg is actually an installer that we can call using CLI, we can use these two variables for what to call.
|
||||||
|
We need to define `name` for the installed app (to be version checked), as well as `installerTool` for the installer app (if named differently that `name`. Installomator will add the path to the folder/disk image with the binary, and it will be called like this:
|
||||||
```
|
`$CLIInstaller $CLIArguments`
|
||||||
./Installomator.sh desktoppr DEBUG=0 NOTIFY=silent
|
For most installations `CLIInstaller` should contain the `installerTool` for the CLI call (if it’s the same).
|
||||||
```
|
We can support a whole range of other software titles by implementing this.
|
||||||
|
See label adobecreativeclouddesktop.
|
||||||
Providing variables this way will override any variables set in the script.
|
|
||||||
|
|
||||||
You can even provide _all_ the variables necessary for download and installation. Of course, without a label the argument parsing will fail, so I created a special label `valuesfromarguments` which only checks if the four required values are present:
|
|
||||||
|
|
||||||
```
|
|
||||||
./Installomator.sh name=desktoppr type=pkg downloadURL=https://github.com/scriptingosx/desktoppr/releases/download/v0.3/desktoppr-0.3.pkg expectedTeamID=JME5BW3F3R valuesfromarguments
|
|
||||||
```
|
|
||||||
|
|
||||||
The order of the variables and label is not relevant. But, when you provide more than one label, all but the _last_ label will be ignored.
|
|
||||||
|
|
||||||
Providing all the variables this way might be useful for certain downloads that have a customized URL for each vendor/customer (like customized TeamView or Watchman Monitoring) or are local downloads.
|
|
||||||
|
|
||||||
|
- `installerTool`:
|
||||||
|
Introduced as part of `CLIInstaller`. If the installer in the DMG or ZIP is named differently than the installed app, then this variable can be used to name the installer that should be located after mounting/expanding the downloaded archive.
|
||||||
|
See label adobecreativeclouddesktop
|
||||||
|
|
||||||
## Frequently Asked Questions
|
## Frequently Asked Questions
|
||||||
|
|
||||||
### What if the latest version of the app is already installed?
|
### What if the latest version of the app is already installed?
|
||||||
|
|
||||||
Short answer: Installomator will re-download and re-install the latest over the existing installation.
|
Short answer: That depends on if labels will know what the latest version will be.
|
||||||
|
|
||||||
Longer answer:
|
Longer answer:
|
||||||
|
|
||||||
Installomator will try to find a currently installed app to log the version. When Installomator finds an existing app (any version) and the `updateTool` variable is set, then Installomator will _not_ download and install, but run the `updateTool` instead.
|
- Labels without this will re-download and re-install the latest over the existing installation.
|
||||||
|
- Labels with this info will only install the app if the version is different than the one installed.
|
||||||
However, there is no simple generic method to actually determine the latest version of an application or installer.
|
- Labels that can use update tool will use that for the update (if the version is different)
|
||||||
|
|
||||||
We deploy Installomator usually for user initiated installations from Self Service, so re-installs don't really 'hurt' and may be a useful troubleshooting step.
|
|
||||||
|
|
||||||
When you want to have automated installations, you can use smart groups based on the app version to limit excessive re-installations.
|
|
||||||
|
|
||||||
### Why don't you just use `autopkg install`?
|
### Why don't you just use `autopkg install`?
|
||||||
|
|
||||||
@@ -444,7 +488,7 @@ Please don't misunderstand this as me saying that AutoPkg is a bad or poorly des
|
|||||||
|
|
||||||
But it is not suited as a client install automation tool.
|
But it is not suited as a client install automation tool.
|
||||||
|
|
||||||
### Why don't you just use brew?
|
### Why don't you just use brew or MacPorts?
|
||||||
|
|
||||||
Read the explanation for `autopkg`, pretty much the same applies for `brew`, i.e. while it is useful on a single Mac, it is a un-manageable mess when you think about deploying and managing on a fleet of computers.
|
Read the explanation for `autopkg`, pretty much the same applies for `brew`, i.e. while it is useful on a single Mac, it is a un-manageable mess when you think about deploying and managing on a fleet of computers.
|
||||||
|
|
||||||
|
|||||||
@@ -1,29 +1,30 @@
|
|||||||
# MARK: check minimal macOS requirement
|
# MARK: check minimal macOS requirement
|
||||||
autoload is-at-least
|
autoload is-at-least
|
||||||
|
|
||||||
if ! is-at-least 10.14 $(sw_vers -productVersion); then
|
installedOSversion=$(sw_vers -productVersion)
|
||||||
printlog "Installomator requires at least macOS 10.14 Mojave."
|
if ! is-at-least 10.14 $installedOSversion; then
|
||||||
|
printlog "Installomator requires at least macOS 10.14 Mojave." ERROR
|
||||||
exit 98
|
exit 98
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# MARK: argument parsing
|
# MARK: argument parsing
|
||||||
if [[ $# -eq 0 ]]; then
|
if [[ $# -eq 0 ]]; then
|
||||||
if [[ -z $label ]]; then # check if label is set inside script
|
if [[ -z $label ]]; then # check if label is set inside script
|
||||||
printlog "no label provided, printing labels"
|
printlog "no label provided, printing labels" REQ
|
||||||
grep -E '^[a-z0-9\_-]*(\)|\|\\)$' "$0" | tr -d ')|\' | grep -v -E '^(broken.*|longversion|version|valuesfromarguments)$' | sort
|
grep -E '^[a-z0-9\_-]*(\)|\|\\)$' "$0" | tr -d ')|\' | grep -v -E '^(broken.*|longversion|version|valuesfromarguments)$' | sort
|
||||||
#grep -E '^[a-z0-9\_-]*(\)|\|\\)$' "${labelFile}" | tr -d ')|\' | grep -v -E '^(broken.*|longversion|version|valuesfromarguments)$' | sort
|
#grep -E '^[a-z0-9\_-]*(\)|\|\\)$' "${labelFile}" | tr -d ')|\' | grep -v -E '^(broken.*|longversion|version|valuesfromarguments)$' | sort
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
elif [[ $1 == "/" ]]; then
|
elif [[ $1 == "/" ]]; then
|
||||||
# jamf uses sends '/' as the first argument
|
# jamf uses sends '/' as the first argument
|
||||||
printlog "shifting arguments for Jamf"
|
printlog "shifting arguments for Jamf" REQ
|
||||||
shift 3
|
shift 3
|
||||||
fi
|
fi
|
||||||
|
|
||||||
while [[ -n $1 ]]; do
|
while [[ -n $1 ]]; do
|
||||||
if [[ $1 =~ ".*\=.*" ]]; then
|
if [[ $1 =~ ".*\=.*" ]]; then
|
||||||
# if an argument contains an = character, send it to eval
|
# if an argument contains an = character, send it to eval
|
||||||
printlog "setting variable from argument $1"
|
printlog "setting variable from argument $1" WARN
|
||||||
eval $1
|
eval $1
|
||||||
else
|
else
|
||||||
# assume it's a label
|
# assume it's a label
|
||||||
@@ -36,44 +37,90 @@ done
|
|||||||
# lowercase the label
|
# lowercase the label
|
||||||
label=${label:l}
|
label=${label:l}
|
||||||
|
|
||||||
printlog "################## Start Installomator v. $VERSION"
|
# separate check for 'version' in order to print plain version number without any other information
|
||||||
printlog "################## $label"
|
if [[ $label == "version" ]]; then
|
||||||
|
echo "$VERSION"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# MARK: Logging
|
||||||
|
log_location="/private/var/log/Installomator.log"
|
||||||
|
|
||||||
|
# Check if we're in debug mode, if so then set logging to DEBUG, otherwise default to INFO
|
||||||
|
# if no log level is specified.
|
||||||
|
if [[ $DEBUG -ne 0 ]]; then
|
||||||
|
LOGGING=DEBUG
|
||||||
|
elif [[ -z $LOGGING ]]; then
|
||||||
|
LOGGING=INFO
|
||||||
|
datadogLoggingLevel=INFO
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Associate logging levels with a numerical value so that we are able to identify what
|
||||||
|
# should be removed. For example if the LOGGING=ERROR only printlog statements with the
|
||||||
|
# level REQ and ERROR will be displayed. LOGGING=DEBUG will show all printlog statements.
|
||||||
|
# If a printlog statement has no level set it's automatically assigned INFO.
|
||||||
|
|
||||||
|
declare -A levels=(DEBUG 0 INFO 1 WARN 2 ERROR 3 REQ 4)
|
||||||
|
|
||||||
|
# If we are able to detect an MDM URL (Jamf Pro) or another identifier for a customer/instance we grab it here, this is useful if we're centrally logging multiple MDM instances.
|
||||||
|
if [[ -f /Library/Preferences/com.jamfsoftware.jamf.plist ]]; then
|
||||||
|
mdmURL=$(defaults read /Library/Preferences/com.jamfsoftware.jamf.plist jss_url)
|
||||||
|
elif [[ -n "$MDMProfileName" ]]; then
|
||||||
|
mdmURL=$(sudo profiles show | grep -A3 "$MDMProfileName" | sed -n -e 's/^.*organization: //p')
|
||||||
|
else
|
||||||
|
mdmURL="Unknown"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Generate a session key for this run, this is useful to idenify streams when we're centrally logging.
|
||||||
|
SESSION=$RANDOM
|
||||||
|
|
||||||
|
# Mark: START
|
||||||
|
printlog "################## Start Installomator v. $VERSION, date $VERSIONDATE" REQ
|
||||||
|
printlog "################## Version: $VERSION" INFO
|
||||||
|
printlog "################## Date: $VERSIONDATE" INFO
|
||||||
|
printlog "################## $label" INFO
|
||||||
|
|
||||||
|
# Check for DEBUG mode
|
||||||
|
if [[ $DEBUG -gt 0 ]]; then
|
||||||
|
printlog "DEBUG mode $DEBUG enabled." DEBUG
|
||||||
|
fi
|
||||||
|
|
||||||
# How we get version number from app
|
# How we get version number from app
|
||||||
# (alternative is "CFBundleVersion", that can be used in labels)
|
if [[ -z $versionKey ]]; then
|
||||||
versionKey="CFBundleShortVersionString"
|
versionKey="CFBundleShortVersionString"
|
||||||
|
fi
|
||||||
|
|
||||||
# get current user
|
# get current user
|
||||||
currentUser=$(scutil <<< "show State:/Users/ConsoleUser" | awk '/Name :/ { print $3 }')
|
currentUser=$(scutil <<< "show State:/Users/ConsoleUser" | awk '/Name :/ { print $3 }')
|
||||||
|
|
||||||
|
# MARK: check for root
|
||||||
|
if [[ "$(whoami)" != "root" && "$DEBUG" -eq 0 ]]; then
|
||||||
|
# not running as root
|
||||||
|
cleanupAndExit 6 "not running as root, exiting" ERROR
|
||||||
|
fi
|
||||||
|
|
||||||
# MARK: labels in case statement
|
# MARK: labels in case statement
|
||||||
case $label in
|
case $label in
|
||||||
version)
|
|
||||||
# print the script VERSION
|
|
||||||
printlog "$VERSION"
|
|
||||||
exit 0
|
|
||||||
;;
|
|
||||||
longversion)
|
longversion)
|
||||||
# print the script version
|
# print the script version
|
||||||
printlog "Installomater: version $VERSION ($VERSIONDATE)"
|
printlog "Installomater: version $VERSION ($VERSIONDATE)" REQ
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
valuesfromarguments)
|
valuesfromarguments)
|
||||||
if [[ -z $name ]]; then
|
if [[ -z $name ]]; then
|
||||||
printlog "need to provide 'name'"
|
printlog "need to provide 'name'" ERROR
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
if [[ -z $type ]]; then
|
if [[ -z $type ]]; then
|
||||||
printlog "need to provide 'type'"
|
printlog "need to provide 'type'" ERROR
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
if [[ -z $downloadURL ]]; then
|
if [[ -z $downloadURL ]]; then
|
||||||
printlog "need to provide 'downloadURL'"
|
printlog "need to provide 'downloadURL'" ERROR
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
if [[ -z $expectedTeamID ]]; then
|
if [[ -z $expectedTeamID ]]; then
|
||||||
printlog "need to provide 'expectedTeamID'"
|
printlog "need to provide 'expectedTeamID'" ERROR
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
|
|||||||
7
fragments/disabled/mightymike.sh
Normal file
7
fragments/disabled/mightymike.sh
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
mightymike)
|
||||||
|
name="Mighty Mike"
|
||||||
|
type="dmg"
|
||||||
|
downloadURL=$(downloadURLFromGit jorio MightyMike)
|
||||||
|
appNewVersion=$(versionFromGit jorio MightyMike)
|
||||||
|
expectedTeamID="RVNL7XC27G"
|
||||||
|
;;
|
||||||
@@ -1,23 +1,33 @@
|
|||||||
# MARK: Functions
|
# MARK: Functions
|
||||||
|
|
||||||
cleanupAndExit() { # $1 = exit code, $2 message
|
cleanupAndExit() { # $1 = exit code, $2 message, $3 level
|
||||||
if [[ -n $2 && $1 -ne 0 ]]; then
|
|
||||||
printlog "ERROR: $2"
|
|
||||||
fi
|
|
||||||
if [ "$DEBUG" -eq 0 ]; then
|
|
||||||
# remove the temporary working directory when done
|
|
||||||
printlog "Deleting $tmpDir"
|
|
||||||
rm -Rf "$tmpDir"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$dmgmount" ]; then
|
if [ -n "$dmgmount" ]; then
|
||||||
# unmount disk image
|
# unmount disk image
|
||||||
printlog "Unmounting $dmgmount"
|
printlog "Unmounting $dmgmount" DEBUG
|
||||||
hdiutil detach "$dmgmount"
|
unmountingOut=$(hdiutil detach "$dmgmount" 2>&1)
|
||||||
|
printlog "Debugging enabled, Unmounting output was:\n$unmountingOut" DEBUG
|
||||||
fi
|
fi
|
||||||
|
if [ "$DEBUG" -ne 1 ]; then
|
||||||
|
# remove the temporary working directory when done (only if DEBUG is not used)
|
||||||
|
printlog "Deleting $tmpDir" DEBUG
|
||||||
|
deleteTmpOut=$(rm -Rfv "$tmpDir")
|
||||||
|
printlog "Debugging enabled, Deleting tmpDir output was:\n$deleteTmpOut" DEBUG
|
||||||
|
fi
|
||||||
|
|
||||||
# If we closed any processes, reopen the app again
|
# If we closed any processes, reopen the app again
|
||||||
reopenClosedProcess
|
reopenClosedProcess
|
||||||
printlog "################## End Installomator, exit code $1 \n\n"
|
if [[ -n $2 && $1 -ne 0 ]]; then
|
||||||
|
printlog "ERROR: $2" $3
|
||||||
|
else
|
||||||
|
printlog "$2" $3
|
||||||
|
fi
|
||||||
|
printlog "################## End Installomator, exit code $1 \n" REQ
|
||||||
|
|
||||||
|
# if label is wrong and we wanted name of the label, then return ##################
|
||||||
|
if [[ $RETURN_LABEL_NAME -eq 1 ]]; then
|
||||||
|
1=0 # If only label name should be returned we exit without any errors
|
||||||
|
echo "#"
|
||||||
|
fi
|
||||||
exit "$1"
|
exit "$1"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,26 +69,84 @@ displaynotification() { # $1: message $2: title
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# MARK: Logging
|
|
||||||
log_location="/private/var/log/Installomator.log"
|
|
||||||
|
|
||||||
printlog(){
|
printlog(){
|
||||||
|
[ -z "$2" ] && 2=INFO
|
||||||
|
log_message=$1
|
||||||
|
log_priority=$2
|
||||||
timestamp=$(date +%F\ %T)
|
timestamp=$(date +%F\ %T)
|
||||||
|
|
||||||
if [[ "$(whoami)" == "root" ]]; then
|
# Check to make sure that the log isn't the same as the last, if it is then don't log and increment a timer.
|
||||||
echo "$timestamp" "$label" "$1" | tee -a $log_location
|
if [[ ${log_message} == ${previous_log_message} ]]; then
|
||||||
else
|
let logrepeat=$logrepeat+1
|
||||||
echo "$timestamp" "$label" "$1"
|
return
|
||||||
fi
|
fi
|
||||||
|
previous_log_message=$log_message
|
||||||
|
|
||||||
|
# Once we finally stop getting duplicate logs output the number of times we got a duplicate.
|
||||||
|
if [[ $logrepeat -gt 1 ]];then
|
||||||
|
echo "$timestamp" : "${log_priority} : $label : Last Log repeated ${logrepeat} times" | tee -a $log_location
|
||||||
|
|
||||||
|
if [[ ! -z $datadogAPI ]]; then
|
||||||
|
curl -s -X POST https://http-intake.logs.datadoghq.com/v1/input -H "Content-Type: text/plain" -H "DD-API-KEY: $datadogAPI" -d "${log_priority} : $mdmURL : $APPLICATION : $VERSION : $SESSION : Last Log repeated ${logrepeat} times" > /dev/null
|
||||||
|
fi
|
||||||
|
logrepeat=0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If the datadogAPI key value is set and our logging level is greater than or equal to our set level
|
||||||
|
# then post to Datadog's HTTPs endpoint.
|
||||||
|
if [[ -n $datadogAPI && ${levels[$log_priority]} -ge ${levels[$datadogLoggingLevel]} ]]; then
|
||||||
|
while IFS= read -r logmessage; do
|
||||||
|
curl -s -X POST https://http-intake.logs.datadoghq.com/v1/input -H "Content-Type: text/plain" -H "DD-API-KEY: $datadogAPI" -d "${log_priority} : $mdmURL : Installomator-${label} : ${VERSIONDATE//-/} : $SESSION : ${logmessage}" > /dev/null
|
||||||
|
done <<< "$log_message"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Extra spaces
|
||||||
|
space_char=""
|
||||||
|
if [[ ${#log_priority} -eq 3 ]]; then
|
||||||
|
space_char=" "
|
||||||
|
elif [[ ${#log_priority} -eq 4 ]]; then
|
||||||
|
space_char=" "
|
||||||
|
fi
|
||||||
|
# If our logging level is greaterthan or equal to our set level then output locally.
|
||||||
|
if [[ ${levels[$log_priority]} -ge ${levels[$LOGGING]} ]]; then
|
||||||
|
while IFS= read -r logmessage; do
|
||||||
|
if [[ "$(whoami)" == "root" ]]; then
|
||||||
|
echo "$timestamp" : "${log_priority}${space_char} : $label : ${logmessage}" | tee -a $log_location
|
||||||
|
else
|
||||||
|
echo "$timestamp" : "${log_priority}${space_char} : $label : ${logmessage}"
|
||||||
|
fi
|
||||||
|
done <<< "$log_message"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Used to remove dupplicate lines in large log output,
|
||||||
|
# for example from msupdate command after it finishes running.
|
||||||
|
deduplicatelogs() {
|
||||||
|
loginput=${1:-"Log"}
|
||||||
|
logoutput=""
|
||||||
|
# Read each line of the incoming log individually, match it with the previous.
|
||||||
|
# If it matches increment logrepeate then skip to the next line.
|
||||||
|
while read log; do
|
||||||
|
if [[ $log == $previous_log ]];then
|
||||||
|
let logrepeat=$logrepeat+1
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
previous_log="$log"
|
||||||
|
if [[ $logrepeat -gt 1 ]];then
|
||||||
|
logoutput+="Last Log repeated ${logrepeat} times\n"
|
||||||
|
logrepeat=0
|
||||||
|
fi
|
||||||
|
|
||||||
|
logoutput+="$log\n"
|
||||||
|
done <<< "$loginput"
|
||||||
}
|
}
|
||||||
|
|
||||||
# will get the latest release download from a github repo
|
# will get the latest release download from a github repo
|
||||||
downloadURLFromGit() { # $1 git user name, $2 git repo name
|
downloadURLFromGit() { # $1 git user name, $2 git repo name
|
||||||
gitusername=${1?:"no git user name"}
|
gitusername=${1?:"no git user name"}
|
||||||
gitreponame=${2?:"no git repo name"}
|
gitreponame=${2?:"no git repo name"}
|
||||||
|
|
||||||
if [[ $type == "pkgInDmg" ]]; then
|
if [[ $type == "pkgInDmg" ]]; then
|
||||||
filetype="dmg"
|
filetype="dmg"
|
||||||
elif [[ $type == "pkgInZip" ]]; then
|
elif [[ $type == "pkgInZip" ]]; then
|
||||||
@@ -86,17 +154,16 @@ downloadURLFromGit() { # $1 git user name, $2 git repo name
|
|||||||
else
|
else
|
||||||
filetype=$type
|
filetype=$type
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -n "$archiveName" ]; then
|
if [ -n "$archiveName" ]; then
|
||||||
downloadURL=$(curl --silent --fail "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" \
|
downloadURL=$(curl -L --silent --fail "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" \
|
||||||
| awk -F '"' "/browser_download_url/ && /$archiveName\"/ { print \$4; exit }")
|
| awk -F '"' "/browser_download_url/ && /$archiveName\"/ { print \$4; exit }")
|
||||||
else
|
else
|
||||||
downloadURL=$(curl --silent --fail "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" \
|
downloadURL=$(curl -L --silent --fail "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" \
|
||||||
| awk -F '"' "/browser_download_url/ && /$filetype\"/ { print \$4; exit }")
|
| awk -F '"' "/browser_download_url/ && /$filetype\"/ { print \$4; exit }")
|
||||||
fi
|
fi
|
||||||
if [ -z "$downloadURL" ]; then
|
if [ -z "$downloadURL" ]; then
|
||||||
cleanupAndExit 9 "could not retrieve download URL for $gitusername/$gitreponame"
|
cleanupAndExit 9 "could not retrieve download URL for $gitusername/$gitreponame" ERROR
|
||||||
#exit 9
|
|
||||||
else
|
else
|
||||||
echo "$downloadURL"
|
echo "$downloadURL"
|
||||||
return 0
|
return 0
|
||||||
@@ -108,10 +175,10 @@ versionFromGit() {
|
|||||||
# $1 git user name, $2 git repo name
|
# $1 git user name, $2 git repo name
|
||||||
gitusername=${1?:"no git user name"}
|
gitusername=${1?:"no git user name"}
|
||||||
gitreponame=${2?:"no git repo name"}
|
gitreponame=${2?:"no git repo name"}
|
||||||
|
|
||||||
appNewVersion=$(curl --silent --fail "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" | grep tag_name | cut -d '"' -f 4 | sed 's/[^0-9\.]//g')
|
appNewVersion=$(curl -L --silent --fail "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" | grep tag_name | cut -d '"' -f 4 | sed 's/[^0-9\.]//g')
|
||||||
if [ -z "$appNewVersion" ]; then
|
if [ -z "$appNewVersion" ]; then
|
||||||
printlog "could not retrieve version number for $gitusername/$gitreponame"
|
printlog "could not retrieve version number for $gitusername/$gitreponame" WARN
|
||||||
appNewVersion=""
|
appNewVersion=""
|
||||||
else
|
else
|
||||||
echo "$appNewVersion"
|
echo "$appNewVersion"
|
||||||
@@ -122,7 +189,7 @@ versionFromGit() {
|
|||||||
|
|
||||||
# Handling of differences in xpath between Catalina and Big Sur
|
# Handling of differences in xpath between Catalina and Big Sur
|
||||||
xpath() {
|
xpath() {
|
||||||
# the xpath tool changes in Big Sur and now requires the `-e` option
|
# the xpath tool changes in Big Sur and now requires the `-e` option
|
||||||
if [[ $(sw_vers -buildVersion) > "20A" ]]; then
|
if [[ $(sw_vers -buildVersion) > "20A" ]]; then
|
||||||
/usr/bin/xpath -e $@
|
/usr/bin/xpath -e $@
|
||||||
# alternative: switch to xmllint (which is not perl)
|
# alternative: switch to xmllint (which is not perl)
|
||||||
@@ -142,27 +209,47 @@ getAppVersion() {
|
|||||||
printlog "Custom App Version detection is used, found $appversion"
|
printlog "Custom App Version detection is used, found $appversion"
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# pkgs contains a version number, then we don't have to search for an app
|
# pkgs contains a version number, then we don't have to search for an app
|
||||||
if [[ $packageID != "" ]]; then
|
if [[ $packageID != "" ]]; then
|
||||||
appversion="$(pkgutil --pkg-info-plist ${packageID} 2>/dev/null | grep -A 1 pkg-version | tail -1 | sed -E 's/.*>([0-9.]*)<.*/\1/g')"
|
appversion="$(pkgutil --pkg-info-plist ${packageID} 2>/dev/null | grep -A 1 pkg-version | tail -1 | sed -E 's/.*>([0-9.]*)<.*/\1/g')"
|
||||||
if [[ $appversion != "" ]]; then
|
if [[ $appversion != "" ]]; then
|
||||||
printlog "found packageID $packageID installed, version $appversion"
|
printlog "found packageID $packageID installed, version $appversion"
|
||||||
|
updateDetected="YES"
|
||||||
return
|
return
|
||||||
else
|
else
|
||||||
printlog "No version found using packageID $packageID"
|
printlog "No version found using packageID $packageID"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# get app in /Applications, or /Applications/Utilities, or find using Spotlight
|
# get app in targetDir, /Applications, or /Applications/Utilities
|
||||||
if [[ -d "/Applications/$appName" ]]; then
|
if [[ -d "$targetDir/$appName" ]]; then
|
||||||
|
applist="$targetDir/$appName"
|
||||||
|
elif [[ -d "/Applications/$appName" ]]; then
|
||||||
applist="/Applications/$appName"
|
applist="/Applications/$appName"
|
||||||
|
# if [[ $type =~ '^(dmg|zip|tbz|app.*)$' ]]; then
|
||||||
|
# targetDir="/Applications"
|
||||||
|
# fi
|
||||||
elif [[ -d "/Applications/Utilities/$appName" ]]; then
|
elif [[ -d "/Applications/Utilities/$appName" ]]; then
|
||||||
applist="/Applications/Utilities/$appName"
|
applist="/Applications/Utilities/$appName"
|
||||||
|
# if [[ $type =~ '^(dmg|zip|tbz|app.*)$' ]]; then
|
||||||
|
# targetDir="/Applications/Utilities"
|
||||||
|
# fi
|
||||||
else
|
else
|
||||||
applist=$(mdfind "kind:application $appName" -0 )
|
# applist=$(mdfind "kind:application $appName" -0 )
|
||||||
|
printlog "name: $name, appName: $appName"
|
||||||
|
applist=$(mdfind "kind:application AND name:$name" -0 )
|
||||||
|
# printlog "App(s) found: ${applist}" DEBUG
|
||||||
|
# applist=$(mdfind "kind:application AND name:$appName" -0 )
|
||||||
fi
|
fi
|
||||||
printlog "App(s) found: ${applist}"
|
if [[ -z applist ]]; then
|
||||||
|
printlog "No previous app found" INFO
|
||||||
|
else
|
||||||
|
printlog "App(s) found: ${applist}" INFO
|
||||||
|
fi
|
||||||
|
# if [[ $type =~ '^(dmg|zip|tbz|app.*)$' ]]; then
|
||||||
|
# printlog "targetDir for installation: $targetDir" INFO
|
||||||
|
# fi
|
||||||
|
|
||||||
appPathArray=( ${(0)applist} )
|
appPathArray=( ${(0)applist} )
|
||||||
|
|
||||||
@@ -172,7 +259,8 @@ getAppVersion() {
|
|||||||
installedAppPath=$filteredAppPaths[1]
|
installedAppPath=$filteredAppPaths[1]
|
||||||
#appversion=$(mdls -name kMDItemVersion -raw $installedAppPath )
|
#appversion=$(mdls -name kMDItemVersion -raw $installedAppPath )
|
||||||
appversion=$(defaults read $installedAppPath/Contents/Info.plist $versionKey) #Not dependant on Spotlight indexing
|
appversion=$(defaults read $installedAppPath/Contents/Info.plist $versionKey) #Not dependant on Spotlight indexing
|
||||||
printlog "found app at $installedAppPath, version $appversion"
|
printlog "found app at $installedAppPath, version $appversion, on versionKey $versionKey"
|
||||||
|
updateDetected="YES"
|
||||||
# Is current app from App Store
|
# Is current app from App Store
|
||||||
if [[ -d "$installedAppPath"/Contents/_MASReceipt ]];then
|
if [[ -d "$installedAppPath"/Contents/_MASReceipt ]];then
|
||||||
printlog "Installed $appName is from App Store, use “IGNORE_APP_STORE_APPS=yes” to replace."
|
printlog "Installed $appName is from App Store, use “IGNORE_APP_STORE_APPS=yes” to replace."
|
||||||
@@ -180,21 +268,21 @@ getAppVersion() {
|
|||||||
printlog "Replacing App Store apps, no matter the version"
|
printlog "Replacing App Store apps, no matter the version"
|
||||||
appversion=0
|
appversion=0
|
||||||
else
|
else
|
||||||
cleanupAndExit 1 "App previously installed from App Store, and we respect that"
|
cleanupAndExit 1 "App previously installed from App Store, and we respect that" ERROR
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
printlog "could not determine location of $appName"
|
printlog "could not determine location of $appName" WARN
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
printlog "could not find $appName"
|
printlog "could not find $appName" WARN
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
checkRunningProcesses() {
|
checkRunningProcesses() {
|
||||||
# don't check in DEBUG mode
|
# don't check in DEBUG mode 1
|
||||||
if [[ $DEBUG -ne 0 ]]; then
|
if [[ $DEBUG -eq 1 ]]; then
|
||||||
printlog "DEBUG mode, not checking for blocking processes"
|
printlog "DEBUG mode 1, not checking for blocking processes" DEBUG
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -205,7 +293,7 @@ checkRunningProcesses() {
|
|||||||
if pgrep -xq "$x"; then
|
if pgrep -xq "$x"; then
|
||||||
printlog "found blocking process $x"
|
printlog "found blocking process $x"
|
||||||
appClosed=1
|
appClosed=1
|
||||||
|
|
||||||
case $BLOCKING_PROCESS_ACTION in
|
case $BLOCKING_PROCESS_ACTION in
|
||||||
quit|quit_kill)
|
quit|quit_kill)
|
||||||
printlog "telling app $x to quit"
|
printlog "telling app $x to quit"
|
||||||
@@ -227,7 +315,7 @@ checkRunningProcesses() {
|
|||||||
prompt_user|prompt_user_then_kill)
|
prompt_user|prompt_user_then_kill)
|
||||||
button=$(displaydialog "Quit “$x” to continue updating? (Leave this dialogue if you want to activate this update later)." "The application “$x” needs to be updated.")
|
button=$(displaydialog "Quit “$x” to continue updating? (Leave this dialogue if you want to activate this update later)." "The application “$x” needs to be updated.")
|
||||||
if [[ $button = "Not Now" ]]; then
|
if [[ $button = "Not Now" ]]; then
|
||||||
cleanupAndExit 10 "user aborted update"
|
cleanupAndExit 10 "user aborted update" ERROR
|
||||||
else
|
else
|
||||||
if [[ $i > 2 && $BLOCKING_PROCESS_ACTION = "prompt_user_then_kill" ]]; then
|
if [[ $i > 2 && $BLOCKING_PROCESS_ACTION = "prompt_user_then_kill" ]]; then
|
||||||
printlog "Changing BLOCKING_PROCESS_ACTION to kill"
|
printlog "Changing BLOCKING_PROCESS_ACTION to kill"
|
||||||
@@ -272,7 +360,7 @@ checkRunningProcesses() {
|
|||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
silent_fail)
|
silent_fail)
|
||||||
cleanupAndExit 12 "blocking process '$x' found, aborting"
|
cleanupAndExit 12 "blocking process '$x' found, aborting" ERROR
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
@@ -283,28 +371,28 @@ checkRunningProcesses() {
|
|||||||
done
|
done
|
||||||
|
|
||||||
if [[ $countedProcesses -ne 0 ]]; then
|
if [[ $countedProcesses -ne 0 ]]; then
|
||||||
cleanupAndExit 11 "could not quit all processes, aborting..."
|
cleanupAndExit 11 "could not quit all processes, aborting..." ERROR
|
||||||
fi
|
fi
|
||||||
|
|
||||||
printlog "no more blocking processes, continue with update"
|
printlog "no more blocking processes, continue with update" REQ
|
||||||
}
|
}
|
||||||
|
|
||||||
reopenClosedProcess() {
|
reopenClosedProcess() {
|
||||||
# If Installomator closed any processes, let's get the app opened again
|
# If Installomator closed any processes, let's get the app opened again
|
||||||
# credit: Søren Theilgaard (@theilgaard)
|
# credit: Søren Theilgaard (@theilgaard)
|
||||||
|
|
||||||
# don't reopen if REOPEN is not "yes"
|
# don't reopen if REOPEN is not "yes"
|
||||||
if [[ $REOPEN != yes ]]; then
|
if [[ $REOPEN != yes ]]; then
|
||||||
printlog "REOPEN=no, not reopening anything"
|
printlog "REOPEN=no, not reopening anything"
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# don't reopen in DEBUG mode
|
# don't reopen in DEBUG mode 1
|
||||||
if [[ $DEBUG -ne 0 ]]; then
|
if [[ $DEBUG -eq 1 ]]; then
|
||||||
printlog "DEBUG mode, not reopening anything"
|
printlog "DEBUG mode 1, not reopening anything" DEBUG
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ $appClosed == 1 ]]; then
|
if [[ $appClosed == 1 ]]; then
|
||||||
printlog "Telling app $appName to open"
|
printlog "Telling app $appName to open"
|
||||||
#runAsUser osascript -e "tell app \"$appName\" to open"
|
#runAsUser osascript -e "tell app \"$appName\" to open"
|
||||||
@@ -314,7 +402,7 @@ reopenClosedProcess() {
|
|||||||
processuser=$(ps aux | grep -i "${appName}" | grep -vi "grep" | awk '{print $1}')
|
processuser=$(ps aux | grep -i "${appName}" | grep -vi "grep" | awk '{print $1}')
|
||||||
printlog "Reopened ${appName} as $processuser"
|
printlog "Reopened ${appName} as $processuser"
|
||||||
else
|
else
|
||||||
printlog "App not closed, so no reopen."
|
printlog "App not closed, so no reopen." INFO
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,71 +412,123 @@ installAppWithPath() { # $1: path to app to install in $targetDir
|
|||||||
|
|
||||||
# check if app exists
|
# check if app exists
|
||||||
if [ ! -e "$appPath" ]; then
|
if [ ! -e "$appPath" ]; then
|
||||||
cleanupAndExit 8 "could not find: $appPath"
|
cleanupAndExit 8 "could not find: $appPath" ERROR
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# verify with spctl
|
# verify with spctl
|
||||||
printlog "Verifying: $appPath"
|
printlog "Verifying: $appPath" INFO
|
||||||
if ! teamID=$(spctl -a -vv "$appPath" 2>&1 | awk '/origin=/ {print $NF }' | tr -d '()' ); then
|
printlog "App size: $(du -sh "$appPath")" DEBUG
|
||||||
cleanupAndExit 4 "Error verifying $appPath"
|
appVerify=$(spctl -a -vv "$appPath" 2>&1 )
|
||||||
fi
|
appVerifyStatus=$(echo $?)
|
||||||
|
teamID=$(echo $appVerify | awk '/origin=/ {print $NF }' | tr -d '()' )
|
||||||
|
deduplicatelogs "$appVerify"
|
||||||
|
|
||||||
printlog "Team ID matching: $teamID (expected: $expectedTeamID )"
|
if [[ $appVerifyStatus -ne 0 ]] ; then
|
||||||
|
#if ! teamID=$(spctl -a -vv "$appPath" 2>&1 | awk '/origin=/ {print $NF }' | tr -d '()' ); then
|
||||||
|
cleanupAndExit 4 "Error verifying $appPath error:\n$logoutput" ERROR
|
||||||
|
fi
|
||||||
|
printlog "Debugging enabled, App Verification output was:\n$logoutput" DEBUG
|
||||||
|
printlog "Team ID matching: $teamID (expected: $expectedTeamID )" INFO
|
||||||
|
|
||||||
if [ "$expectedTeamID" != "$teamID" ]; then
|
if [ "$expectedTeamID" != "$teamID" ]; then
|
||||||
cleanupAndExit 5 "Team IDs do not match"
|
cleanupAndExit 5 "Team IDs do not match" ERROR
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# versioncheck
|
# app versioncheck
|
||||||
# credit: Søren Theilgaard (@theilgaard)
|
|
||||||
appNewVersion=$(defaults read $appPath/Contents/Info.plist $versionKey)
|
appNewVersion=$(defaults read $appPath/Contents/Info.plist $versionKey)
|
||||||
if [[ $appversion == $appNewVersion ]]; then
|
if [[ -n $appNewVersion && $appversion == $appNewVersion ]]; then
|
||||||
printlog "Downloaded version of $name is $appNewVersion, same as installed."
|
printlog "Downloaded version of $name is $appNewVersion on versionKey $versionKey, same as installed."
|
||||||
if [[ $INSTALL != "force" ]]; then
|
if [[ $INSTALL != "force" ]]; then
|
||||||
message="$name, version $appNewVersion, is the latest version."
|
message="$name, version $appNewVersion, is the latest version."
|
||||||
if [[ $currentUser != "loginwindow" && $NOTIFY == "all" ]]; then
|
if [[ $currentUser != "loginwindow" && $NOTIFY == "all" ]]; then
|
||||||
printlog "notifying"
|
printlog "notifying"
|
||||||
displaynotification "$message" "No update for $name!"
|
displaynotification "$message" "No update for $name!"
|
||||||
fi
|
fi
|
||||||
cleanupAndExit 0 "No new version to install"
|
cleanupAndExit 0 "No new version to install" REG
|
||||||
else
|
else
|
||||||
printlog "Using force to install anyway."
|
printlog "Using force to install anyway."
|
||||||
fi
|
fi
|
||||||
|
elif [[ -z $appversion ]]; then
|
||||||
|
printlog "Installing $name version $appNewVersion on versionKey $versionKey."
|
||||||
else
|
else
|
||||||
printlog "Downloaded version of $name is $appNewVersion (replacing version $appversion)."
|
printlog "Downloaded version of $name is $appNewVersion on versionKey $versionKey (replacing version $appversion)."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# skip install for DEBUG
|
# macOS versioncheck
|
||||||
if [ "$DEBUG" -ne 0 ]; then
|
minimumOSversion=$(defaults read $appPath/Contents/Info.plist LSMinimumSystemVersion 2>/dev/null )
|
||||||
printlog "DEBUG enabled, skipping remove, copy and chown steps"
|
if [[ -n $minimumOSversion && $minimumOSversion =~ '[0-9.]*' ]]; then
|
||||||
|
printlog "App has LSMinimumSystemVersion: $minimumOSversion"
|
||||||
|
if ! is-at-least $minimumOSversion $installedOSversion; then
|
||||||
|
printlog "App requires higher System Version than installed: $installedOSversion"
|
||||||
|
message="Cannot install $name, version $appNewVersion, as it is not compatible with the running system version."
|
||||||
|
if [[ $currentUser != "loginwindow" && $NOTIFY == "all" ]]; then
|
||||||
|
printlog "notifying"
|
||||||
|
displaynotification "$message" "Error updating $name!"
|
||||||
|
fi
|
||||||
|
cleanupAndExit 6 "Installed macOS is too old for this app." ERROR
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# skip install for DEBUG 1
|
||||||
|
if [ "$DEBUG" -eq 1 ]; then
|
||||||
|
printlog "DEBUG mode 1 enabled, skipping remove, copy and chown steps" DEBUG
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# check for root
|
# skip install for DEBUG 2
|
||||||
if [ "$(whoami)" != "root" ]; then
|
if [ "$DEBUG" -eq 2 ]; then
|
||||||
# not running as root
|
printlog "DEBUG mode 2 enabled, not installing anything, exiting" DEBUG
|
||||||
cleanupAndExit 6 "not running as root, exiting"
|
cleanupAndExit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# remove existing application
|
# Test if variable CLIInstaller is set
|
||||||
if [ -e "$targetDir/$appName" ]; then
|
if [[ -z $CLIInstaller ]]; then
|
||||||
printlog "Removing existing $targetDir/$appName"
|
|
||||||
rm -Rf "$targetDir/$appName"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# copy app to /Applications
|
# remove existing application
|
||||||
printlog "Copy $appPath to $targetDir"
|
if [ -e "$targetDir/$appName" ]; then
|
||||||
if ! ditto "$appPath" "$targetDir/$appName"; then
|
printlog "Removing existing $targetDir/$appName" WARN
|
||||||
cleanupAndExit 7 "Error while copying"
|
deleteAppOut=$(rm -Rfv "$targetDir/$appName" 2>&1)
|
||||||
fi
|
tempName="$targetDir/$appName"
|
||||||
|
tempNameLength=$((${#tempName} + 10))
|
||||||
|
deleteAppOut=$(echo $deleteAppOut | cut -c 1-$tempNameLength)
|
||||||
|
deduplicatelogs "$deleteAppOut"
|
||||||
|
printlog "Debugging enabled, App removing output was:\n$logoutput" DEBUG
|
||||||
|
fi
|
||||||
|
|
||||||
|
# copy app to /Applications
|
||||||
|
printlog "Copy $appPath to $targetDir"
|
||||||
|
copyAppOut=$(ditto -v "$appPath" "$targetDir/$appName" 2>&1)
|
||||||
|
copyAppStatus=$(echo $?)
|
||||||
|
deduplicatelogs "$copyAppOut"
|
||||||
|
printlog "Debugging enabled, App copy output was:\n$logoutput" DEBUG
|
||||||
|
if [[ $copyAppStatus -ne 0 ]] ; then
|
||||||
|
#if ! ditto "$appPath" "$targetDir/$appName"; then
|
||||||
|
cleanupAndExit 7 "Error while copying:\n$logoutput" ERROR
|
||||||
|
fi
|
||||||
|
|
||||||
# set ownership to current user
|
# set ownership to current user
|
||||||
if [ "$currentUser" != "loginwindow" ]; then
|
if [[ "$currentUser" != "loginwindow" && $SYSTEMOWNER -ne 1 ]]; then
|
||||||
printlog "Changing owner to $currentUser"
|
printlog "Changing owner to $currentUser" WARN
|
||||||
chown -R "$currentUser" "$targetDir/$appName"
|
chown -R "$currentUser" "$targetDir/$appName"
|
||||||
else
|
else
|
||||||
printlog "No user logged in, not changing user"
|
printlog "No user logged in or SYSTEMOWNER=1, setting owner to root:wheel" WARN
|
||||||
|
chown -R root:wheel "$targetDir/$appName"
|
||||||
|
fi
|
||||||
|
|
||||||
|
elif [[ ! -z $CLIInstaller ]]; then
|
||||||
|
mountname=$(dirname $appPath)
|
||||||
|
printlog "CLIInstaller exists, running installer command $mountname/$CLIInstaller $CLIArguments" INFO
|
||||||
|
|
||||||
|
CLIoutput=$("$mountname/$CLIInstaller" "${CLIArguments[@]}" 2>&1)
|
||||||
|
CLIstatus=$(echo $?)
|
||||||
|
deduplicatelogs "$CLIoutput"
|
||||||
|
|
||||||
|
if [ $CLIstatus -ne 0 ] ; then
|
||||||
|
cleanupAndExit 3 "Error installing $mountname/$CLIInstaller $CLIArguments error:\n$logoutput" ERROR
|
||||||
|
else
|
||||||
|
printlog "Succesfully ran $mountname/$CLIInstaller $CLIArguments" INFO
|
||||||
|
fi
|
||||||
|
printlog "Debugging enabled, update tool output was:\n$logoutput" DEBUG
|
||||||
fi
|
fi
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -397,105 +537,135 @@ mountDMG() {
|
|||||||
# mount the dmg
|
# mount the dmg
|
||||||
printlog "Mounting $tmpDir/$archiveName"
|
printlog "Mounting $tmpDir/$archiveName"
|
||||||
# always pipe 'Y\n' in case the dmg requires an agreement
|
# always pipe 'Y\n' in case the dmg requires an agreement
|
||||||
if ! dmgmount=$(echo 'Y'$'\n' | hdiutil attach "$tmpDir/$archiveName" -nobrowse -readonly | tail -n 1 | cut -c 54- ); then
|
dmgmountOut=$(echo 'Y'$'\n' | hdiutil attach "$tmpDir/$archiveName" -nobrowse -readonly )
|
||||||
cleanupAndExit 3 "Error mounting $tmpDir/$archiveName"
|
dmgmountStatus=$(echo $?)
|
||||||
fi
|
dmgmount=$(echo $dmgmountOut | tail -n 1 | cut -c 54- )
|
||||||
|
deduplicatelogs "$dmgmountOut"
|
||||||
|
|
||||||
|
if [[ $dmgmountStatus -ne 0 ]] ; then
|
||||||
|
#if ! dmgmount=$(echo 'Y'$'\n' | hdiutil attach "$tmpDir/$archiveName" -nobrowse -readonly | tail -n 1 | cut -c 54- ); then
|
||||||
|
cleanupAndExit 3 "Error mounting $tmpDir/$archiveName error:\n$logoutput" ERROR
|
||||||
|
fi
|
||||||
if [[ ! -e $dmgmount ]]; then
|
if [[ ! -e $dmgmount ]]; then
|
||||||
printlog "Error mounting $tmpDir/$archiveName"
|
cleanupAndExit 3 "Error accessing mountpoint for $tmpDir/$archiveName error:\n$logoutput" ERROR
|
||||||
cleanupAndExit 3
|
|
||||||
fi
|
fi
|
||||||
|
printlog "Debugging enabled, dmgmount output was:\n$logoutput" DEBUG
|
||||||
|
|
||||||
printlog "Mounted: $dmgmount"
|
printlog "Mounted: $dmgmount" INFO
|
||||||
}
|
}
|
||||||
|
|
||||||
installFromDMG() {
|
installFromDMG() {
|
||||||
mountDMG
|
mountDMG
|
||||||
|
|
||||||
installAppWithPath "$dmgmount/$appName"
|
installAppWithPath "$dmgmount/$appName"
|
||||||
}
|
}
|
||||||
|
|
||||||
installFromPKG() {
|
installFromPKG() {
|
||||||
# verify with spctl
|
# verify with spctl
|
||||||
printlog "Verifying: $archiveName"
|
printlog "Verifying: $archiveName"
|
||||||
|
printlog "File list: $(ls -lh "$archiveName")" DEBUG
|
||||||
if ! spctlout=$(spctl -a -vv -t install "$archiveName" 2>&1 ); then
|
printlog "File type: $(file "$archiveName")" DEBUG
|
||||||
printlog "Error verifying $archiveName"
|
spctlOut=$(spctl -a -vv -t install "$archiveName" 2>&1 )
|
||||||
cleanupAndExit 4
|
spctlStatus=$(echo $?)
|
||||||
|
printlog "spctlOut is $spctlOut" DEBUG
|
||||||
|
|
||||||
|
teamID=$(echo $spctlOut | awk -F '(' '/origin=/ {print $2 }' | tr -d '()' )
|
||||||
|
# Apple signed software has no teamID, grab entire origin instead
|
||||||
|
if [[ -z $teamID ]]; then
|
||||||
|
teamID=$(echo $spctlOut | awk -F '=' '/origin=/ {print $NF }')
|
||||||
|
fi
|
||||||
|
|
||||||
|
deduplicatelogs "$spctlOut"
|
||||||
|
|
||||||
|
if [[ $spctlStatus -ne 0 ]] ; then
|
||||||
|
#if ! spctlout=$(spctl -a -vv -t install "$archiveName" 2>&1 ); then
|
||||||
|
cleanupAndExit 4 "Error verifying $archiveName error:\n$logoutput" ERROR
|
||||||
fi
|
fi
|
||||||
|
|
||||||
teamID=$(echo $spctlout | awk -F '(' '/origin=/ {print $2 }' | tr -d '()' )
|
|
||||||
|
|
||||||
# Apple signed software has no teamID, grab entire origin instead
|
# Apple signed software has no teamID, grab entire origin instead
|
||||||
if [[ -z $teamID ]]; then
|
if [[ -z $teamID ]]; then
|
||||||
teamID=$(echo $spctlout | awk -F '=' '/origin=/ {print $NF }')
|
teamID=$(echo $spctlout | awk -F '=' '/origin=/ {print $NF }')
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
printlog "Team ID: $teamID (expected: $expectedTeamID )"
|
printlog "Team ID: $teamID (expected: $expectedTeamID )"
|
||||||
|
|
||||||
if [ "$expectedTeamID" != "$teamID" ]; then
|
if [ "$expectedTeamID" != "$teamID" ]; then
|
||||||
printlog "Team IDs do not match!"
|
cleanupAndExit 5 "Team IDs do not match!" ERROR
|
||||||
cleanupAndExit 5
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check version of pkg to be installed if packageID is set
|
# Check version of pkg to be installed if packageID is set
|
||||||
if [[ $packageID != "" && $appversion != "" ]]; then
|
if [[ $packageID != "" && $appversion != "" ]]; then
|
||||||
printlog "Checking package version."
|
printlog "Checking package version."
|
||||||
pkgutil --expand "$archiveName" "$archiveName"_pkg
|
baseArchiveName=$(basename $archiveName)
|
||||||
#printlog "$(cat "$archiveName"_pkg/Distribution | xpath '//installer-gui-script/pkg-ref[@id][@version]' 2>/dev/null)"
|
expandedPkg="$tmpDir/${baseArchiveName}_pkg"
|
||||||
appNewVersion=$(cat "$archiveName"_pkg/Distribution | xpath '//installer-gui-script/pkg-ref[@id][@version]' 2>/dev/null | grep -i "$packageID" | tr ' ' '\n' | grep -i version | cut -d \" -f 2) #sed -E 's/.*\"([0-9.]*)\".*/\1/g'
|
pkgutil --expand "$archiveName" "$expandedPkg"
|
||||||
rm -r "$archiveName"_pkg
|
appNewVersion=$(cat "$expandedPkg"/Distribution | xpath 'string(//installer-gui-script/pkg-ref[@id][@version]/@version)' 2>/dev/null )
|
||||||
|
rm -r "$expandedPkg"
|
||||||
printlog "Downloaded package $packageID version $appNewVersion"
|
printlog "Downloaded package $packageID version $appNewVersion"
|
||||||
if [[ $appversion == $appNewVersion ]]; then
|
if [[ $appversion == $appNewVersion ]]; then
|
||||||
printlog "Downloaded version of $name is the same as installed."
|
printlog "Downloaded version of $name is the same as installed."
|
||||||
if [[ $INSTALL != "force" ]]; then
|
if [[ $INSTALL != "force" ]]; then
|
||||||
message="$name, version $appNewVersion, is the latest version."
|
message="$name, version $appNewVersion, is the latest version."
|
||||||
if [[ $currentUser != "loginwindow" && $NOTIFY == "all" ]]; then
|
if [[ $currentUser != "loginwindow" && $NOTIFY == "all" ]]; then
|
||||||
printlog "notifying"
|
printlog "notifying"
|
||||||
displaynotification "$message" "No update for $name!"
|
displaynotification "$message" "No update for $name!"
|
||||||
fi
|
fi
|
||||||
cleanupAndExit 0 "No new version to install"
|
cleanupAndExit 0 "No new version to install" REQ
|
||||||
else
|
else
|
||||||
printlog "Using force to install anyway."
|
printlog "Using force to install anyway."
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# skip install for DEBUG
|
# skip install for DEBUG 1
|
||||||
if [ "$DEBUG" -ne 0 ]; then
|
if [ "$DEBUG" -eq 1 ]; then
|
||||||
printlog "DEBUG enabled, skipping installation"
|
printlog "DEBUG enabled, skipping installation" DEBUG
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# check for root
|
# skip install for DEBUG 2
|
||||||
if [ "$(whoami)" != "root" ]; then
|
if [ "$DEBUG" -eq 2 ]; then
|
||||||
# not running as root
|
cleanupAndExit 0 "DEBUG mode 2 enabled, exiting" DEBUG
|
||||||
cleanupAndExit 6 "not running as root, exiting"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# install pkg
|
# install pkg
|
||||||
printlog "Installing $archiveName to $targetDir"
|
printlog "Installing $archiveName to $targetDir"
|
||||||
if ! installer -pkg "$archiveName" -tgt "$targetDir" ; then
|
pkgInstall=$(installer -verbose -dumplog -pkg "$archiveName" -tgt "$targetDir" 2>&1)
|
||||||
printlog "error installing $archiveName"
|
pkgInstallStatus=$(echo $?)
|
||||||
cleanupAndExit 9
|
sleep 1
|
||||||
|
pkgEndTime=$(date "+$LogDateFormat")
|
||||||
|
pkgInstall+=$(echo "\nOutput of /var/log/install.log below this line.\n")
|
||||||
|
pkgInstall+=$(echo "----------------------------------------------------------\n")
|
||||||
|
pkgInstall+=$(awk -v "b=$starttime" -v "e=$pkgEndTime" -F ',' '$1 >= b && $1 <= e' /var/log/install.log)
|
||||||
|
deduplicatelogs "$pkgInstall"
|
||||||
|
|
||||||
|
if [[ $pkgInstallStatus -ne 0 ]] && [[ $logoutput == *"requires Rosetta 2"* ]] && [[ $rosetta2 == no ]]; then
|
||||||
|
printlog "Package requires Rosetta 2, Installing Rosetta 2 and Installing Package" INFO
|
||||||
|
/usr/sbin/softwareupdate --install-rosetta --agree-to-license
|
||||||
|
rosetta2=yes
|
||||||
|
installFromPKG
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ $pkginstallstatus -ne 0 ]] ; then
|
||||||
|
#if ! installer -pkg "$archiveName" -tgt "$targetDir" ; then
|
||||||
|
cleanupAndExit 9 "Error installing $archiveName error:\n$logoutput" ERROR
|
||||||
|
fi
|
||||||
|
printlog "Debugging enabled, installer output was:\n$logoutput" DEBUG
|
||||||
}
|
}
|
||||||
|
|
||||||
installFromZIP() {
|
installFromZIP() {
|
||||||
# unzip the archive
|
# unzip the archive
|
||||||
printlog "Unzipping $archiveName"
|
printlog "Unzipping $archiveName"
|
||||||
|
|
||||||
# tar -xf "$archiveName"
|
# tar -xf "$archiveName"
|
||||||
|
|
||||||
# note: when you expand a zip using tar in Mojave the expanded
|
# note: when you expand a zip using tar in Mojave the expanded
|
||||||
# app will never pass the spctl check
|
# app will never pass the spctl check
|
||||||
|
|
||||||
# unzip -o -qq "$archiveName"
|
# unzip -o -qq "$archiveName"
|
||||||
|
|
||||||
# note: githubdesktop fails spctl verification when expanded
|
# note: githubdesktop fails spctl verification when expanded
|
||||||
# with unzip
|
# with unzip
|
||||||
|
|
||||||
ditto -x -k "$archiveName" "$tmpDir"
|
ditto -x -k "$archiveName" "$tmpDir"
|
||||||
installAppWithPath "$tmpDir/$appName"
|
installAppWithPath "$tmpDir/$appName"
|
||||||
}
|
}
|
||||||
@@ -512,17 +682,29 @@ installPkgInDmg() {
|
|||||||
# locate pkg in dmg
|
# locate pkg in dmg
|
||||||
if [[ -z $pkgName ]]; then
|
if [[ -z $pkgName ]]; then
|
||||||
# find first file ending with 'pkg'
|
# find first file ending with 'pkg'
|
||||||
findfiles=$(find "$dmgmount" -iname "*.pkg" -maxdepth 1 )
|
findfiles=$(find "$dmgmount" -iname "*.pkg" -type f -maxdepth 1 )
|
||||||
|
printlog "Found pkg(s):\n$findfiles" DEBUG
|
||||||
filearray=( ${(f)findfiles} )
|
filearray=( ${(f)findfiles} )
|
||||||
if [[ ${#filearray} -eq 0 ]]; then
|
if [[ ${#filearray} -eq 0 ]]; then
|
||||||
cleanupAndExit 20 "couldn't find pkg in dmg $archiveName"
|
cleanupAndExit 20 "couldn't find pkg in dmg $archiveName" ERROR
|
||||||
fi
|
fi
|
||||||
archiveName="${filearray[1]}"
|
archiveName="${filearray[1]}"
|
||||||
printlog "found pkg: $archiveName"
|
|
||||||
else
|
else
|
||||||
# it is now safe to overwrite archiveName for installFromPKG
|
if [[ -s "$dmgmount/$pkgName" ]] ; then # was: $tmpDir
|
||||||
archiveName="$dmgmount/$pkgName"
|
archiveName="$dmgmount/$pkgName"
|
||||||
|
else
|
||||||
|
# try searching for pkg
|
||||||
|
findfiles=$(find "$dmgmount" -iname "$pkgName") # was: $tmpDir
|
||||||
|
printlog "Found pkg(s):\n$findfiles" DEBUG
|
||||||
|
filearray=( ${(f)findfiles} )
|
||||||
|
if [[ ${#filearray} -eq 0 ]]; then
|
||||||
|
cleanupAndExit 20 "couldn't find pkg “$pkgName” in dmg $archiveName" ERROR
|
||||||
|
fi
|
||||||
|
# it is now safe to overwrite archiveName for installFromPKG
|
||||||
|
archiveName="${filearray[1]}"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
printlog "found pkg: $archiveName"
|
||||||
|
|
||||||
# installFromPkgs
|
# installFromPkgs
|
||||||
installFromPKG
|
installFromPKG
|
||||||
@@ -536,17 +718,29 @@ installPkgInZip() {
|
|||||||
# locate pkg in zip
|
# locate pkg in zip
|
||||||
if [[ -z $pkgName ]]; then
|
if [[ -z $pkgName ]]; then
|
||||||
# find first file ending with 'pkg'
|
# find first file ending with 'pkg'
|
||||||
findfiles=$(find "$tmpDir" -iname "*.pkg" -maxdepth 2 )
|
findfiles=$(find "$tmpDir" -iname "*.pkg" -type f -maxdepth 2 )
|
||||||
|
printlog "Found pkg(s):\n$findfiles" DEBUG
|
||||||
filearray=( ${(f)findfiles} )
|
filearray=( ${(f)findfiles} )
|
||||||
if [[ ${#filearray} -eq 0 ]]; then
|
if [[ ${#filearray} -eq 0 ]]; then
|
||||||
cleanupAndExit 20 "couldn't find pkg in zip $archiveName"
|
cleanupAndExit 20 "couldn't find pkg in zip $archiveName" ERROR
|
||||||
fi
|
fi
|
||||||
archiveName="${filearray[1]}"
|
|
||||||
# it is now safe to overwrite archiveName for installFromPKG
|
# it is now safe to overwrite archiveName for installFromPKG
|
||||||
|
archiveName="${filearray[1]}"
|
||||||
printlog "found pkg: $archiveName"
|
printlog "found pkg: $archiveName"
|
||||||
else
|
else
|
||||||
# it is now safe to overwrite archiveName for installFromPKG
|
if [[ -s "$tmpDir/$pkgName" ]]; then
|
||||||
archiveName="$tmpDir/$pkgName"
|
archiveName="$tmpDir/$pkgName"
|
||||||
|
else
|
||||||
|
# try searching for pkg
|
||||||
|
findfiles=$(find "$tmpDir" -iname "$pkgName")
|
||||||
|
filearray=( ${(f)findfiles} )
|
||||||
|
if [[ ${#filearray} -eq 0 ]]; then
|
||||||
|
cleanupAndExit 20 "couldn't find pkg “$pkgName” in zip $archiveName" ERROR
|
||||||
|
fi
|
||||||
|
# it is now safe to overwrite archiveName for installFromPKG
|
||||||
|
archiveName="${filearray[1]}"
|
||||||
|
printlog "found pkg: $archiveName"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# installFromPkgs
|
# installFromPkgs
|
||||||
@@ -564,7 +758,7 @@ installAppInDmgInZip() {
|
|||||||
findfiles=$(find "$tmpDir" -iname "*.dmg" -maxdepth 2 )
|
findfiles=$(find "$tmpDir" -iname "*.dmg" -maxdepth 2 )
|
||||||
filearray=( ${(f)findfiles} )
|
filearray=( ${(f)findfiles} )
|
||||||
if [[ ${#filearray} -eq 0 ]]; then
|
if [[ ${#filearray} -eq 0 ]]; then
|
||||||
cleanupAndExit 20 "couldn't find dmg in zip $archiveName"
|
cleanupAndExit 20 "couldn't find dmg in zip $archiveName" ERROR
|
||||||
fi
|
fi
|
||||||
archiveName="$(basename ${filearray[1]})"
|
archiveName="$(basename ${filearray[1]})"
|
||||||
# it is now safe to overwrite archiveName for installFromDMG
|
# it is now safe to overwrite archiveName for installFromDMG
|
||||||
@@ -583,22 +777,39 @@ runUpdateTool() {
|
|||||||
if [[ -x $updateTool ]]; then
|
if [[ -x $updateTool ]]; then
|
||||||
printlog "running $updateTool $updateToolArguments"
|
printlog "running $updateTool $updateToolArguments"
|
||||||
if [[ -n $updateToolRunAsCurrentUser ]]; then
|
if [[ -n $updateToolRunAsCurrentUser ]]; then
|
||||||
runAsUser $updateTool ${updateToolArguments}
|
updateOutput=$(runAsUser $updateTool ${updateToolArguments} 2>&1)
|
||||||
|
updateStatus=$(echo $?)
|
||||||
else
|
else
|
||||||
$updateTool ${updateToolArguments}
|
updateOutput=$($updateTool ${updateToolArguments} 2>&1)
|
||||||
|
updateStatus=$(echo $?)
|
||||||
fi
|
fi
|
||||||
if [[ $? -ne 0 ]]; then
|
sleep 1
|
||||||
cleanupAndExit 15 "Error running $updateTool"
|
updateEndTime=$(date "+$updateToolLogDateFormat")
|
||||||
|
deduplicatelogs $updateOutput
|
||||||
|
if [[ -n $updateToolLog ]]; then
|
||||||
|
updateOutput+=$(echo "Output of Installer log of $updateToolLog below this line.\n")
|
||||||
|
updateOutput+=$(echo "----------------------------------------------------------\n")
|
||||||
|
updateOutput+=$(awk -v "b=$updatestarttime" -v "e=$updateEndTime" -F ',' '$1 >= b && $1 <= e' $updateToolLog)
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $updateStatus -ne 0 ]]; then
|
||||||
|
printlog "Error running $updateTool, Procceding with normal installation. Exit Status: $updateStatus Error:\n$logoutput" WARN
|
||||||
|
return 1
|
||||||
|
if [[ $type == updateronly ]]; then
|
||||||
|
cleanupAndExit 77 "No Download URL Set, this is an update only application and the updater failed" ERROR
|
||||||
|
fi
|
||||||
|
elif [[ $updateStatus -eq 0 ]]; then
|
||||||
|
printlog "Debugging enabled, update tool output was:\n$logoutput" DEBUG
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
printlog "couldn't find $updateTool, continuing normally"
|
printlog "couldn't find $updateTool, continuing normally" WARN
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
finishing() {
|
finishing() {
|
||||||
printlog "Finishing…"
|
printlog "Finishing..."
|
||||||
sleep 10 # wait a moment to let spotlight catch up
|
sleep 10 # wait a moment to let spotlight catch up
|
||||||
getAppVersion
|
getAppVersion
|
||||||
|
|
||||||
@@ -608,12 +819,42 @@ finishing() {
|
|||||||
message="Installed $name, version $appversion"
|
message="Installed $name, version $appversion"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
printlog "$message"
|
printlog "$message" REQ
|
||||||
|
|
||||||
if [[ $currentUser != "loginwindow" && ( $NOTIFY == "success" || $NOTIFY == "all" ) ]]; then
|
if [[ $currentUser != "loginwindow" && ( $NOTIFY == "success" || $NOTIFY == "all" ) ]]; then
|
||||||
printlog "notifying"
|
printlog "notifying"
|
||||||
displaynotification "$message" "$name update/installation complete!"
|
if [[ $updateDetected == "YES" ]]; then
|
||||||
|
displaynotification "$message" "$name update complete!"
|
||||||
|
else
|
||||||
|
displaynotification "$message" "$name installation complete!"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Detect if there is an app actively making a display sleep assertion, e.g.
|
||||||
|
# KeyNote, PowerPoint, Zoom, or Webex.
|
||||||
|
# See: https://developer.apple.com/documentation/iokit/iopmlib_h/iopmassertiontypes
|
||||||
|
hasDisplaySleepAssertion() {
|
||||||
|
# Get the names of all apps with active display sleep assertions
|
||||||
|
local apps="$(/usr/bin/pmset -g assertions | /usr/bin/awk '/NoDisplaySleepAssertion | PreventUserIdleDisplaySleep/ && match($0,/\(.+\)/) && ! /coreaudiod/ {gsub(/^.*\(/,"",$0); gsub(/\).*$/,"",$0); print};')"
|
||||||
|
|
||||||
|
if [[ ! "${apps}" ]]; then
|
||||||
|
# No display sleep assertions detected
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create an array of apps that need to be ignored
|
||||||
|
local ignore_array=("${(@s/,/)IGNORE_DND_APPS}")
|
||||||
|
|
||||||
|
for app in ${(f)apps}; do
|
||||||
|
if (( ! ${ignore_array[(Ie)${app}]} )); then
|
||||||
|
# Relevant app with display sleep assertion detected
|
||||||
|
printlog "Display sleep assertion detected by ${app}."
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# No relevant display sleep assertion detected
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,9 +20,11 @@ export PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
|||||||
|
|
||||||
# NOTE: adjust these variables:
|
# NOTE: adjust these variables:
|
||||||
|
|
||||||
# set to 0 for production, 1 for debugging
|
# set to 0 for production, 1 or 2 for debugging
|
||||||
# while debugging, items will be downloaded to the parent directory of this script
|
# while debugging, items will be downloaded to the parent directory of this script
|
||||||
# also no actual installation will be performed
|
# also no actual installation will be performed
|
||||||
|
# debug mode 1 will download to the directory the script is run in, but will not check the version
|
||||||
|
# debug mode 2 will download to the temp directory, check for blocking processes, check the version, but will not install anything or remove the current version
|
||||||
DEBUG=1
|
DEBUG=1
|
||||||
|
|
||||||
# notify behavior
|
# notify behavior
|
||||||
@@ -37,29 +39,36 @@ NOTIFY=success
|
|||||||
BLOCKING_PROCESS_ACTION=tell_user
|
BLOCKING_PROCESS_ACTION=tell_user
|
||||||
# options:
|
# options:
|
||||||
# - ignore continue even when blocking processes are found
|
# - ignore continue even when blocking processes are found
|
||||||
# - quit app will be told to quit nicely, if running
|
# - quit app will be told to quit nicely if running
|
||||||
# - quit_kill told to quit twice, then it will be killed
|
# - quit_kill told to quit twice, then it will be killed
|
||||||
# Could be great for service apps, if they do not respawn
|
# Could be great for service apps if they do not respawn
|
||||||
# - silent_fail exit script without prompt or installation
|
# - silent_fail exit script without prompt or installation
|
||||||
# - prompt_user show a user dialog for each blocking process found
|
# - prompt_user show a user dialog for each blocking process found,
|
||||||
# abort after three attempts to quit
|
# user can choose "Quit and Update" or "Not Now".
|
||||||
# (only if user accepts to quit the apps, otherwise
|
# When "Quit and Update" is chosen, blocking process
|
||||||
# the update is cancelled).
|
# will be told to quit. Installomator will wait 30 seconds
|
||||||
|
# before checking again in case Save dialogs etc are being responded to.
|
||||||
|
# Installomator will abort if quitting after three tries does not succeed.
|
||||||
|
# "Not Now" will exit Installomator.
|
||||||
# - prompt_user_then_kill
|
# - prompt_user_then_kill
|
||||||
# show a user dialog for each blocking process found,
|
# show a user dialog for each blocking process found,
|
||||||
# attempt to quit two times, kill the process finally
|
# user can choose "Quit and Update" or "Not Now".
|
||||||
|
# When "Quit and Update" is chosen, blocking process
|
||||||
|
# will be terminated. Installomator will abort if terminating
|
||||||
|
# after two tries does not succeed. "Not Now" will exit Installomator.
|
||||||
# - prompt_user_loop
|
# - prompt_user_loop
|
||||||
# Like prompt-user, but clicking "Not Now", will just wait an hour,
|
# Like prompt-user, but clicking "Not Now", will just wait an hour,
|
||||||
# and then it will ask again.
|
# and then it will ask again.
|
||||||
# WARNING! It might block the MDM agent on the machine, as
|
# WARNING! It might block the MDM agent on the machine, as
|
||||||
# the scripts gets stuct in waiting until the hour has passed,
|
# the script will not exit, it will pause until the hour has passed,
|
||||||
# possibly blocking for other management actions in this time.
|
# possibly blocking for other management actions in this time.
|
||||||
# - tell_user User will be showed a notification about the important update,
|
# - tell_user User will be showed a notification about the important update,
|
||||||
# but user is only allowed to quit and continue, and then we
|
# but user is only allowed to Quit and Continue, and then we
|
||||||
# ask the app to quit.
|
# ask the app to quit. This is default.
|
||||||
# - tell_user_then_kill
|
# - tell_user_then_kill
|
||||||
# Show dialog 2 times, and if the quitting fails, the
|
# User will be showed a notification about the important update,
|
||||||
# blocking processes will be killed.
|
# but user is only allowed to Quit and Continue. If the quitting fails,
|
||||||
|
# the blocking processes will be terminated.
|
||||||
# - kill kill process without prompting or giving the user a chance to save
|
# - kill kill process without prompting or giving the user a chance to save
|
||||||
|
|
||||||
|
|
||||||
@@ -71,6 +80,7 @@ LOGO=appstore
|
|||||||
# - mosyleb Mosyle Business
|
# - mosyleb Mosyle Business
|
||||||
# - mosylem Mosyle Manager (Education)
|
# - mosylem Mosyle Manager (Education)
|
||||||
# - addigy Addigy
|
# - addigy Addigy
|
||||||
|
# - microsoft Microsoft Endpoint Manager (Intune)
|
||||||
# path can also be set in the command call, and if file exists, it will be used.
|
# path can also be set in the command call, and if file exists, it will be used.
|
||||||
# Like 'LOGO="/System/Applications/App\ Store.app/Contents/Resources/AppIcon.icns"'
|
# Like 'LOGO="/System/Applications/App\ Store.app/Contents/Resources/AppIcon.icns"'
|
||||||
# (spaces have to be escaped).
|
# (spaces have to be escaped).
|
||||||
@@ -79,18 +89,25 @@ LOGO=appstore
|
|||||||
# App Store apps handling
|
# App Store apps handling
|
||||||
IGNORE_APP_STORE_APPS=no
|
IGNORE_APP_STORE_APPS=no
|
||||||
# options:
|
# options:
|
||||||
# - no If installed app is from App Store (which include VPP installed apps)
|
# - no If the installed app is from App Store (which include VPP installed apps)
|
||||||
# it will not be touched, no matter it's version (default)
|
# it will not be touched, no matter its version (default)
|
||||||
# - yes Replace App Store (and VPP) version of app and handle future
|
# - yes Replace App Store (and VPP) version of the app and handle future
|
||||||
# updates using Installomator, even if latest version.
|
# updates using Installomator, even if latest version.
|
||||||
# Shouldn’t give any problems for the user in most cases.
|
# Shouldn’t give any problems for the user in most cases.
|
||||||
# Known bad example: Slack will loose all settings.
|
# Known bad example: Slack will lose all settings.
|
||||||
|
|
||||||
|
# Owner of copied apps
|
||||||
|
SYSTEMOWNER=0
|
||||||
|
# options:
|
||||||
|
# - 0 Current user will be owner of copied apps, just like if they
|
||||||
|
# installed it themselves (default).
|
||||||
|
# - 1 root:wheel will be set on the copied app.
|
||||||
|
# Useful for shared machines.
|
||||||
|
|
||||||
# install behavior
|
# install behavior
|
||||||
INSTALL=""
|
INSTALL=""
|
||||||
# options:
|
# options:
|
||||||
# - When not set, software will only be installed
|
# - When not set, the software will only be installed
|
||||||
# if it is newer/different in version
|
# if it is newer/different in version
|
||||||
# - force Install even if it’s the same version
|
# - force Install even if it’s the same version
|
||||||
|
|
||||||
@@ -98,9 +115,29 @@ INSTALL=""
|
|||||||
# Re-opening of closed app
|
# Re-opening of closed app
|
||||||
REOPEN="yes"
|
REOPEN="yes"
|
||||||
# options:
|
# options:
|
||||||
# - yes App wil be reopened if it was closed
|
# - yes App will be reopened if it was closed
|
||||||
# - no App not reopened
|
# - no App not reopened
|
||||||
|
|
||||||
|
# Only let Installomator return the name of the label
|
||||||
|
# RETURN_LABEL_NAME=0
|
||||||
|
# options:
|
||||||
|
# - 1 Installomator will return the name of the label and exit, so last line of
|
||||||
|
# output will be that name. When Installomator is locally installed and we
|
||||||
|
# use DEPNotify, then DEPNotify can present a more nice name to the user,
|
||||||
|
# instead of just the label name.
|
||||||
|
|
||||||
|
|
||||||
|
# Interrupt Do Not Disturb (DND) full screen apps
|
||||||
|
INTERRUPT_DND="yes"
|
||||||
|
# options:
|
||||||
|
# - yes Script will run without checking for DND full screen apps.
|
||||||
|
# - no Script will exit when an active DND full screen app is detected.
|
||||||
|
|
||||||
|
# Comma separated list of app names to ignore when evaluating DND
|
||||||
|
IGNORE_DND_APPS=""
|
||||||
|
# example that will ignore browsers when evaluating DND:
|
||||||
|
# IGNORE_DND_APPS="firefox,Google Chrome,Safari,Microsoft Edge,Opera,Amphetamine,caffeinate"
|
||||||
|
|
||||||
|
|
||||||
# NOTE: How labels work
|
# NOTE: How labels work
|
||||||
|
|
||||||
@@ -124,7 +161,7 @@ REOPEN="yes"
|
|||||||
#
|
#
|
||||||
# - packageID: (optional)
|
# - packageID: (optional)
|
||||||
# The package ID of a pkg
|
# The package ID of a pkg
|
||||||
# If given, will be used to find version of installed software, instead of searching for an app.
|
# If given, will be used to find the version of installed software, instead of searching for an app.
|
||||||
# Usefull if a pkg does not install an app.
|
# Usefull if a pkg does not install an app.
|
||||||
# See label installomator_st
|
# See label installomator_st
|
||||||
#
|
#
|
||||||
@@ -132,9 +169,15 @@ REOPEN="yes"
|
|||||||
# URL to download the dmg.
|
# URL to download the dmg.
|
||||||
# Can be generated with a series of commands (see BBEdit for an example).
|
# Can be generated with a series of commands (see BBEdit for an example).
|
||||||
#
|
#
|
||||||
|
# - curlOptions: (array, optional)
|
||||||
|
# Options to the curl command, needed for curl to be able to download the software.
|
||||||
|
# Usually used for adding extra headers that some servers need in order to serve the file.
|
||||||
|
# curlOptions=( -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Safari/605.1.15" )
|
||||||
|
# (See “mocha”-labels, for examples on labels, and buildLabel.sh for header-examples.)
|
||||||
|
#
|
||||||
# - appNewVersion: (optional)
|
# - appNewVersion: (optional)
|
||||||
# Version of the downloaded software.
|
# Version of the downloaded software.
|
||||||
# If given, it will be compared to installed version, to see if download is different.
|
# If given, it will be compared to the installed version, to see if the download is different.
|
||||||
# It does not check for newer or not, only different.
|
# It does not check for newer or not, only different.
|
||||||
#
|
#
|
||||||
# - versionKey: (optional)
|
# - versionKey: (optional)
|
||||||
@@ -164,6 +207,8 @@ REOPEN="yes"
|
|||||||
# - archiveName: (optional)
|
# - archiveName: (optional)
|
||||||
# The name of the downloaded file.
|
# The name of the downloaded file.
|
||||||
# When not given the archiveName is derived from the $name.
|
# When not given the archiveName is derived from the $name.
|
||||||
|
# Note: This has to be defined BEFORE calling downloadURLFromGit or
|
||||||
|
# versionFromGit functions in the label.
|
||||||
#
|
#
|
||||||
# - appName: (optional)
|
# - appName: (optional)
|
||||||
# File name of the app bundle in the dmg to verify and copy (include .app).
|
# File name of the app bundle in the dmg to verify and copy (include .app).
|
||||||
@@ -186,7 +231,7 @@ REOPEN="yes"
|
|||||||
# blockingProcesses=( NONE )
|
# blockingProcesses=( NONE )
|
||||||
#
|
#
|
||||||
# - pkgName: (optional, only used for pkgInDmg, dmgInZip, and appInDmgInZip)
|
# - pkgName: (optional, only used for pkgInDmg, dmgInZip, and appInDmgInZip)
|
||||||
# File name of the pkg/dmg file _inside_ the dmg or zip
|
# File name or path to the pkg/dmg file _inside_ the dmg or zip.
|
||||||
# When not given the pkgName is derived from the $name
|
# When not given the pkgName is derived from the $name
|
||||||
#
|
#
|
||||||
# - updateTool:
|
# - updateTool:
|
||||||
@@ -196,8 +241,64 @@ REOPEN="yes"
|
|||||||
# $updateTool $updateArguments
|
# $updateTool $updateArguments
|
||||||
# Will be run instead of of downloading and installing a complete new version.
|
# Will be run instead of of downloading and installing a complete new version.
|
||||||
# Use this when the updateTool does differential and optimized downloads.
|
# Use this when the updateTool does differential and optimized downloads.
|
||||||
# e.g. msupdate
|
# e.g. msupdate on various Microsoft labels
|
||||||
#
|
#
|
||||||
# - updateToolRunAsCurrentUser:
|
# - updateToolRunAsCurrentUser:
|
||||||
# When this variable is set (any value), $updateTool will be run as the current user.
|
# When this variable is set (any value), $updateTool will be run as the current user.
|
||||||
#
|
#
|
||||||
|
# - CLIInstaller:
|
||||||
|
# - CLIArguments:
|
||||||
|
# If the downloaded dmg is an installer that we can call using CLI, we can
|
||||||
|
# use these two variables for what to call.
|
||||||
|
# We need to define `name` for the installed app (to be version checked), as well as
|
||||||
|
# `installerTool` for the installer app (if named differently than `name`. Installomator
|
||||||
|
# will add the path to the folder/disk image with the binary, and it will be called like this:
|
||||||
|
`$CLIInstaller $CLIArguments`
|
||||||
|
# For most installations `CLIInstaller` should contain the `installerTool` for the CLI call
|
||||||
|
# (if it’s the same).
|
||||||
|
# We can support a whole range of other software titles by implementing this.
|
||||||
|
# See label adobecreativeclouddesktop
|
||||||
|
#
|
||||||
|
# - installerTool:
|
||||||
|
# Introduced as part of `CLIInstaller`. If the installer in the DMG or ZIP is named
|
||||||
|
# differently than the installed app, then this variable can be used to name the
|
||||||
|
# installer that should be located after mounting/expanding the downloaded archive.
|
||||||
|
# See label adobecreativeclouddesktop
|
||||||
|
#
|
||||||
|
### Logging
|
||||||
|
# Logging behavior
|
||||||
|
LOGGING="INFO"
|
||||||
|
# options:
|
||||||
|
# - DEBUG Everything is logged
|
||||||
|
# - INFO (default) normal logging level
|
||||||
|
# - WARN only warning
|
||||||
|
# - ERROR only errors
|
||||||
|
# - REQ ????
|
||||||
|
|
||||||
|
# MDM profile name
|
||||||
|
MDMProfileName=""
|
||||||
|
# options:
|
||||||
|
# - MDM Profile Addigy has this name on the profile
|
||||||
|
# - Mosyle Corporation MDM Mosyle uses this name on the profile
|
||||||
|
# From the LOGO variable we can know if Addigy og Mosyle is used, so if that variable
|
||||||
|
# is either of these, and this variable is empty, then we will auto detect this.
|
||||||
|
|
||||||
|
# Datadog logging used
|
||||||
|
datadogAPI=""
|
||||||
|
# Simply add your own API key for this in order to have logs sent to Datadog
|
||||||
|
# See more here: https://www.datadoghq.com/product/log-management/
|
||||||
|
|
||||||
|
# Log Date format used when parsing logs for debugging, this is the default used by
|
||||||
|
# install.log, override this in the case statements if you need something custom per
|
||||||
|
# application (See adobeillustrator). Using stadard GNU Date formatting.
|
||||||
|
LogDateFormat="%Y-%m-%d %H:%M:%S"
|
||||||
|
|
||||||
|
# Get the start time for parsing install.log if we fail.
|
||||||
|
starttime=$(date "+$LogDateFormat")
|
||||||
|
|
||||||
|
# Check if we have rosetta installed
|
||||||
|
if [[ $(/usr/bin/arch) == "arm64" ]]; then
|
||||||
|
if ! arch -x86_64 /usr/bin/true >/dev/null 2>&1; then # pgrep oahd >/dev/null 2>&1
|
||||||
|
rosetta2=no
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|||||||
9
fragments/labels/1passwordcli.sh
Normal file
9
fragments/labels/1passwordcli.sh
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
1passwordcli)
|
||||||
|
name="1Password CLI"
|
||||||
|
type="pkg"
|
||||||
|
#packageID="com.1password.op"
|
||||||
|
downloadURL=$(curl -fs https://app-updates.agilebits.com/product_history/CLI | grep -m 1 -i op_apple_universal | cut -d'"' -f 2)
|
||||||
|
appNewVersion=$(echo $downloadURL | sed -E 's/.*\/[a-zA-Z_]*([0-9.]*)\..*/\1/g')
|
||||||
|
appCustomVersion(){ /usr/local/bin/op -v }
|
||||||
|
expectedTeamID="2BUA8C4S2C"
|
||||||
|
;;
|
||||||
17
fragments/labels/adobecreativeclouddesktop.sh
Normal file
17
fragments/labels/adobecreativeclouddesktop.sh
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
adobecreativeclouddesktop)
|
||||||
|
name="Adobe Creative Cloud"
|
||||||
|
#appName="Install.app"
|
||||||
|
type="dmg"
|
||||||
|
if [[ $(arch) == "arm64" ]]; then
|
||||||
|
downloadURL=$(curl -fs "https://helpx.adobe.com/download-install/kb/creative-cloud-desktop-app-download.html" | grep -o "https*.*macarm64.*dmg" | cut -d '"' -f1 | head -1)
|
||||||
|
elif [[ $(arch) == "i386" ]]; then
|
||||||
|
downloadURL=$(curl -fs "https://helpx.adobe.com/download-install/kb/creative-cloud-desktop-app-download.html" | grep -o "https*.*osx10.*dmg" | cut -d '"' -f1 | head -1)
|
||||||
|
fi
|
||||||
|
#downloadURL=$(curl -fs "https://helpx.adobe.com/download-install/kb/creative-cloud-desktop-app-download.html" | grep -o "https*.*dmg" | head -1)
|
||||||
|
appNewVersion=$(curl -fs "https://helpx.adobe.com/creative-cloud/release-note/cc-release-notes.html" | grep "mandatory" | head -1 | grep -o "Version *.* released" | cut -d " " -f2)
|
||||||
|
installerTool="Install.app"
|
||||||
|
CLIInstaller="Install.app/Contents/MacOS/Install"
|
||||||
|
CLIArguments=(--mode=silent)
|
||||||
|
expectedTeamID="JQ525L2MZD"
|
||||||
|
Company="Adobe"
|
||||||
|
;;
|
||||||
@@ -3,6 +3,6 @@ airserver)
|
|||||||
name="AirServer"
|
name="AirServer"
|
||||||
type="dmg"
|
type="dmg"
|
||||||
downloadURL="https://www.airserver.com/download/mac/latest"
|
downloadURL="https://www.airserver.com/download/mac/latest"
|
||||||
#appNewVersion=$() # Cannot find version history or release notes on home page
|
appNewVersion=$(curl -fsIL "${downloadURL}" | grep -i "location" | sed -E 's/.*\/[a-zA-Z]*-([0-9.]*)\..*/\1/g')
|
||||||
expectedTeamID="6C755KS5W3"
|
expectedTeamID="6C755KS5W3"
|
||||||
;;
|
;;
|
||||||
|
|||||||
7
fragments/labels/alephone.sh
Normal file
7
fragments/labels/alephone.sh
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
alephone)
|
||||||
|
name="Aleph One"
|
||||||
|
type="dmg"
|
||||||
|
downloadURL=$(downloadURLFromGit Aleph-One-Marathon alephone)
|
||||||
|
appNewVersion=$(versionFromGit Aleph-One-Marathon alephone)
|
||||||
|
expectedTeamID="E8K89CXZE7"
|
||||||
|
;;
|
||||||
7
fragments/labels/amazoncorretto8jdk.sh
Normal file
7
fragments/labels/amazoncorretto8jdk.sh
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
amazoncorretto8jdk)
|
||||||
|
name="Amazon Corretto 8 JDK"
|
||||||
|
type="pkg"
|
||||||
|
downloadURL="https://corretto.aws/downloads/latest/amazon-corretto-8-x64-macos-jdk.pkg"
|
||||||
|
appNewVersion=$(curl -s https://raw.githubusercontent.com/corretto/corretto-8/develop/CHANGELOG.md | grep "## Corretto version" | head -n 1 | awk '{ print $4; exit}')
|
||||||
|
expectedTeamID="94KV3E626L"
|
||||||
|
;;
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
androidfiletransfer)
|
androidfiletransfer)
|
||||||
#credit: Sam Ess (saess-sep)
|
|
||||||
name="Android File Transfer"
|
name="Android File Transfer"
|
||||||
type="dmg"
|
type="dmg"
|
||||||
downloadURL="https://dl.google.com/dl/androidjumper/mtp/current/AndroidFileTransfer.dmg"
|
downloadURL="https://dl.google.com/dl/androidjumper/mtp/current/AndroidFileTransfer.dmg"
|
||||||
|
|||||||
@@ -2,5 +2,6 @@ apparency)
|
|||||||
name="Apparency"
|
name="Apparency"
|
||||||
type="dmg"
|
type="dmg"
|
||||||
downloadURL="https://www.mothersruin.com/software/downloads/Apparency.dmg"
|
downloadURL="https://www.mothersruin.com/software/downloads/Apparency.dmg"
|
||||||
|
appNewVersion=$(curl -fs https://mothersruin.com/software/Apparency/data/ApparencyVersionInfo.plist | grep -A1 CFBundleShortVersionString | tail -1 | sed -E 's/.*>([0-9.]*)<.*/\1/g')
|
||||||
expectedTeamID="936EB786NH"
|
expectedTeamID="936EB786NH"
|
||||||
;;
|
;;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
appcleaner)
|
appcleaner)
|
||||||
# credit: Tadayuki Onishi (@kenchan0130)
|
|
||||||
name="AppCleaner"
|
name="AppCleaner"
|
||||||
type="zip"
|
type="zip"
|
||||||
downloadURL=$(curl -fs https://freemacsoft.net/appcleaner/Updates.xml | xpath '//rss/channel/*/enclosure/@url' 2>/dev/null | tr " " "\n" | sort | tail -1 | cut -d '"' -f 2)
|
downloadURL=$(curl -fs https://freemacsoft.net/appcleaner/Updates.xml | xpath '//rss/channel/item[last()]/enclosure/@url' 2>/dev/null | tr " " "\n" | sort | tail -1 | cut -d '"' -f 2)
|
||||||
|
appNewVersion=$(curl -fsL "https://freemacsoft.net/appcleaner/Updates.xml" | xpath '//rss/channel/item[last()]/enclosure/@sparkle:shortVersionString' 2>/dev/null | cut -d '"' -f 2)
|
||||||
expectedTeamID="X85ZX835W9"
|
expectedTeamID="X85ZX835W9"
|
||||||
;;
|
;;
|
||||||
|
|||||||
@@ -3,5 +3,5 @@ applenyfonts)
|
|||||||
type="pkgInDmg"
|
type="pkgInDmg"
|
||||||
downloadURL="https://devimages-cdn.apple.com/design/resources/download/NY.dmg"
|
downloadURL="https://devimages-cdn.apple.com/design/resources/download/NY.dmg"
|
||||||
packageID="com.apple.pkg.NYFonts"
|
packageID="com.apple.pkg.NYFonts"
|
||||||
expectedTeamID="Development Update"
|
expectedTeamID="Software Update"
|
||||||
;;
|
;;
|
||||||
|
|||||||
7
fragments/labels/applesfarabic.sh
Normal file
7
fragments/labels/applesfarabic.sh
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
applesfarabic)
|
||||||
|
name="San Francisco Arabic"
|
||||||
|
type="pkgInDmg"
|
||||||
|
downloadURL="https://devimages-cdn.apple.com/design/resources/download/SF-Arabic.dmg"
|
||||||
|
packageID="com.apple.pkg.SFArabicFonts"
|
||||||
|
expectedTeamID="Software Update"
|
||||||
|
;;
|
||||||
@@ -3,5 +3,5 @@ applesfcompact)
|
|||||||
type="pkgInDmg"
|
type="pkgInDmg"
|
||||||
downloadURL="https://devimages-cdn.apple.com/design/resources/download/SF-Compact.dmg"
|
downloadURL="https://devimages-cdn.apple.com/design/resources/download/SF-Compact.dmg"
|
||||||
packageID="com.apple.pkg.SanFranciscoCompact"
|
packageID="com.apple.pkg.SanFranciscoCompact"
|
||||||
expectedTeamID="Development Update"
|
expectedTeamID="Software Update"
|
||||||
;;
|
;;
|
||||||
|
|||||||
@@ -3,5 +3,5 @@ applesfpro)
|
|||||||
type="pkgInDmg"
|
type="pkgInDmg"
|
||||||
downloadURL="https://devimages-cdn.apple.com/design/resources/download/SF-Pro.dmg"
|
downloadURL="https://devimages-cdn.apple.com/design/resources/download/SF-Pro.dmg"
|
||||||
packageID="com.apple.pkg.SanFranciscoPro"
|
packageID="com.apple.pkg.SanFranciscoPro"
|
||||||
expectedTeamID="Development Update"
|
expectedTeamID="Software Update"
|
||||||
;;
|
;;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ applesfsymbols|\
|
|||||||
sfsymbols)
|
sfsymbols)
|
||||||
name="SF Symbols"
|
name="SF Symbols"
|
||||||
type="pkgInDmg"
|
type="pkgInDmg"
|
||||||
downloadURL="https://developer.apple.com/design/downloads/SF-Symbols.dmg"
|
downloadURL=$( curl -fs "https://developer.apple.com/sf-symbols/" | grep -oe "https.*Symbols.*\.dmg" | head -1 )
|
||||||
|
appNewVersion=$( echo "$downloadURL" | sed -E 's/.*SF-Symbols-([0-9.]*)\..*/\1/g')
|
||||||
expectedTeamID="Software Update"
|
expectedTeamID="Software Update"
|
||||||
;;
|
;;
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
audacity)
|
audacity)
|
||||||
# credit: Gabe Marchan (gabemarchan.com - @darklink87)
|
|
||||||
name="Audacity"
|
name="Audacity"
|
||||||
type="dmg"
|
type="dmg"
|
||||||
downloadURL=$(downloadURLFromGit audacity audacity)
|
downloadURL=$(downloadURLFromGit audacity audacity)
|
||||||
appNewVersion=$(versionFromGit audacity audacity)
|
appNewVersion=$(versionFromGit audacity audacity)
|
||||||
expectedTeamID="T3N4JQ7YY6"
|
expectedTeamID="AWEYX923UX"
|
||||||
;;
|
;;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
authydesktop)
|
authydesktop)
|
||||||
name="Authy Desktop"
|
name="Authy Desktop"
|
||||||
type="dmg"
|
type="dmg"
|
||||||
downloadURL="https://electron.authy.com/download?channel=stable&arch=x64&platform=darwin&version=latest&product=authy"
|
downloadURL=$(curl -s -w '%{redirect_url}' -o /dev/null "https://electron.authy.com/download?channel=stable&arch=x64&platform=darwin&version=latest&product=authy" | sed 's/\ /%20/g')
|
||||||
appNewVersion="$(curl -sfL --output /dev/null -r 0-0 "${downloadURL}" --remote-header-name --remote-name -w "%{url_effective}\n" | grep -o -E '([a-zA-Z0-9\_.%-]*)\.(dmg|pkg|zip|tbz)$' | sed -E 's/.*-([0-9.]*)\.dmg/\1/g')"
|
appNewVersion="$(curl -sfL --output /dev/null -r 0-0 "${downloadURL}" --remote-header-name --remote-name -w "%{url_effective}\n" | grep -o -E '([a-zA-Z0-9\_.%-]*)\.(dmg|pkg|zip|tbz)$' | sed -E 's/.*-([0-9.]*)\.dmg/\1/g')"
|
||||||
expectedTeamID="9EVH78F4V4"
|
expectedTeamID="9EVH78F4V4"
|
||||||
;;
|
;;
|
||||||
|
|||||||
10
fragments/labels/autodeskfusion360admininstall.sh
Normal file
10
fragments/labels/autodeskfusion360admininstall.sh
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
autodeskfusion360admininstall)
|
||||||
|
name="Autodesk Fusion 360 Admin Install"
|
||||||
|
type="pkg"
|
||||||
|
packageID="com.autodesk.edu.fusion360"
|
||||||
|
downloadURL="https://dl.appstreaming.autodesk.com/production/installers/Autodesk%20Fusion%20360%20Admin%20Install.pkg"
|
||||||
|
appNewVersion=$(curl -fs "https://dl.appstreaming.autodesk.com/production/97e6dd95735340d6ad6e222a520454db/73e72ada57b7480280f7a6f4a289729f/full.json" | sed -E 's/.*build-version":"([[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+).*/\1/g')
|
||||||
|
expectedTeamID="XXKJ396S2Y"
|
||||||
|
appName="Autodesk Fusion 360.app"
|
||||||
|
blockingProcesses=( "Autodesk Fusion 360" "Fusion 360" )
|
||||||
|
;;
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
autopkgr)
|
autopkgr)
|
||||||
# credit: Søren Theilgaard (@theilgaard)
|
|
||||||
name="AutoPkgr"
|
name="AutoPkgr"
|
||||||
type="dmg"
|
type="dmg"
|
||||||
#downloadURL=$(curl -fs "https://api.github.com/repos/lindegroup/autopkgr/releases/latest" | awk -F '"' "/browser_download_url/ && /dmg/ && ! /sig/ && ! /CLI/ && ! /sha256/ { print \$4 }")
|
|
||||||
downloadURL=$(downloadURLFromGit lindegroup autopkgr)
|
downloadURL=$(downloadURLFromGit lindegroup autopkgr)
|
||||||
appNewVersion=$(versionFromGit lindegroup autopkgr)
|
appNewVersion=$(versionFromGit lindegroup autopkgr)
|
||||||
expectedTeamID="JVY2ZR6SEF"
|
expectedTeamID="JVY2ZR6SEF"
|
||||||
|
|||||||
14
fragments/labels/axurerp10.sh
Normal file
14
fragments/labels/axurerp10.sh
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
axurerp10)
|
||||||
|
name="Axure RP 10"
|
||||||
|
type="dmg"
|
||||||
|
if [[ $(arch) == "arm64" ]]; then
|
||||||
|
downloadURL="https://d3uii9pxdigrx1.cloudfront.net/AxureRP-Setup-arm64.dmg"
|
||||||
|
elif [[ $(arch) == "i386" ]]; then
|
||||||
|
downloadURL="https://d3uii9pxdigrx1.cloudfront.net/AxureRP-Setup.dmg"
|
||||||
|
fi
|
||||||
|
appNewVersion=$( curl -sL https://www.axure.com/release-history | grep -Eo '[0-9]{1,4}\.[0-9]{1,4}\.[0-9]{1,4}\.[0-9]{1,4}' -m 1 )
|
||||||
|
expectedTeamID="HUMW6UU796"
|
||||||
|
versionKey="CFBundleVersion"
|
||||||
|
appName="Axure RP 10.app"
|
||||||
|
blockingProcesses=( "Axure RP 10" )
|
||||||
|
;;
|
||||||
@@ -2,7 +2,7 @@ bluejeans)
|
|||||||
name="BlueJeans"
|
name="BlueJeans"
|
||||||
type="pkg"
|
type="pkg"
|
||||||
if [[ $(arch) == "arm64" ]]; then
|
if [[ $(arch) == "arm64" ]]; then
|
||||||
downloadURL=$(curl -fs "https://www.bluejeans.com/downloads" | xmllint --html --format - 2>/dev/null | grep -o "https://.*BlueJeansInstaller.*arm.*.pkg" )
|
downloadURL=$(curl -fs "https://www.bluejeans.com/downloads" | xmllint --html --format - 2>/dev/null | grep -o "https://.*BlueJeans.*Installer.*arm.*.pkg" )
|
||||||
elif [[ $(arch) == "i386" ]]; then
|
elif [[ $(arch) == "i386" ]]; then
|
||||||
downloadURL=$(curl -fs "https://www.bluejeans.com/downloads" | xmllint --html --format - 2>/dev/null | grep -o "https://.*BlueJeansInstaller.*x86.*.dmg" | sed 's/dmg/pkg/g')
|
downloadURL=$(curl -fs "https://www.bluejeans.com/downloads" | xmllint --html --format - 2>/dev/null | grep -o "https://.*BlueJeansInstaller.*x86.*.dmg" | sed 's/dmg/pkg/g')
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -1,12 +1,6 @@
|
|||||||
boxdrive)
|
boxdrive)
|
||||||
# credit: Isaac Ordonez, Mann consulting (@mannconsulting)
|
|
||||||
name="Box"
|
name="Box"
|
||||||
type="pkg"
|
type="pkg"
|
||||||
if [[ $(arch) == "arm64" ]]; then
|
downloadURL="https://e3.boxcdn.net/box-installers/desktop/releases/mac/Box.pkg"
|
||||||
#Note: https://support.box.com/hc/en-us/articles/1500004479962-Box-Drive-support-on-devices-with-M1-chips
|
|
||||||
downloadURL="https://e3.boxcdn.net/desktop/pre-releases/mac/BoxDrive.2.20.140-M1-beta.pkg"
|
|
||||||
elif [[ $(arch) == "i386" ]]; then
|
|
||||||
downloadURL="https://e3.boxcdn.net/box-installers/desktop/releases/mac/Box.pkg"
|
|
||||||
fi
|
|
||||||
expectedTeamID="M683GB7CPW"
|
expectedTeamID="M683GB7CPW"
|
||||||
;;
|
;;
|
||||||
|
|||||||
@@ -1,15 +1,18 @@
|
|||||||
brave)
|
brave)
|
||||||
# credit: @securitygeneration
|
|
||||||
name="Brave Browser"
|
name="Brave Browser"
|
||||||
type="dmg"
|
type="dmg"
|
||||||
if [[ $(arch) != "i386" ]]; then
|
if [[ $(arch) != "i386" ]]; then
|
||||||
printlog "Architecture: arm64 (not i386)"
|
printlog "Architecture: arm64 (not i386)"
|
||||||
downloadURL=$(curl -fsIL https://laptop-updates.brave.com/latest/osxarm64/release | grep -i "^location" | awk '{print $2}' | tr -d '\r\n')
|
downloadURL=$(curl -fsIL https://laptop-updates.brave.com/latest/osxarm64/release | grep -i "^location" | sed -E 's/.*(https.*\.dmg).*/\1/g')
|
||||||
|
appNewVersion="$(curl -fsL "https://updates.bravesoftware.com/sparkle/Brave-Browser/stable-arm64/appcast.xml" | xpath '//rss/channel/item[last()]/enclosure/@sparkle:version' 2>/dev/null | cut -d '"' -f 2)"
|
||||||
|
#appNewVersion="96.$(curl -fsL "https://updates.bravesoftware.com/sparkle/Brave-Browser/stable-arm64/appcast.xml" | xpath '//rss/channel/item[last()]/enclosure/@sparkle:shortVersionString' 2>/dev/null | cut -d '"' -f 2 | cut -d "." -f1-3)"
|
||||||
else
|
else
|
||||||
printlog "Architecture: i386"
|
printlog "Architecture: i386"
|
||||||
downloadURL=$(curl -fsIL https://laptop-updates.brave.com/latest/osx/release | grep -i "^location" | awk '{print $2}' | tr -d '\r\n')
|
downloadURL=$(curl -fsIL https://laptop-updates.brave.com/latest/osx/release | grep -i "^location" | sed -E 's/.*(https.*\.dmg).*/\1/g')
|
||||||
|
appNewVersion="$(curl -fsL "https://updates.bravesoftware.com/sparkle/Brave-Browser/stable/appcast.xml" | xpath '//rss/channel/item[last()]/enclosure/@sparkle:version' 2>/dev/null | cut -d '"' -f 2)"
|
||||||
|
#appNewVersion="96.$(curl -fsL "https://updates.bravesoftware.com/sparkle/Brave-Browser/stable/appcast.xml" | xpath '//rss/channel/item[last()]/enclosure/@sparkle:shortVersionString' 2>/dev/null | cut -d '"' -f 2 | cut -d "." -f1-3)"
|
||||||
fi
|
fi
|
||||||
# downloadURL=$(curl --location --fail --silent "https://updates.bravesoftware.com/sparkle/Brave-Browser/stable/appcast.xml" | xpath '//rss/channel/item[last()]/enclosure/@url' 2>/dev/null | cut -d '"' -f 2)
|
versionKey="CFBundleVersion"
|
||||||
appNewVersion=$(curl --location --fail --silent "https://updates.bravesoftware.com/sparkle/Brave-Browser/stable/appcast.xml" | xpath '//rss/channel/item[last()]/enclosure/@sparkle:shortVersionString' 2>/dev/null | cut -d '"' -f 2)
|
# downloadURL=$(curl -fsL "https://updates.bravesoftware.com/sparkle/Brave-Browser/stable/appcast.xml" | xpath '//rss/channel/item[last()]/enclosure/@url' 2>/dev/null | cut -d '"' -f 2)
|
||||||
expectedTeamID="KL8N8XSYF4"
|
expectedTeamID="KL8N8XSYF4"
|
||||||
;;
|
;;
|
||||||
|
|||||||
7
fragments/labels/bugdom.sh
Normal file
7
fragments/labels/bugdom.sh
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
bugdom)
|
||||||
|
name="Bugdom"
|
||||||
|
type="dmg"
|
||||||
|
downloadURL=$(downloadURLFromGit jorio Bugdom)
|
||||||
|
appNewVersion=$(versionFromGit jorio Bugdom)
|
||||||
|
expectedTeamID="RVNL7XC27G"
|
||||||
|
;;
|
||||||
7
fragments/labels/calcservice.sh
Normal file
7
fragments/labels/calcservice.sh
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
calcservice)
|
||||||
|
name="CalcService"
|
||||||
|
type="zip"
|
||||||
|
downloadURL="$(curl -fs -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Safari/605.1.15" "https://www.devontechnologies.com/support/download" | tr '"' "\n" | grep -o "http.*download.*.zip" | grep -i calcservice | head -1)"
|
||||||
|
appNewVersion="$(echo $downloadURL | sed -E 's/.*\/([0-9.]*)\/.*/\1/g')"
|
||||||
|
expectedTeamID="679S2QUWR8"
|
||||||
|
;;
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
camostudio)
|
camostudio)
|
||||||
# credit: Søren Theilgaard (@theilgaard)
|
|
||||||
name="Camo Studio"
|
name="Camo Studio"
|
||||||
type="zip"
|
type="zip"
|
||||||
downloadURL="https://reincubate.com/res/labs/camo/camo-macos-latest.zip"
|
downloadURL="https://reincubate.com/res/labs/camo/camo-macos-latest.zip"
|
||||||
appNewVersion=$(curl -s -L https://reincubate.com/support/camo/release-notes/ | grep -m2 "has-m-t-0" | head -1 | cut -d ">" -f2 | cut -d " " -f1)
|
#appNewVersion=$(curl -s -L https://reincubate.com/support/camo/release-notes/ | grep -m2 "has-m-t-0" | head -1 | cut -d ">" -f2 | cut -d " " -f1)
|
||||||
|
appNewVersion=$( curl -fs "https://uds.reincubate.com/release-notes/camo/" | head -1 | cut -d "," -f3 | grep -o -e "[0-9.]*" )
|
||||||
|
# Camo Studio will ask for admin permissions to install som plug-ins. that has not been handled.
|
||||||
expectedTeamID="Q248YREB53"
|
expectedTeamID="Q248YREB53"
|
||||||
;;
|
;;
|
||||||
|
|||||||
12
fragments/labels/canva.sh
Normal file
12
fragments/labels/canva.sh
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
canva)
|
||||||
|
name="Canva"
|
||||||
|
type="dmg"
|
||||||
|
if [[ $(arch) == "arm64" ]]; then
|
||||||
|
downloadURL=https://desktop-release.canva.com/Canva-latest-arm64.dmg
|
||||||
|
appNewVersion=$( curl -fsLI -H "accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9" -H "accept-encoding: gzip, deflate, br" -H "accept-language: en-US,en;q=0.9" -H "Referrer Policy: strict-origin-when-cross-origin" -H "upgrade-insecure-requests: 1" -H "sec-fetch-dest: document" -H "sec-gpc: 1" -H "sec-fetch-user: ?1" -H "sec-fetch-mode: navigate" -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Safari/605.1.15" "https://www.canva.com/download/mac/arm/canva-desktop/" | grep -i "^location" | cut -d " " -f2 | tr -d '\r' | sed -E 's/.*\/[a-zA-Z]*-([0-9.]*)-*.*\.dmg/\1/g' )
|
||||||
|
elif [[ $(arch) == "i386" ]]; then
|
||||||
|
downloadURL=https://desktop-release.canva.com/Canva-latest.dmg
|
||||||
|
appNewVersion=$( curl -fsLI -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Safari/605.1.15" -H "accept-encoding: gzip, deflate, br" -H "Referrer Policy: strict-origin-when-cross-origin" -H "upgrade-insecure-requests: 1" -H "sec-fetch-dest: document" -H "sec-gpc: 1" -H "sec-fetch-user: ?1" -H "accept-language: en-US,en;q=0.9" -H "accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9" -H "sec-fetch-mode: navigate" "https://www.canva.com/download/mac/intel/canva-desktop/" | grep -i "^location" | cut -d " " -f2 | tr -d '\r' | sed -E 's/.*\/[a-zA-Z]*-([0-9.]*)-*.*\.dmg/\1/g' )
|
||||||
|
fi
|
||||||
|
expectedTeamID="5HD2ARTBFS"
|
||||||
|
;;
|
||||||
6
fragments/labels/chatwork.sh
Normal file
6
fragments/labels/chatwork.sh
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
chatwork)
|
||||||
|
name="Chatwork"
|
||||||
|
type="dmg"
|
||||||
|
downloadURL="https://desktop-app.chatwork.com/installer/Chatwork.dmg"
|
||||||
|
expectedTeamID="H34A3H2Y54"
|
||||||
|
;;
|
||||||
7
fragments/labels/clipy.sh
Normal file
7
fragments/labels/clipy.sh
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
clipy)
|
||||||
|
name="Clipy"
|
||||||
|
type="dmg"
|
||||||
|
downloadURL=$(downloadURLFromGit Clipy Clipy)
|
||||||
|
appNewVersion=$(versionFromGit Clipy Clipy)
|
||||||
|
expectedTeamID="BBCHAJ584H"
|
||||||
|
;;
|
||||||
7
fragments/labels/closeio.sh
Normal file
7
fragments/labels/closeio.sh
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
closeio)
|
||||||
|
name="Close.io"
|
||||||
|
type="dmg"
|
||||||
|
downloadURL=$(downloadURLFromGit closeio closeio-desktop-releases)
|
||||||
|
appNewVersion=$(versionFromGit closeio closeio-desktop-releases)
|
||||||
|
expectedTeamID="WTNQ6773UC"
|
||||||
|
;;
|
||||||
@@ -1,8 +1,11 @@
|
|||||||
code42)
|
code42)
|
||||||
# credit: Isaac Ordonez, Mann consulting (@mannconsulting)
|
|
||||||
name="Code42"
|
name="Code42"
|
||||||
type="pkgInDmg"
|
type="pkgInDmg"
|
||||||
downloadURL=https://download.code42.com/installs/agent/latest-mac.dmg
|
if [[ $(arch) == i386 ]]; then
|
||||||
|
downloadURL="https://download.code42.com/installs/agent/latest-mac.dmg"
|
||||||
|
elif [[ $(arch) == arm64 ]]; then
|
||||||
|
downloadURL="https://download.code42.com/installs/agent/latest-mac-arm64.dmg"
|
||||||
|
fi
|
||||||
expectedTeamID="9YV9435DHD"
|
expectedTeamID="9YV9435DHD"
|
||||||
blockingProcesses=( NONE )
|
blockingProcesses=( NONE )
|
||||||
;;
|
;;
|
||||||
|
|||||||
7
fragments/labels/daisydisk.sh
Normal file
7
fragments/labels/daisydisk.sh
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
daisydisk)
|
||||||
|
name="DaisyDisk"
|
||||||
|
type="zip"
|
||||||
|
downloadURL="https://daisydiskapp.com/downloads/DaisyDisk.zip"
|
||||||
|
appNewVersion=$( curl -fs 'https://daisydiskapp.com/downloads/appcastReleaseNotes.php?appEdition=Standard' | grep Version | head -1 | sed -E 's/.*Version ([0-9.]*).*/\1/g' )
|
||||||
|
expectedTeamID="4CBU3JHV97"
|
||||||
|
;;
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
dangerzone)
|
dangerzone)
|
||||||
# credit: Micah Lee (@micahflee)
|
|
||||||
name="Dangerzone"
|
name="Dangerzone"
|
||||||
type="dmg"
|
type="dmg"
|
||||||
downloadURL=$(curl -s https://dangerzone.rocks/ | grep https://github.com/firstlookmedia/dangerzone/releases/download | grep \.dmg | cut -d'"' -f2)
|
downloadURL="$(downloadURLFromGit firstlookmedia dangerzone)"
|
||||||
expectedTeamID="P24U45L8P5"
|
appNewVersion="$(versionFromGit firstlookmedia dangerzone)"
|
||||||
|
expectedTeamID="N9B95FDWH4"
|
||||||
;;
|
;;
|
||||||
|
|||||||
@@ -1,7 +1,13 @@
|
|||||||
dbeaverce)
|
dbeaverce)
|
||||||
name="DBeaver"
|
name="DBeaver"
|
||||||
type="dmg"
|
type="dmg"
|
||||||
downloadURL="https://dbeaver.io/files/dbeaver-ce-latest-macos.dmg"
|
if [[ $(arch) == "arm64" ]]; then
|
||||||
|
downloadURL="https://dbeaver.io/files/dbeaver-ce-latest-macos-aarch64.dmg"
|
||||||
|
appNewVersion="$(curl -fsIL "${downloadURL}" | grep -i ^location | sed 's/^.*[^0-9]\([0-9]*\.[0-9]*\.[0-9]*\).*$/\1/' | head -1)"
|
||||||
|
elif [[ $(arch) == "i386" ]]; then
|
||||||
|
downloadURL="https://dbeaver.io/files/dbeaver-ce-latest-macos.dmg"
|
||||||
|
appNewVersion="$(curl -fsIL "${downloadURL}" | grep -i ^location | sed 's/^.*[^0-9]\([0-9]*\.[0-9]*\.[0-9]*\).*$/\1/' | head -1)"
|
||||||
|
fi
|
||||||
expectedTeamID="42B6MDKMW8"
|
expectedTeamID="42B6MDKMW8"
|
||||||
blockingProcesses=( dbeaver )
|
blockingProcesses=( dbeaver )
|
||||||
;;
|
;;
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
depnotify)
|
depnotify)
|
||||||
name="DEPNotify"
|
name="DEPNotify"
|
||||||
type="zip"
|
type="pkg"
|
||||||
downloadURL="https://files.nomad.menu/DEPNotify.zip"
|
#packageID="menu.nomad.depnotify"
|
||||||
|
downloadURL="https://files.nomad.menu/DEPNotify.pkg"
|
||||||
|
#appNewVersion=$()
|
||||||
expectedTeamID="VRPY9KHGX6"
|
expectedTeamID="VRPY9KHGX6"
|
||||||
targetDir="/Applications/Utilities"
|
|
||||||
;;
|
;;
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
dialog)
|
dialog|\
|
||||||
|
swiftdialog)
|
||||||
name="Dialog"
|
name="Dialog"
|
||||||
type="pkg"
|
type="pkg"
|
||||||
downloadURL=$(downloadURLFromGit bartreardon Dialog-public )
|
packageID="au.csiro.dialogcli"
|
||||||
appNewVersion=$(versionFromGit bartreardon Dialog-public )
|
downloadURL="$(downloadURLFromGit bartreardon swiftDialog)"
|
||||||
|
appNewVersion="$(versionFromGit bartreardon swiftDialog)"
|
||||||
expectedTeamID="PWA5E9TQ59"
|
expectedTeamID="PWA5E9TQ59"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
8
fragments/labels/diskspace.sh
Normal file
8
fragments/labels/diskspace.sh
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
diskspace)
|
||||||
|
name="diskspace"
|
||||||
|
type="pkg"
|
||||||
|
packageID="com.scriptingosx.diskspace"
|
||||||
|
downloadURL="$(downloadURLFromGit scriptingosx diskspace)"
|
||||||
|
appNewVersion="$(versionFromGit scriptingosx diskspace)"
|
||||||
|
expectedTeamID="JME5BW3F3R"
|
||||||
|
;;
|
||||||
@@ -1,13 +1,12 @@
|
|||||||
docker)
|
docker)
|
||||||
# credit: @securitygeneration
|
|
||||||
name="Docker"
|
name="Docker"
|
||||||
type="dmg"
|
type="dmg"
|
||||||
#downloadURL="https://download.docker.com/mac/stable/Docker.dmg"
|
|
||||||
if [[ $(arch) == arm64 ]]; then
|
if [[ $(arch) == arm64 ]]; then
|
||||||
downloadURL="https://desktop.docker.com/mac/stable/arm64/Docker.dmg"
|
downloadURL="https://desktop.docker.com/mac/stable/arm64/Docker.dmg"
|
||||||
|
appNewVersion=$( curl -fs "https://desktop.docker.com/mac/main/arm64/appcast.xml" | xpath '(//rss/channel/item/enclosure/@sparkle:shortVersionString)[last()]' 2>/dev/null | cut -d '"' -f2 )
|
||||||
elif [[ $(arch) == i386 ]]; then
|
elif [[ $(arch) == i386 ]]; then
|
||||||
downloadURL="https://desktop.docker.com/mac/stable/amd64/Docker.dmg"
|
downloadURL="https://desktop.docker.com/mac/stable/amd64/Docker.dmg"
|
||||||
|
appNewVersion=$( curl -fs "https://desktop.docker.com/mac/main/amd64/appcast.xml" | xpath '(//rss/channel/item/enclosure/@sparkle:shortVersionString)[last()]' 2>/dev/null | cut -d '"' -f2 )
|
||||||
fi
|
fi
|
||||||
appNewVersion=$(curl -ifs https://docs.docker.com/docker-for-mac/release-notes/ | grep ">Docker Desktop Community" | head -1 | sed -n -e 's/^.*Community //p' | cut -d '<' -f1)
|
|
||||||
expectedTeamID="9BNSXJN65R"
|
expectedTeamID="9BNSXJN65R"
|
||||||
;;
|
;;
|
||||||
|
|||||||
9
fragments/labels/dockutil.sh
Normal file
9
fragments/labels/dockutil.sh
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
dockutil)
|
||||||
|
name="dockutil"
|
||||||
|
type="pkg"
|
||||||
|
packageID="dockutil.cli.tool"
|
||||||
|
downloadURL=$(downloadURLFromGit "kcrawford" "dockutil")
|
||||||
|
appNewVersion=$(versionFromGit "kcrawford" "dockutil")
|
||||||
|
expectedTeamID="Z5J8CJBUWC"
|
||||||
|
blockingProcesses=( NONE )
|
||||||
|
;;
|
||||||
7
fragments/labels/easyfind.sh
Normal file
7
fragments/labels/easyfind.sh
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
easyfind)
|
||||||
|
name="EasyFind"
|
||||||
|
type="zip"
|
||||||
|
downloadURL="$(curl -fs "https://www.devontechnologies.com/apps/freeware" | grep -o "http.*download.*.zip" | grep -i easyfind)"
|
||||||
|
appNewVersion="$(echo $downloadURL | sed -E 's/.*\/([0-9.]*)\/.*/\1/g')"
|
||||||
|
expectedTeamID="679S2QUWR8"
|
||||||
|
;;
|
||||||
9
fragments/labels/eshareosx.sh
Normal file
9
fragments/labels/eshareosx.sh
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
eshareosx)
|
||||||
|
name="e-Share"
|
||||||
|
type="pkg"
|
||||||
|
#packageID="com.ncryptedcloud.e-Share.pkg"
|
||||||
|
downloadURL=https://www.ncryptedcloud.com/static/downloads/osx/$(curl -fs https://www.ncryptedcloud.com/static/downloads/osx/ | grep -o -i "href.*\".*\"" | cut -d '"' -f2)
|
||||||
|
versionKey="CFBundleVersion"
|
||||||
|
appNewVersion=$( echo "${downloadURL}" | sed -E 's/.*\/[a-zA-Z\-]*_([0-9.]*)\.pkg/\1/g' )
|
||||||
|
expectedTeamID="X9MBQS7DDC"
|
||||||
|
;;
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
evernote)
|
evernote)
|
||||||
name="Evernote"
|
name="Evernote"
|
||||||
type="dmg"
|
type="dmg"
|
||||||
downloadURL=$(curl -fs -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15)" "https://evernote.com/download" | grep -i ".dmg" | cut -d '"' -f2)
|
downloadURL=$(curl -fs -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15)" "https://evernote.com/download" | grep -i ".dmg" | grep -ioe "href.*" | cut -d '"' -f2)
|
||||||
appNewVersion=$( echo "${downloadURL}" | sed -E 's/.*\/[a-zA-Z]*-([0-9.]*)-.*/\1/g' )
|
appNewVersion=$( echo "${downloadURL}" | sed -E 's/.*\/[a-zA-Z]*-([0-9.]*)-.*/\1/g' )
|
||||||
expectedTeamID="Q79WDW8YH9"
|
expectedTeamID="Q79WDW8YH9"
|
||||||
appName="Evernote.app"
|
appName="Evernote.app"
|
||||||
|
|||||||
7
fragments/labels/exifrenamer.sh
Normal file
7
fragments/labels/exifrenamer.sh
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
exifrenamer)
|
||||||
|
name="ExifRenamer"
|
||||||
|
type="dmg"
|
||||||
|
downloadURL="https://www.qdev.de/"$(curl -fs "https://www.qdev.de/download.php?file=ExifRenamer.dmg" | grep -o -e "URL=[a-zA-Z/]*.dmg" | cut -d "=" -f2)
|
||||||
|
appNewVersion=$(curl -fs "https://www.qdev.de/?location=downloads" | grep -A1 -m1 "ExifRenamer" | tail -1 | cut -d ">" -f2 | cut -d " " -f1)
|
||||||
|
expectedTeamID="MLF9FE35AM"
|
||||||
|
;;
|
||||||
7
fragments/labels/fastscripts.sh
Normal file
7
fragments/labels/fastscripts.sh
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
fastscripts)
|
||||||
|
name="FastScripts"
|
||||||
|
type="zip"
|
||||||
|
downloadURL=$( curl -fs "https://redsweater.com/fastscripts/appcast3.php" | xpath '(//rss/channel/item/enclosure/@url)[1]' 2>/dev/null | cut -d '"' -f2 )
|
||||||
|
appNewVersion=$( curl -fs "https://redsweater.com/fastscripts/appcast3.php" | xpath '(//rss/channel/item/enclosure/@sparkle:shortVersionString)[1]' 2>/dev/null | cut -d '"' -f2 )
|
||||||
|
expectedTeamID="493CVA9A35"
|
||||||
|
;;
|
||||||
@@ -1,13 +1,12 @@
|
|||||||
ferdi)
|
ferdi)
|
||||||
name="Ferdi"
|
name="Ferdi"
|
||||||
type="zip"
|
type="zip"
|
||||||
if [[ $(arch) == i386 ]]; then
|
if [[ $(arch) == "arm64" ]]; then
|
||||||
downloadURL=$(curl --silent --fail "https://api.github.com/repos/getferdi/ferdi/releases/latest" \
|
archiveName="arm64-mac.zip"
|
||||||
| awk -F '"' "/browser_download_url/ && /mac.zip/ && ! /blockmap/ && ! /arm64-mac/ && ! /AppImage/{ print \$4 }")
|
elif [[ $(arch) == "i386" ]]; then
|
||||||
elif [[ $(arch) == arm64 ]]; then
|
archiveName="Ferdi-[0-9.]*-mac.zip"
|
||||||
downloadURL=$(downloadURLFromGit getferdi ferdi )
|
fi
|
||||||
archiveName="arm64-mac.zip"
|
downloadURL="$(downloadURLFromGit getferdi ferdi)"
|
||||||
fi
|
|
||||||
appNewVersion=$(versionFromGit getferdi ferdi )
|
appNewVersion=$(versionFromGit getferdi ferdi )
|
||||||
expectedTeamID="B6J9X9DWFL"
|
expectedTeamID="B6J9X9DWFL"
|
||||||
;;
|
;;
|
||||||
|
|||||||
7
fragments/labels/findanyfile.sh
Normal file
7
fragments/labels/findanyfile.sh
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
findanyfile)
|
||||||
|
name="Find Any File"
|
||||||
|
type="zip"
|
||||||
|
downloadURL=$(curl -fs "https://findanyfile.app/appcast2.php" | xpath '(//rss/channel/item/enclosure/@url)[1]' 2>/dev/null | cut -d '"' -f2)
|
||||||
|
appNewVersion=$(curl -fs "https://findanyfile.app/appcast2.php" | xpath '(//rss/channel/item/enclosure/@sparkle:shortVersionString)[1]' 2>/dev/null | cut -d '"' -f2)
|
||||||
|
expectedTeamID="25856V4B4X"
|
||||||
|
;;
|
||||||
@@ -2,7 +2,7 @@ firefox)
|
|||||||
name="Firefox"
|
name="Firefox"
|
||||||
type="dmg"
|
type="dmg"
|
||||||
downloadURL="https://download.mozilla.org/?product=firefox-latest&os=osx&lang=en-US"
|
downloadURL="https://download.mozilla.org/?product=firefox-latest&os=osx&lang=en-US"
|
||||||
appNewVersion=$(/usr/bin/curl https://www.mozilla.org/en-US/firefox/releases/ --silent | /usr/bin/grep '<html' | /usr/bin/awk -F\" '{ print $8 }') # Credit: William Smith (@meck)
|
appNewVersion=$(curl -fs https://www.mozilla.org/en-US/firefox/releases/ | grep '<html' | grep -o -i -e "data-latest-firefox=\"[0-9.]*\"" | cut -d '"' -f2)
|
||||||
expectedTeamID="43AQ936H96"
|
expectedTeamID="43AQ936H96"
|
||||||
blockingProcesses=( firefox )
|
blockingProcesses=( firefox )
|
||||||
;;
|
;;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ firefox_da)
|
|||||||
name="Firefox"
|
name="Firefox"
|
||||||
type="dmg"
|
type="dmg"
|
||||||
downloadURL="https://download.mozilla.org/?product=firefox-latest&os=osx&lang=da"
|
downloadURL="https://download.mozilla.org/?product=firefox-latest&os=osx&lang=da"
|
||||||
appNewVersion=$(/usr/bin/curl https://www.mozilla.org/en-US/firefox/releases/ --silent | /usr/bin/grep '<html' | /usr/bin/awk -F\" '{ print $8 }') # Credit: William Smith (@meck)
|
appNewVersion=$(curl -fs https://www.mozilla.org/en-US/firefox/releases/ | grep '<html' | grep -o -i -e "data-latest-firefox=\"[0-9.]*\"" | cut -d '"' -f2)
|
||||||
expectedTeamID="43AQ936H96"
|
expectedTeamID="43AQ936H96"
|
||||||
blockingProcesses=( firefox )
|
blockingProcesses=( firefox )
|
||||||
;;
|
;;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ firefox_intl)
|
|||||||
printlog "Download not found for that language. Using en-US"
|
printlog "Download not found for that language. Using en-US"
|
||||||
downloadURL="https://download.mozilla.org/?product=firefox-latest&os=osx&lang=en-US"
|
downloadURL="https://download.mozilla.org/?product=firefox-latest&os=osx&lang=en-US"
|
||||||
fi
|
fi
|
||||||
appNewVersion=$(/usr/bin/curl -sl https://www.mozilla.org/en-US/firefox/releases/ | /usr/bin/grep '<html' | /usr/bin/awk -F\" '{ print $8 }') # Credit: William Smith (@meck)
|
appNewVersion=$(curl -fs https://www.mozilla.org/en-US/firefox/releases/ | grep '<html' | grep -o -i -e "data-latest-firefox=\"[0-9.]*\"" | cut -d '"' -f2)
|
||||||
expectedTeamID="43AQ936H96"
|
expectedTeamID="43AQ936H96"
|
||||||
blockingProcesses=( firefox )
|
blockingProcesses=( firefox )
|
||||||
;;
|
;;
|
||||||
|
|||||||
7
fragments/labels/flux.sh
Normal file
7
fragments/labels/flux.sh
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
flux)
|
||||||
|
name="Flux"
|
||||||
|
type="zip"
|
||||||
|
downloadURL="https://justgetflux.com/mac/Flux.zip"
|
||||||
|
expectedTeamID="VZKSA7H9J9"
|
||||||
|
;;
|
||||||
|
|
||||||
9
fragments/labels/forticlient_ztna.sh
Normal file
9
fragments/labels/forticlient_ztna.sh
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
forticlient_ztna)
|
||||||
|
name="FortiClient ZTNA"
|
||||||
|
type="pkgInDmg"
|
||||||
|
pkgName="Install.mpkg"
|
||||||
|
packageID="com.fortinet.forticlient."
|
||||||
|
downloadURL="https://links.fortinet.com/forticlient/mac/fabricagent"
|
||||||
|
appNewVersion="$(curl -fsL "$downloadURL" --remote-header-name --remote-name -w "%{url_effective}\n" -r 0-0 | cut -d "_" -f2)"
|
||||||
|
expectedTeamID="AH4XFXJ7DK"
|
||||||
|
;;
|
||||||
@@ -1,7 +1,13 @@
|
|||||||
front)
|
front)
|
||||||
name="Front"
|
name="Front"
|
||||||
type="dmg"
|
type="dmg"
|
||||||
downloadURL="https://dl.frontapp.com/macos/Front.dmg"
|
if [[ $(arch) == "arm64" ]]; then
|
||||||
|
downloadURL="https://dl.frontapp.com/macos/Front-arm64.dmg"
|
||||||
|
appNewVersion=$(curl -fs "https://dl.frontapp.com/desktop/updates/latest/mac-arm64/latest-mac.yml" | grep -i version | cut -d " " -f2)
|
||||||
|
elif [[ $(arch) == "i386" ]]; then
|
||||||
|
downloadURL="https://dl.frontapp.com/macos/Front.dmg"
|
||||||
|
appNewVersion=$(curl -fs "https://dl.frontapp.com/desktop/updates/latest/mac/latest-mac.yml" | grep -i version | cut -d " " -f2)
|
||||||
|
fi
|
||||||
expectedTeamID="X549L7572J"
|
expectedTeamID="X549L7572J"
|
||||||
Company="FrontApp. Inc."
|
Company="FrontApp. Inc."
|
||||||
;;
|
;;
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
golang)
|
golang)
|
||||||
# credit: Søren Theilgaard (@theilgaard)
|
|
||||||
name="GoLang"
|
name="GoLang"
|
||||||
type="pkg"
|
type="pkg"
|
||||||
packageID="org.golang.go"
|
packageID="org.golang.go"
|
||||||
downloadURL="$(curl -fsIL "https://golang.org$(curl -fs "https://golang.org/dl/" | grep -i "downloadBox" | grep "pkg" | tr '"' '\n' | grep "pkg")" | grep -i "^location" | awk '{print $2}' | tr -d '\r\n')"
|
downloadURL="https://go.dev$(curl -fs "https://go.dev/dl/" | grep -i "downloadBox" | grep "pkg" | tr '"' '\n' | grep "pkg")"
|
||||||
appNewVersion="$( echo "${downloadURL}" | sed -E 's/.*\/(go[0-9.]*)\..*/\1/g' )" # Version includes letters "go"
|
appNewVersion="$( echo "${downloadURL}" | sed -E 's/.*\/(go[0-9.]*)\..*/\1/g' )" # Version includes letters "go" in the beginning
|
||||||
expectedTeamID="EQHXZ8M8AV"
|
expectedTeamID="EQHXZ8M8AV"
|
||||||
blockingProcesses=( NONE )
|
blockingProcesses=( NONE )
|
||||||
;;
|
;;
|
||||||
|
|||||||
@@ -1,14 +1,7 @@
|
|||||||
googlechrome)
|
googlechrome)
|
||||||
name="Google Chrome"
|
name="Google Chrome"
|
||||||
type="dmg"
|
type="dmg"
|
||||||
if [[ $(arch) != "i386" ]]; then
|
downloadURL="https://dl.google.com/chrome/mac/universal/stable/GGRO/googlechrome.dmg"
|
||||||
printlog "Architecture: arm64 (not i386)"
|
appNewVersion=$(curl -s https://omahaproxy.appspot.com/history | awk -F',' '/mac_arm64,stable/{print $3; exit}')
|
||||||
downloadURL="https://dl.google.com/chrome/mac/universal/stable/GGRO/googlechrome.dmg"
|
|
||||||
appNewVersion=$(curl -s https://omahaproxy.appspot.com/history | awk -F',' '/mac_arm64,stable/{print $3; exit}')
|
|
||||||
else
|
|
||||||
printlog "Architecture: i386"
|
|
||||||
downloadURL="https://dl.google.com/chrome/mac/stable/GGRO/googlechrome.dmg"
|
|
||||||
appNewVersion=$(curl -s https://omahaproxy.appspot.com/history | awk -F',' '/mac,stable/{print $3; exit}')
|
|
||||||
fi
|
|
||||||
expectedTeamID="EQHXZ8M8AV"
|
expectedTeamID="EQHXZ8M8AV"
|
||||||
;;
|
;;
|
||||||
|
|||||||
@@ -5,4 +5,5 @@ gpgsuite)
|
|||||||
pkgName="Install.pkg"
|
pkgName="Install.pkg"
|
||||||
downloadURL=$(curl -s https://gpgtools.org/ | grep https://releases.gpgtools.org/GPG_Suite- | grep Download | cut -d'"' -f4)
|
downloadURL=$(curl -s https://gpgtools.org/ | grep https://releases.gpgtools.org/GPG_Suite- | grep Download | cut -d'"' -f4)
|
||||||
expectedTeamID="PKV8ZPD836"
|
expectedTeamID="PKV8ZPD836"
|
||||||
|
blockingProcesses=( "GPG Keychain" )
|
||||||
;;
|
;;
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
gpgsync)
|
gpgsync)
|
||||||
# credit: Micah Lee (@micahflee)
|
|
||||||
name="GPG Sync"
|
name="GPG Sync"
|
||||||
type="pkg"
|
type="pkg"
|
||||||
downloadURL="https://github.com$(curl -s -L https://github.com/firstlookmedia/gpgsync/releases/latest | grep /firstlookmedia/gpgsync/releases/download | grep \.pkg | cut -d'"' -f2)"
|
packageID="org.firstlook.gpgsync"
|
||||||
|
downloadURL="$(downloadURLFromGit firstlookmedia gpgsync)"
|
||||||
|
appNewVersion="$(versionFromGit firstlookmedia gpgsync)"
|
||||||
expectedTeamID="P24U45L8P5"
|
expectedTeamID="P24U45L8P5"
|
||||||
;;
|
;;
|
||||||
|
|||||||
9
fragments/labels/grammarly.sh
Normal file
9
fragments/labels/grammarly.sh
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
grammarly)
|
||||||
|
name="Grammarly Desktop"
|
||||||
|
type="dmg"
|
||||||
|
packageID="com.grammarly.ProjectLlama"
|
||||||
|
downloadURL=$(curl -fsL "https://download-mac.grammarly.com/appcast.xml" | xpath '//rss/channel/item[1]/enclosure/@url' 2>/dev/null | cut -d '"' -f 2)
|
||||||
|
expectedTeamID="W8F64X92K3"
|
||||||
|
appNewVersion=$(curl -is "https://download-mac.grammarly.com/appcast.xml" | grep sparkle:version | tr ',' '\n' | grep sparkle:version | cut -d '"' -f 4)
|
||||||
|
appName="Grammarly Installer.app"
|
||||||
|
;;
|
||||||
7
fragments/labels/houdahspot.sh
Normal file
7
fragments/labels/houdahspot.sh
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
houdahspot)
|
||||||
|
name="HoudahSpot"
|
||||||
|
type="zip"
|
||||||
|
downloadURL="$(curl -fs https://www.houdah.com/houdahSpot/updates/cast6.php | xpath '(//rss/channel/item/enclosure/@url)[1]' 2>/dev/null | head -1 | cut -d '"' -f 2)"
|
||||||
|
appNewVersion="$(curl -fs https://www.houdah.com/houdahSpot/updates/cast6.php | xpath '(//rss/channel/item/enclosure/@sparkle:shortVersionString)[1]' 2>/dev/null | head -1 | cut -d '"' -f 2)"
|
||||||
|
expectedTeamID="DKGQD8H8ZY"
|
||||||
|
;;
|
||||||
7
fragments/labels/ibarcoder.sh
Normal file
7
fragments/labels/ibarcoder.sh
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
ibarcoder)
|
||||||
|
name="iBarcoder"
|
||||||
|
type="dmg"
|
||||||
|
downloadURL="https://cristallight.com/Downloads/mac/ibarcoder.dmg"
|
||||||
|
appNewVersion="$(curl -fs "https://cristallight.com/iBarcoder/" | grep -i version: | head -1 | awk '{print $2}')"
|
||||||
|
expectedTeamID="JAXVB9AH9M"
|
||||||
|
;;
|
||||||
7
fragments/labels/iina.sh
Normal file
7
fragments/labels/iina.sh
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
iina)
|
||||||
|
name="IINA"
|
||||||
|
type="dmg"
|
||||||
|
downloadURL=$(downloadURLFromGit iina iina )
|
||||||
|
appNewVersion=$(versionFromGit iina iina )
|
||||||
|
expectedTeamID="67CQ77V27R"
|
||||||
|
;;
|
||||||
@@ -2,7 +2,8 @@ inkscape)
|
|||||||
# credit: Søren Theilgaard (@theilgaard)
|
# credit: Søren Theilgaard (@theilgaard)
|
||||||
name="Inkscape"
|
name="Inkscape"
|
||||||
type="dmg"
|
type="dmg"
|
||||||
downloadURL="https://inkscape.org$(curl -fs https://inkscape.org$(curl -fsJL https://inkscape.org/release/ | grep "/release/" | grep en | head -n 1 | cut -d '"' -f 6)mac-os-x/1010-1015/dl/ | grep "click here" | cut -d '"' -f 2)"
|
downloadURL="https://inkscape.org$(curl -fs https://inkscape.org$(curl -fsJL https://inkscape.org/release/ | grep "/release/" | grep en | head -n 1 | cut -d '"' -f 6)mac-os-x/dmg/dl/ | grep "click here" | cut -d '"' -f 2)"
|
||||||
#appNewVersion=$(curl -fsJL https://inkscape.org/release/ | grep "<h2>Inkscape" | cut -d '>' -f 3 | cut -d '<' -f 1 | sed 's/[^0-9.]*//g') # Can't figure out where exact new version is found. Currently returns 1.0, but version is "1.0.0 (4035a4f)"
|
appCustomVersion() { /Applications/Inkscape.app/Contents/MacOS/inkscape --version | cut -d " " -f2 }
|
||||||
|
appNewVersion=$(curl -fsJL https://inkscape.org/release/ | grep "<title>" | grep -o -e "[0-9.]*")
|
||||||
expectedTeamID="SW3D6BB6A6"
|
expectedTeamID="SW3D6BB6A6"
|
||||||
;;
|
;;
|
||||||
|
|||||||
10
fragments/labels/installomator.sh
Normal file
10
fragments/labels/installomator.sh
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
installomator|\
|
||||||
|
installomator_theile)
|
||||||
|
name="Installomator"
|
||||||
|
type="pkg"
|
||||||
|
packageID="com.scriptingosx.Installomator"
|
||||||
|
downloadURL=$(downloadURLFromGit Installomator Installomator )
|
||||||
|
appNewVersion=$(versionFromGit Installomator Installomator )
|
||||||
|
expectedTeamID="JME5BW3F3R"
|
||||||
|
blockingProcesses=( NONE )
|
||||||
|
;;
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
installomator_theile)
|
|
||||||
# credit: Søren Theilgaard (@theilgaard)
|
|
||||||
name="Installomator"
|
|
||||||
type="pkg"
|
|
||||||
packageID="dk.theilgaard.pkg.Installomator"
|
|
||||||
downloadURL=$(downloadURLFromGit theile Installomator )
|
|
||||||
appNewVersion=$(versionFromGit theile Installomator )
|
|
||||||
#appCustomVersion(){/usr/local/bin/Installomator.sh version | tail -1 | awk '{print $4}'}
|
|
||||||
expectedTeamID="FXW6QXBFW5"
|
|
||||||
blockingProcesses=( NONE )
|
|
||||||
;;
|
|
||||||
7
fragments/labels/itsycal.sh
Normal file
7
fragments/labels/itsycal.sh
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
itsycal)
|
||||||
|
name="Itsycal"
|
||||||
|
type="zip"
|
||||||
|
downloadURL=$(curl -fs https://s3.amazonaws.com/itsycal/itsycal-apple-silicon.xml | xpath '(//rss/channel/item/enclosure/@url)[1]' 2>/dev/null | head -1 | cut -d '"' -f 2)
|
||||||
|
appNewVersion=$(curl -fs https://s3.amazonaws.com/itsycal/itsycal-apple-silicon.xml | xpath '(//rss/channel/item/enclosure/@sparkle:shortVersionString)[1]' 2>/dev/null | head -1 | cut -d '"' -f 2)
|
||||||
|
expectedTeamID="HFT3T55WND"
|
||||||
|
;;
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
jabradirect)
|
jabradirect)
|
||||||
name="Jabra Direct"
|
name="Jabra Direct"
|
||||||
type="pkgInDmg"
|
type="pkgInDmg"
|
||||||
|
packageID="com.jabra.directonline"
|
||||||
downloadURL="https://jabraxpressonlineprdstor.blob.core.windows.net/jdo/JabraDirectSetup.dmg"
|
downloadURL="https://jabraxpressonlineprdstor.blob.core.windows.net/jdo/JabraDirectSetup.dmg"
|
||||||
|
appNewVersion=$(curl -fs https://www.jabra.com/Support/release-notes/release-note-jabra-direct | grep -oe "Release version:.*[0-9.]*<" | head -1 | cut -d ">" -f2 | cut -d "<" -f1 | sed 's/ //g')
|
||||||
expectedTeamID="55LV32M29R"
|
expectedTeamID="55LV32M29R"
|
||||||
appNewVersion=$(curl -fs https://www.jabra.com/Support/release-notes/release-note-jabra-direct | grep -o "Jabra Direct macOS:*.*<" | head -1 | cut -d ":" -f2 | cut -d " " -f2 | cut -d "<" -f1)
|
|
||||||
;;
|
;;
|
||||||
|
|||||||
13
fragments/labels/jetbrainsrubymine.sh
Normal file
13
fragments/labels/jetbrainsrubymine.sh
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
jetbrainsrubymine)
|
||||||
|
name="RubyMine"
|
||||||
|
type="dmg"
|
||||||
|
jetbrainscode="RM"
|
||||||
|
if [[ $(arch) == i386 ]]; then
|
||||||
|
jetbrainsdistribution="mac"
|
||||||
|
elif [[ $(arch) == arm64 ]]; then
|
||||||
|
jetbrainsdistribution="macM1"
|
||||||
|
fi
|
||||||
|
downloadURL="https://download.jetbrains.com/product?code=${jetbrainscode}&latest&distribution=${jetbrainsdistribution}"
|
||||||
|
appNewVersion=$( curl -fsIL "${downloadURL}" | grep -i "location" | tail -1 | sed -E 's/.*\/[a-zA-Z-]*-([0-9.]*).*[-.].*dmg/\1/g' )
|
||||||
|
expectedTeamID="2ZEFAR8TH3"
|
||||||
|
;;
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
lexarrecoverytool)
|
lexarrecoverytool)
|
||||||
# credit: Søren Theilgaard (@theilgaard)
|
|
||||||
name="Lexar Recovery Tool"
|
name="Lexar Recovery Tool"
|
||||||
type="appInDmgInZip"
|
type="appInDmgInZip"
|
||||||
downloadURL="https://www.lexar.com$( curl -fs "https://www.lexar.com/support/downloads/" | grep -i "mac" | grep -i "recovery" | head -1 | tr '"' '\n' | grep -i ".zip" )"
|
downloadURL="https://www.lexar.com/wp-content/uploads/product_images/Lexar-Recovery-Tool-Mac.zip"
|
||||||
#appNewVersion=""
|
|
||||||
expectedTeamID="Y8HM6WR2DV"
|
expectedTeamID="Y8HM6WR2DV"
|
||||||
;;
|
;;
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
libreoffice)
|
libreoffice)
|
||||||
# credit: Micah Lee (@micahflee)
|
|
||||||
name="LibreOffice"
|
name="LibreOffice"
|
||||||
type="dmg"
|
type="dmg"
|
||||||
downloadURL="https://download.documentfoundation.org/libreoffice/stable/$(curl -s https://www.libreoffice.org/download/download/ | grep dl_version_number | head -n 1 | cut -d'>' -f3 | cut -d'<' -f1)/mac/x86_64/LibreOffice_$(curl -s https://www.libreoffice.org/download/download/ | grep dl_version_number | head -n 1 | cut -d'>' -f3 | cut -d'<' -f1)_MacOS_x86-64.dmg"
|
if [[ $(arch) == "arm64" ]]; then
|
||||||
|
downloadURL="https://download.documentfoundation.org/libreoffice/stable/$(curl -s https://www.libreoffice.org/download/download/ | grep dl_version_number | head -n 1 | cut -d'>' -f3 | cut -d'<' -f1)/mac/aarch64/LibreOffice_$(curl -s https://www.libreoffice.org/download/download/ | grep dl_version_number | head -n 1 | cut -d'>' -f3 | cut -d'<' -f1)_MacOS_aarch64.dmg"
|
||||||
|
elif [[ $(arch) == "i386" ]]; then
|
||||||
|
downloadURL="https://download.documentfoundation.org/libreoffice/stable/$(curl -s https://www.libreoffice.org/download/download/ | grep dl_version_number | head -n 1 | cut -d'>' -f3 | cut -d'<' -f1)/mac/x86_64/LibreOffice_$(curl -s https://www.libreoffice.org/download/download/ | grep dl_version_number | head -n 1 | cut -d'>' -f3 | cut -d'<' -f1)_MacOS_x86-64.dmg"
|
||||||
|
fi
|
||||||
appNewVersion=$( echo "${downloadURL}" | sed -E 's/.*\/[a-zA-Z]*_([0-9.]*)_.*/\1/g' )
|
appNewVersion=$( echo "${downloadURL}" | sed -E 's/.*\/[a-zA-Z]*_([0-9.]*)_.*/\1/g' )
|
||||||
expectedTeamID="7P5S3ZLCN7"
|
expectedTeamID="7P5S3ZLCN7"
|
||||||
|
blockingProcesses=( soffice )
|
||||||
;;
|
;;
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
logitechoptions)
|
logitechoptions)
|
||||||
# credit: AP Orlebeke (@apizz)
|
|
||||||
name="Logitech Options"
|
name="Logitech Options"
|
||||||
type="pkgInZip"
|
type="pkgInZip"
|
||||||
downloadURL=$(curl -fs -L https://www.logitech.com/en-us/product/options | grep -m 1 -o "https.*zip" | sed 's/\"//' | awk '{print $1}')
|
#downloadURL=$(curl -fs "https://support.logi.com/api/v2/help_center/en-us/articles.json?label_names=webcontent=productdownload,webos=mac-macos-x-11.0" | tr "," "\n" | grep -A 10 "macOS" | grep -oie "https.*/.*/options/.*\.zip" | head -1)
|
||||||
appNewVersion=$(curl -fs -L https://www.logitech.com/en-us/product/options | grep -m 1 -o "https.*zip" | sed 's/\"//' | awk '{print $1}' | sed -E 's/.*_([0-9\.]*)[-\.].*/\1/' )
|
downloadURL="https://download01.logi.com/web/ftp/pub/techsupport/options/options_installer.zip"
|
||||||
pkgName="LogiMgr Installer ${appNewVersion}.app/Contents/Resources/LogiMgr.pkg"
|
appNewVersion=$(curl -fs "https://support.logi.com/api/v2/help_center/en-us/articles.json?label_names=webcontent=productdownload,webos=mac-macos-x-11.0" | tr "," "\n" | grep -A 10 "macOS" | grep -B 5 -ie "https.*/.*/options/.*\.zip" | grep "Software Version" | sed 's/\\u[0-9a-z][0-9a-z][0-9a-z][0-9a-z]//g' | grep -ioe "Software Version.*[0-9.]*" | tr "/" "\n" | grep -oe "[0-9.]*" | head -1)
|
||||||
|
#pkgName="LogiMgr Installer "*".app/Contents/Resources/LogiMgr.pkg"
|
||||||
|
pkgName=LogiMgr.pkg
|
||||||
expectedTeamID="QED4VVPZWA"
|
expectedTeamID="QED4VVPZWA"
|
||||||
;;
|
;;
|
||||||
|
|||||||
13
fragments/labels/logseq.sh
Normal file
13
fragments/labels/logseq.sh
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
logseq)
|
||||||
|
name="Logseq"
|
||||||
|
type="dmg"
|
||||||
|
if [[ $(arch) == "arm64" ]]; then
|
||||||
|
archiveName="darwin-arm64-[0-9.]*.dmg"
|
||||||
|
downloadURL=$(downloadURLFromGit logseq logseq)
|
||||||
|
elif [[ $(arch) == "i386" ]]; then
|
||||||
|
archiveName="darwin-x64-[0-9.]*.dmg"
|
||||||
|
downloadURL=$(downloadURLFromGit logseq logseq)
|
||||||
|
fi
|
||||||
|
appNewVersion=$(versionFromGit logseq logseq)
|
||||||
|
expectedTeamID="3K44EUN829"
|
||||||
|
;;
|
||||||
@@ -2,7 +2,11 @@ loom)
|
|||||||
# credit: Lance Stephens (@pythoninthegrass on MacAdmins Slack)
|
# credit: Lance Stephens (@pythoninthegrass on MacAdmins Slack)
|
||||||
name="Loom"
|
name="Loom"
|
||||||
type="dmg"
|
type="dmg"
|
||||||
downloadURL=https://cdn.loom.com/desktop-packages/$(curl -fs https://s3-us-west-2.amazonaws.com/loom.desktop.packages/loom-inc-production/desktop-packages/latest-mac.yml | awk '/url/ && /dmg/ {print $3}' | head -1)
|
if [[ $(arch) == "arm64" ]]; then
|
||||||
|
downloadURL=https://cdn.loom.com/desktop-packages/$(curl -fs https://s3-us-west-2.amazonaws.com/loom.desktop.packages/loom-inc-production/desktop-packages/latest-mac.yml | awk '/url/ && /arm64/ && /dmg/ {print $3}' | head -1)
|
||||||
|
elif [[ $(arch) == "i386" ]]; then
|
||||||
|
downloadURL=https://cdn.loom.com/desktop-packages/$(curl -fs https://s3-us-west-2.amazonaws.com/loom.desktop.packages/loom-inc-production/desktop-packages/latest-mac.yml | awk '/url/ && /dmg/ {print $3}' | head -1)
|
||||||
|
fi
|
||||||
appNewVersion=$(curl -fs https://s3-us-west-2.amazonaws.com/loom.desktop.packages/loom-inc-production/desktop-packages/latest-mac.yml | awk '/version/ {print $2}' )
|
appNewVersion=$(curl -fs https://s3-us-west-2.amazonaws.com/loom.desktop.packages/loom-inc-production/desktop-packages/latest-mac.yml | awk '/version/ {print $2}' )
|
||||||
expectedTeamID="QGD2ZPXZZG"
|
expectedTeamID="QGD2ZPXZZG"
|
||||||
;;
|
;;
|
||||||
|
|||||||
7
fragments/labels/lowprofile.sh
Normal file
7
fragments/labels/lowprofile.sh
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
lowprofile)
|
||||||
|
name="Low Profile"
|
||||||
|
type="dmg"
|
||||||
|
downloadURL="$(downloadURLFromGit ninxsoft LowProfile)"
|
||||||
|
appNewVersion="$(versionFromGit ninxsoft LowProfile)"
|
||||||
|
expectedTeamID="7K3HVCLV7Z"
|
||||||
|
;;
|
||||||
9
fragments/labels/macadminspython.sh
Normal file
9
fragments/labels/macadminspython.sh
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
macadminspython)
|
||||||
|
name="MacAdmins Python"
|
||||||
|
type="pkg"
|
||||||
|
packageID="org.macadmins.python.recommended"
|
||||||
|
downloadURL=$(curl --silent --fail "https://api.github.com/repos/macadmins/python/releases/latest" | awk -F '"' "/browser_download_url/ && /python_recommended_signed/ { print \$4; exit }")
|
||||||
|
appNewVersion=$(grep -o -E '\d+\.\d+\.\d+\.\d+' <<< $downloadURL | head -n 1)
|
||||||
|
expectedTeamID="9GQZ7KUFR6"
|
||||||
|
blockingProcesses=( NONE )
|
||||||
|
;;
|
||||||
7
fragments/labels/maccyapp.sh
Normal file
7
fragments/labels/maccyapp.sh
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
maccyapp)
|
||||||
|
name="Maccy"
|
||||||
|
type="zip"
|
||||||
|
downloadURL="$(downloadURLFromGit p0deje Maccy)"
|
||||||
|
appNewVersion="$(versionFromGit p0deje Maccy)"
|
||||||
|
expectedTeamID="MN3X4648SC"
|
||||||
|
;;
|
||||||
23
fragments/labels/macports.sh
Normal file
23
fragments/labels/macports.sh
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
macports)
|
||||||
|
name="MacPorts"
|
||||||
|
type="pkg"
|
||||||
|
#buildVersion=$(uname -r | cut -d '.' -f 1)
|
||||||
|
case $(uname -r | cut -d '.' -f 1) in
|
||||||
|
21)
|
||||||
|
archiveName="Monterey.pkg"
|
||||||
|
;;
|
||||||
|
20)
|
||||||
|
archiveName="BigSur.pkg"
|
||||||
|
;;
|
||||||
|
19)
|
||||||
|
archiveName="Catalina.pkg"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
cleanupAndExit 1 "macOS 10.14 or earlier not supported by Installomator."
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
downloadURL=$(downloadURLFromGit macports macports-base)
|
||||||
|
appNewVersion=$(versionFromGit macports macports-base)
|
||||||
|
appCustomVersion(){ if [ -x /opt/local/bin/port ]; then /opt/local/bin/port version | awk '{print $2}'; else "0"; fi }
|
||||||
|
expectedTeamID="QTA3A3B7F3"
|
||||||
|
;;
|
||||||
8
fragments/labels/marathon.sh
Normal file
8
fragments/labels/marathon.sh
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
marathon)
|
||||||
|
name="Marathon"
|
||||||
|
type="dmg"
|
||||||
|
archiveName="Marathon-[0-9.]*-Mac.dmg"
|
||||||
|
downloadURL="$(downloadURLFromGit Aleph-One-Marathon alephone)"
|
||||||
|
appNewVersion="$(versionFromGit Aleph-One-Marathon alephone)"
|
||||||
|
expectedTeamID="E8K89CXZE7"
|
||||||
|
;;
|
||||||
8
fragments/labels/marathon2.sh
Normal file
8
fragments/labels/marathon2.sh
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
marathon2)
|
||||||
|
name="Marathon 2"
|
||||||
|
type="dmg"
|
||||||
|
archiveName="Marathon2-[0-9.]*-Mac.dmg"
|
||||||
|
downloadURL="$(downloadURLFromGit Aleph-One-Marathon alephone)"
|
||||||
|
appNewVersion="$(versionFromGit Aleph-One-Marathon alephone)"
|
||||||
|
expectedTeamID="E8K89CXZE7"
|
||||||
|
;;
|
||||||
8
fragments/labels/marathoninfinity.sh
Normal file
8
fragments/labels/marathoninfinity.sh
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
marathoninfinity)
|
||||||
|
name="Marathon Infinity"
|
||||||
|
type="dmg"
|
||||||
|
archiveName="MarathonInfinity-[0-9.]*-Mac.dmg"
|
||||||
|
downloadURL="$(downloadURLFromGit Aleph-One-Marathon alephone)"
|
||||||
|
appNewVersion="$(versionFromGit Aleph-One-Marathon alephone)"
|
||||||
|
expectedTeamID="E8K89CXZE7"
|
||||||
|
;;
|
||||||
@@ -1,12 +1,9 @@
|
|||||||
mattermost)
|
mattermost)
|
||||||
name="Mattermost"
|
name="Mattermost"
|
||||||
type="dmg"
|
type="dmg"
|
||||||
if [[ $(arch) == i386 ]]; then
|
archiveName="mac-universal.dmg"
|
||||||
archiveName="mac.dmg"
|
|
||||||
elif [[ $(arch) == arm64 ]]; then
|
|
||||||
archiveName="mac-m1.dmg"
|
|
||||||
fi
|
|
||||||
downloadURL=$(downloadURLFromGit mattermost desktop)
|
downloadURL=$(downloadURLFromGit mattermost desktop)
|
||||||
appNewVersion=$(versionFromGit mattermost desktop )
|
appNewVersion=$(versionFromGit mattermost desktop)
|
||||||
expectedTeamID="UQ8HT4Q2XM"
|
expectedTeamID="UQ8HT4Q2XM"
|
||||||
|
blockingProcesses=( "Mattermost Helper.app" "Mattermost Helper (Renderer).app" "Mattermost Helper (GPU).app" "Mattermost Helper (Plugin).app" )
|
||||||
;;
|
;;
|
||||||
|
|||||||
10
fragments/labels/microsoftazuredatastudio.sh
Normal file
10
fragments/labels/microsoftazuredatastudio.sh
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
microsoftazuredatastudio|\
|
||||||
|
azuredatastudio)
|
||||||
|
name="Azure Data Studio"
|
||||||
|
type="zip"
|
||||||
|
downloadURL=$( curl -sL https://github.com/microsoft/azuredatastudio/releases/latest | grep 'macOS ZIP' | grep -Eo "(http|https)://[a-zA-Z0-9./?=_%:-]*" )
|
||||||
|
appNewVersion=$(versionFromGit microsoft azuredatastudio )
|
||||||
|
expectedTeamID="UBF8T346G9"
|
||||||
|
appName="Azure Data Studio.app"
|
||||||
|
blockingProcesses=( "Azure Data Studio" )
|
||||||
|
;;
|
||||||
@@ -5,6 +5,10 @@ microsoftcompanyportal)
|
|||||||
#appNewVersion=$(curl -fs https://macadmins.software/latest.xml | xpath '//latest/package[id="com.microsoft.intunecompanyportal.standalone"]/cfbundleshortversionstring' 2>/dev/null | sed -E 's/<cfbundleshortversionstring>([0-9.]*)<.*/\1/')
|
#appNewVersion=$(curl -fs https://macadmins.software/latest.xml | xpath '//latest/package[id="com.microsoft.intunecompanyportal.standalone"]/cfbundleshortversionstring' 2>/dev/null | sed -E 's/<cfbundleshortversionstring>([0-9.]*)<.*/\1/')
|
||||||
appNewVersion=$(curl -fsIL "$downloadURL" | grep -i location: | grep -o "/CompanyPortal_.*pkg" | cut -d "_" -f 2 | cut -d "-" -f 1)
|
appNewVersion=$(curl -fsIL "$downloadURL" | grep -i location: | grep -o "/CompanyPortal_.*pkg" | cut -d "_" -f 2 | cut -d "-" -f 1)
|
||||||
expectedTeamID="UBF8T346G9"
|
expectedTeamID="UBF8T346G9"
|
||||||
|
if [[ -x "/Library/Application Support/Microsoft/MAU2.0/Microsoft AutoUpdate.app/Contents/MacOS/msupdate" && $INSTALL != "force" && $DEBUG -eq 0 ]]; then
|
||||||
|
printlog "Running msupdate --list"
|
||||||
|
"/Library/Application Support/Microsoft/MAU2.0/Microsoft AutoUpdate.app/Contents/MacOS/msupdate" --list
|
||||||
|
fi
|
||||||
updateTool="/Library/Application Support/Microsoft/MAU2.0/Microsoft AutoUpdate.app/Contents/MacOS/msupdate"
|
updateTool="/Library/Application Support/Microsoft/MAU2.0/Microsoft AutoUpdate.app/Contents/MacOS/msupdate"
|
||||||
updateToolArguments=( --install --apps IMCP01 )
|
updateToolArguments=( --install --apps IMCP01 )
|
||||||
;;
|
;;
|
||||||
|
|||||||
@@ -1,10 +1,15 @@
|
|||||||
|
microsoftdefender|\
|
||||||
microsoftdefenderatp)
|
microsoftdefenderatp)
|
||||||
name="Microsoft Defender ATP"
|
name="Microsoft Defender"
|
||||||
type="pkg"
|
type="pkg"
|
||||||
downloadURL="https://go.microsoft.com/fwlink/?linkid=2097502"
|
downloadURL="https://go.microsoft.com/fwlink/?linkid=2097502"
|
||||||
appNewVersion=$(curl -fs https://macadmins.software/latest.xml | xpath '//latest/package[id="com.microsoft.defender.standalone"]/version' 2>/dev/null | sed -E 's/<version>([0-9.]*) .*/\1/')
|
appNewVersion=$(curl -fs https://macadmins.software/latest.xml | xpath '//latest/package[id="com.microsoft.defender.standalone"]/version' 2>/dev/null | sed -E 's/<version>([0-9.]*) .*/\1/')
|
||||||
# No version number in download url
|
# No version number in download url
|
||||||
expectedTeamID="UBF8T346G9"
|
expectedTeamID="UBF8T346G9"
|
||||||
|
if [[ -x "/Library/Application Support/Microsoft/MAU2.0/Microsoft AutoUpdate.app/Contents/MacOS/msupdate" && $INSTALL != "force" && $DEBUG -eq 0 ]]; then
|
||||||
|
printlog "Running msupdate --list"
|
||||||
|
"/Library/Application Support/Microsoft/MAU2.0/Microsoft AutoUpdate.app/Contents/MacOS/msupdate" --list
|
||||||
|
fi
|
||||||
updateTool="/Library/Application Support/Microsoft/MAU2.0/Microsoft AutoUpdate.app/Contents/MacOS/msupdate"
|
updateTool="/Library/Application Support/Microsoft/MAU2.0/Microsoft AutoUpdate.app/Contents/MacOS/msupdate"
|
||||||
updateToolArguments=( --install --apps WDAV00 )
|
updateToolArguments=( --install --apps WDAV00 )
|
||||||
;;
|
;;
|
||||||
@@ -1,11 +1,16 @@
|
|||||||
microsoftedge|\
|
microsoftedge|\
|
||||||
microsoftedgeconsumerstable)
|
microsoftedgeconsumerstable|\
|
||||||
|
microsoftedgeenterprisestable)
|
||||||
name="Microsoft Edge"
|
name="Microsoft Edge"
|
||||||
type="pkg"
|
type="pkg"
|
||||||
downloadURL="https://go.microsoft.com/fwlink/?linkid=2069148"
|
downloadURL="https://go.microsoft.com/fwlink/?linkid=2093504"
|
||||||
#appNewVersion=$(curl -fs https://macadmins.software/latest.xml | xpath '//latest/package[id="com.microsoft.edge"]/cfbundleversion' 2>/dev/null | sed -E 's/<cfbundleversion>([0-9.]*)<.*/\1/')
|
#appNewVersion=$(curl -fs https://macadmins.software/latest.xml | xpath '//latest/package[id="com.microsoft.edge"]/cfbundleversion' 2>/dev/null | sed -E 's/<cfbundleversion>([0-9.]*)<.*/\1/')
|
||||||
appNewVersion=$(curl -fsIL "$downloadURL" | grep -i location: | grep -o "/MicrosoftEdge.*pkg" | sed -E 's/.*\/[a-zA-Z]*-([0-9.]*)\..*/\1/g')
|
appNewVersion=$(curl -fsIL "$downloadURL" | grep -i location: | grep -o "/MicrosoftEdge.*pkg" | sed -E 's/.*\/[a-zA-Z]*-([0-9.]*)\..*/\1/g')
|
||||||
expectedTeamID="UBF8T346G9"
|
expectedTeamID="UBF8T346G9"
|
||||||
|
if [[ -x "/Library/Application Support/Microsoft/MAU2.0/Microsoft AutoUpdate.app/Contents/MacOS/msupdate" && $INSTALL != "force" && $DEBUG -eq 0 ]]; then
|
||||||
|
printlog "Running msupdate --list"
|
||||||
|
"/Library/Application Support/Microsoft/MAU2.0/Microsoft AutoUpdate.app/Contents/MacOS/msupdate" --list
|
||||||
|
fi
|
||||||
updateTool="/Library/Application Support/Microsoft/MAU2.0/Microsoft AutoUpdate.app/Contents/MacOS/msupdate"
|
updateTool="/Library/Application Support/Microsoft/MAU2.0/Microsoft AutoUpdate.app/Contents/MacOS/msupdate"
|
||||||
updateToolArguments=( --install --apps EDGE01 )
|
updateToolArguments=( --install --apps EDGE01 )
|
||||||
;;
|
;;
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
microsoftedgeenterprisestable)
|
|
||||||
name="Microsoft Edge"
|
|
||||||
type="pkg"
|
|
||||||
downloadURL="https://go.microsoft.com/fwlink/?linkid=2093438"
|
|
||||||
#appNewVersion=$(curl -fs https://macadmins.software/latest.xml | xpath '//latest/package[id="com.microsoft.edge"]/version' 2>/dev/null | sed -E 's/<version>([0-9.]*) .*/\1/')
|
|
||||||
appNewVersion=$(curl -fsIL "$downloadURL" | grep -i location: | grep -o "/MicrosoftEdge.*pkg" | sed -E 's/.*\/[a-zA-Z]*-([0-9.]*)\..*/\1/g')
|
|
||||||
expectedTeamID="UBF8T346G9"
|
|
||||||
updateTool="/Library/Application Support/Microsoft/MAU2.0/Microsoft AutoUpdate.app/Contents/MacOS/msupdate"
|
|
||||||
updateToolArguments=( --install --apps EDGE01 )
|
|
||||||
;;
|
|
||||||
@@ -5,6 +5,10 @@ microsoftexcel)
|
|||||||
#appNewVersion=$(curl -fs https://macadmins.software/latest.xml | xpath '//latest/package[id="com.microsoft.excel.standalone.365"]/cfbundleshortversionstring' 2>/dev/null | sed -E 's/<cfbundleshortversionstring>([0-9.]*)<.*/\1/')
|
#appNewVersion=$(curl -fs https://macadmins.software/latest.xml | xpath '//latest/package[id="com.microsoft.excel.standalone.365"]/cfbundleshortversionstring' 2>/dev/null | sed -E 's/<cfbundleshortversionstring>([0-9.]*)<.*/\1/')
|
||||||
appNewVersion=$(curl -fsIL "$downloadURL" | grep -i location: | grep -o "/Microsoft_.*pkg" | cut -d "_" -f 3 | cut -d "." -f 1-2)
|
appNewVersion=$(curl -fsIL "$downloadURL" | grep -i location: | grep -o "/Microsoft_.*pkg" | cut -d "_" -f 3 | cut -d "." -f 1-2)
|
||||||
expectedTeamID="UBF8T346G9"
|
expectedTeamID="UBF8T346G9"
|
||||||
|
if [[ -x "/Library/Application Support/Microsoft/MAU2.0/Microsoft AutoUpdate.app/Contents/MacOS/msupdate" && $INSTALL != "force" && $DEBUG -eq 0 ]]; then
|
||||||
|
printlog "Running msupdate --list"
|
||||||
|
"/Library/Application Support/Microsoft/MAU2.0/Microsoft AutoUpdate.app/Contents/MacOS/msupdate" --list
|
||||||
|
fi
|
||||||
updateTool="/Library/Application Support/Microsoft/MAU2.0/Microsoft AutoUpdate.app/Contents/MacOS/msupdate"
|
updateTool="/Library/Application Support/Microsoft/MAU2.0/Microsoft AutoUpdate.app/Contents/MacOS/msupdate"
|
||||||
updateToolArguments=( --install --apps XCEL2019 )
|
updateToolArguments=( --install --apps XCEL2019 )
|
||||||
;;
|
;;
|
||||||
|
|||||||
@@ -7,6 +7,10 @@ microsoftoffice365)
|
|||||||
expectedTeamID="UBF8T346G9"
|
expectedTeamID="UBF8T346G9"
|
||||||
# using MS PowerPoint as the 'stand-in' for the entire suite
|
# using MS PowerPoint as the 'stand-in' for the entire suite
|
||||||
#appName="Microsoft PowerPoint.app"
|
#appName="Microsoft PowerPoint.app"
|
||||||
|
if [[ -x "/Library/Application Support/Microsoft/MAU2.0/Microsoft AutoUpdate.app/Contents/MacOS/msupdate" && $INSTALL != "force" && $DEBUG -eq 0 ]]; then
|
||||||
|
printlog "Running msupdate --list"
|
||||||
|
"/Library/Application Support/Microsoft/MAU2.0/Microsoft AutoUpdate.app/Contents/MacOS/msupdate" --list
|
||||||
|
fi
|
||||||
blockingProcesses=( "Microsoft AutoUpdate" "Microsoft Word" "Microsoft PowerPoint" "Microsoft Excel" "Microsoft OneNote" "Microsoft Outlook" "OneDrive" )
|
blockingProcesses=( "Microsoft AutoUpdate" "Microsoft Word" "Microsoft PowerPoint" "Microsoft Excel" "Microsoft OneNote" "Microsoft Outlook" "OneDrive" )
|
||||||
updateTool="/Library/Application Support/Microsoft/MAU2.0/Microsoft AutoUpdate.app/Contents/MacOS/msupdate"
|
updateTool="/Library/Application Support/Microsoft/MAU2.0/Microsoft AutoUpdate.app/Contents/MacOS/msupdate"
|
||||||
updateToolArguments=( --install )
|
updateToolArguments=( --install )
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user