4bdfdd6ae75a39b78f9ff7792ccaf1b25914a1df
configuration/crontab
| ... | ... | @@ -1,3 +1,3 @@ |
| 1 | 1 | * * * * * export PATH=/bin:/usr/bin:/usr/local/bin; sleep $(( $RANDOM * 60 / 32768 )); update_authorized_keys_for_landscape_managers_if_changed $( cat /root/ssh-key-reader.token ) https://security-service.sapsailing.com /root 2>&1 >>/var/log/sailing.err |
| 2 | 2 | # NOTICE: Please try to reference the customised crontabs at $GIT_HOME/configuration/crontabs or use |
| 3 | -# the build-crontab-and-cp-files script. This file has been maintained for continuity, but is deprecated. |
|
| ... | ... | \ No newline at end of file |
| 0 | +# the build_crontab_and_setup_files command in imageupgrade_functions.sh. This file has been maintained for continuity, but is deprecated. |
|
| ... | ... | \ No newline at end of file |
configuration/environments_scripts/mongo_instance_setup/README
| ... | ... | @@ -4,8 +4,8 @@ furthermore the ../imageupgrade_functions.sh has to go to /usr/local/bin. |
| 4 | 4 | Deploy mongod.conf to /etc and make sure that /root has a+r and a+x permissions because |
| 5 | 5 | otherwise the mongod user won't be able to read through the symbolic link |
| 6 | 6 | Link mongodb to /etc/logrotate.d |
| 7 | -Link the crontab-mongo, in configuration/crontabs/environments, to /root/crontab and run "crontab crontab" as root. |
|
| 8 | - |
|
| 7 | +Utilise the build-crontab-and-cp-files script or the build_crontab_and_setup_files (in imageupgrade_functions.sh) |
|
| 8 | +to create the crontab file and install it in the root user. |
|
| 9 | 9 | Run with optional EC2 user detail, e.g., as follows: |
| 10 | 10 | |
| 11 | 11 | REPLICA_SET_NAME=archive |
configuration/mysql_instance_setup/crontab-ec2-user
| ... | ... | @@ -1,3 +1,3 @@ |
| 1 | 1 | * * * * * export PATH=/bin:/usr/bin:/usr/local/bin; sleep $(( $RANDOM * 60 / 32768 )); update_authorized_keys_for_landscape_managers_if_changed $( cat /home/ec2-user/ssh-key-reader.token ) https://security-service.sapsailing.com /home/ec2-user |
| 2 | 2 | # NOTICE: Please try to reference the customised crontabs at $GIT_HOME/configuration/crontabs or use |
| 3 | -# the build-crontab-and-cp-files script. This file has been maintained for continuity, but is deprecated. |
|
| 3 | +# the build_crontab_and_setup_files command in imageupgrade_functions.sh. This file has been maintained for continuity, but is deprecated. |
configuration/sailing_server_setup/crontab-root
| ... | ... | @@ -1,3 +1,3 @@ |
| 1 | 1 | * * * * * export PATH=/bin:/usr/bin:/usr/local/bin; sleep $(( $RANDOM * 60 / 32768 )); update_authorized_keys_for_landscape_managers_if_changed $( cat /root/ssh-key-reader.token ) https://security-service.sapsailing.com /root 2>&1 >>/var/log/sailing.err |
| 2 | 2 | # NOTICE: Please try to reference the customised crontabs at $GIT_HOME/configuration/crontabs or use |
| 3 | -# the build-crontab-and-cp-files script. This file has been maintained for continuity, but is deprecated. |
|
| 3 | +# the build_crontab_and_setup_files command in imageupgrade_functions.sh. This file has been maintained for continuity, but is deprecated. |
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/nodes/base/AutoPlayNode.java
| ... | ... | @@ -15,6 +15,6 @@ public interface AutoPlayNode { |
| 15 | 15 | * Will be called before onStart, before calling this the default duration is submitted. Override for custom duration. |
| 16 | 16 | * A time can be supplied multiple times, the timer will restart from the time of submission |
| 17 | 17 | */ |
| 18 | - default void customDurationHook(Consumer<Integer> consumer) { |
|
| 18 | + default void customDurationHook(Consumer<Integer> consumerOfDurationInSeconds) { |
|
| 19 | 19 | }; |
| 20 | 20 | } |
| ... | ... | \ No newline at end of file |
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/AbstractLeaderboardConfigPanel.java
| ... | ... | @@ -117,7 +117,6 @@ public abstract class AbstractLeaderboardConfigPanel extends FormPanel |
| 117 | 117 | protected SubscriptionServiceFactory subscriptionServiceFactory; |
| 118 | 118 | |
| 119 | 119 | private final Displayer<StrippedLeaderboardDTO> leaderboardsDisplayer = new Displayer<StrippedLeaderboardDTO>() { |
| 120 | - |
|
| 121 | 120 | @Override |
| 122 | 121 | public void fill(Iterable<StrippedLeaderboardDTO> result) { |
| 123 | 122 | fillLeaderboards(result); |
| ... | ... | @@ -129,7 +128,6 @@ public abstract class AbstractLeaderboardConfigPanel extends FormPanel |
| 129 | 128 | } |
| 130 | 129 | |
| 131 | 130 | private final Displayer<RegattaDTO> regattasDisplayer = new Displayer<RegattaDTO>() { |
| 132 | - |
|
| 133 | 131 | @Override |
| 134 | 132 | public void fill(Iterable<RegattaDTO> result) { |
| 135 | 133 | fillRegattas(result); |
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/LeaderboardConfigPanel.java
| ... | ... | @@ -166,7 +166,6 @@ public class LeaderboardConfigPanel extends AbstractLeaderboardConfigPanel |
| 166 | 166 | stringMessages.createRegattaLeaderboardWithOtherTieBreakingLeaderboard() + " ...", |
| 167 | 167 | leaderboardCreateAndRegattaReadPermission, this::createRegattaLeaderboardWithOtherTieBreakingLeaderboard); |
| 168 | 168 | createRegattaLeaderboardWithOtherTieBreakingLeaderboardBtn.ensureDebugId("CreateRegattaLeaderboardWithOtherTieBreakingLeaderboardButton"); |
| 169 | - |
|
| 170 | 169 | leaderboardRemoveButton = buttonPanel.addRemoveAction(stringMessages.remove(), leaderboardSelectionModel, true, |
| 171 | 170 | () -> removeLeaderboards(leaderboardSelectionModel.getSelectedSet())); |
| 172 | 171 | leaderboardRemoveButton.ensureDebugId("LeaderboardsRemoveButton"); |
| ... | ... | @@ -396,7 +395,7 @@ public class LeaderboardConfigPanel extends AbstractLeaderboardConfigPanel |
| 396 | 395 | |
| 397 | 396 | private void editLeaderboard(StrippedLeaderboardDTO leaderboardDTO) { |
| 398 | 397 | final String oldLeaderboardName = leaderboardDTO.getName(); |
| 399 | - List<StrippedLeaderboardDTO> otherExistingLeaderboard = new ArrayList<StrippedLeaderboardDTO>(); |
|
| 398 | + final List<StrippedLeaderboardDTO> otherExistingLeaderboard = new ArrayList<>(); |
|
| 400 | 399 | otherExistingLeaderboard.addAll(availableLeaderboardList); |
| 401 | 400 | otherExistingLeaderboard.remove(leaderboardDTO); |
| 402 | 401 | if (leaderboardDTO.type.isMetaLeaderboard()) { |
| ... | ... | @@ -1113,6 +1112,8 @@ public class LeaderboardConfigPanel extends AbstractLeaderboardConfigPanel |
| 1113 | 1112 | break; |
| 1114 | 1113 | } |
| 1115 | 1114 | } |
| 1115 | + getLeaderboardsRefresher().addIfNotContainedElseReplace(updatedLeaderboard, |
|
| 1116 | + new NameBasedStrippedLeaderboardDTOEntityIdentityComparator()); |
|
| 1116 | 1117 | availableLeaderboardList.set(indexOfLeaderboard, updatedLeaderboard); |
| 1117 | 1118 | filterLeaderboardPanel.updateAll(availableLeaderboardList); |
| 1118 | 1119 | } |
java/com.sap.sse.landscape.aws/src/com/sap/sse/landscape/aws/impl/ApacheReverseProxy.java
| ... | ... | @@ -128,8 +128,9 @@ implements com.sap.sse.landscape.Process<RotatingFileBasedLog, MetricsT> { |
| 128 | 128 | private void setRedirect(String configFileNameForHostname, String macroName, String hostname, |
| 129 | 129 | Optional<String> optionalKeyName, byte[] privateKeyEncryptionPassphrase, boolean doCommit, boolean doPush, String... macroArguments) |
| 130 | 130 | throws Exception { |
| 131 | - String command = "su - " + CONFIG_USER + " -c 'cd " + CONFIG_REPO_PATH + " && git checkout " + CONFIG_REPO_MAIN_BRANCH_NAME + " && echo \"Use " + macroName + " " + hostname + " " + String.join(" ", macroArguments) + "\" > " |
|
| 132 | - + getAbsoluteConfigFilePath(configFileNameForHostname); |
|
| 131 | + String command = "su - " + CONFIG_USER + " -c 'cd " + CONFIG_REPO_PATH + " && git checkout " |
|
| 132 | + + CONFIG_REPO_MAIN_BRANCH_NAME + " && echo \"Use " + macroName + " " + hostname + " " |
|
| 133 | + + String.join(" ", macroArguments) + "\" > " + getAbsoluteConfigFilePath(configFileNameForHostname); |
|
| 133 | 134 | if (doCommit) { |
| 134 | 135 | command = command + " && cd " |
| 135 | 136 | + CONFIG_REPO_PATH + " && " + createCommitAndPushString(configFileNameForHostname, |
| ... | ... | @@ -145,7 +146,8 @@ implements com.sap.sse.landscape.Process<RotatingFileBasedLog, MetricsT> { |
| 145 | 146 | } |
| 146 | 147 | |
| 147 | 148 | /** |
| 148 | - * Overloads {@link #setRedirect(String, String, String, Optional, byte[], boolean, boolean, String...)} and defaults to true and true for committing and pushing. |
|
| 149 | + * Overloads {@link #setRedirect(String, String, String, Optional, byte[], boolean, boolean, String...)} and |
|
| 150 | + * defaults to {@code true} and {@code true} for committing and pushing. |
|
| 149 | 151 | * |
| 150 | 152 | * @see #setRedirect(String, String, String, Optional, byte[], boolean, boolean, String...) |
| 151 | 153 | */ |
| ... | ... | @@ -153,10 +155,11 @@ implements com.sap.sse.landscape.Process<RotatingFileBasedLog, MetricsT> { |
| 153 | 155 | Optional<String> optionalKeyName, byte[] privateKeyEncryptionPassphrase, String... macroArguments) |
| 154 | 156 | throws Exception { |
| 155 | 157 | setRedirect(configFileNameForHostname, macroName, hostname, optionalKeyName, privateKeyEncryptionPassphrase, |
| 156 | - true, true, macroArguments); |
|
| 158 | + /* doCommit */ true, /* doPush */ true, macroArguments); |
|
| 157 | 159 | } |
| 158 | 160 | |
| 159 | - private String runCommandAndReturnStdoutAndStderr(String command, String stderrLogPrefix, Level stderrLogLevel, Optional<String> optionalKeyName, byte[] privateKeyEncryptionPassphrase) throws Exception { |
|
| 161 | + private String runCommandAndReturnStdoutAndStderr(String command, String stderrLogPrefix, Level stderrLogLevel, |
|
| 162 | + Optional<String> optionalKeyName, byte[] privateKeyEncryptionPassphrase) throws Exception { |
|
| 160 | 163 | final SshCommandChannel sshChannel = getHost().createRootSshChannel(TIMEOUT, optionalKeyName, privateKeyEncryptionPassphrase); |
| 161 | 164 | final String stdout = sshChannel.runCommandAndReturnStdoutAndLogStderr(command, stderrLogPrefix, stderrLogLevel); |
| 162 | 165 | return stdout; |
wiki/info/landscape/amazon-ec2.md
| ... | ... | @@ -399,6 +399,56 @@ In the "Amazon Machine Images (AMIs)" table each row offers an action icon for r |
| 399 | 399 | |
| 400 | 400 | We now have a script to automatically create a mailing list of all the landscape managers, that is stored in /var/cache. It is updated via a cronjob. We have to be careful to write atomically, so the mailing list isn't missing any email addresses, if the notify-operators script is called midway through a write. |
| 401 | 401 | |
| 402 | +### Crontab setup and script organisation |
|
| 403 | + |
|
| 404 | +We previously relied on lots of symbolic links to the various architecture scripts, which were scattered throughout the configuration directory of our Git repo. This made it easy to propagate changes, but also led to moments of chaos, as we had to find every single dependency, for every change pushed to the git repo repo (stored by the trac user), in case it was the target of a symbolic link. |
|
| 405 | + |
|
| 406 | +We now have a well defined structure (detailed below) for the different environment types, such as the central reverse proxy, the disposables, the build server, sailing server, etc.. and a method for updating instances in a controlled manner. |
|
| 407 | +``` |
|
| 408 | +configuration |
|
| 409 | +├── crontabs |
|
| 410 | +│ ├── crontab-update-trac-trac-urls |
|
| 411 | +│ └── crontab-syncgit |
|
| 412 | +└── environments_scripts |
|
| 413 | + ├── build-crontab-and-cp-files |
|
| 414 | + ├── build_server |
|
| 415 | + │ ├── files |
|
| 416 | + │ │ ├── etc |
|
| 417 | + │ │ │ ├── sysconfig |
|
| 418 | + │ │ │ │ └── hudson |
|
| 419 | + │ │ │ └── systemd |
|
| 420 | + │ │ │ └── system |
|
| 421 | + │ │ . ├── hudson.service |
|
| 422 | + │ │ . └── mountnvmeswap.service -> ../../../../../repo/etc/systemd/system/mountnvmeswap.service |
|
| 423 | + │ └── users |
|
| 424 | + │ └── root |
|
| 425 | + │ └── crontab-update-authorized-keys -> ../../../../crontabs/crontab-update-authorized-keys |
|
| 426 | + └── repo |
|
| 427 | + ├── etc |
|
| 428 | + └── var |
|
| 429 | +``` |
|
| 430 | +In the environments_scripts folder, we have the script `build-crontab-and-cp-files` for the aforementioned "controlled building", which is explained further below. Then we have directories for each environment type as well as a general purpose repo for storing files common to multiple instances. Within each environment type directory, should be a setup script, for creating an instance, of the environment type, from scratch. There is also an optional users and files folder. |
|
| 431 | + |
|
| 432 | +The users folder is for organising crontabs: there is a folder for each user that should have a crontab and, within these username folders, are symbolic links |
|
| 433 | +to the crontabs folder, which contains files named `crontab-"function"`, each one containing a one-line crontab. |
|
| 434 | + |
|
| 435 | +The files folder is for organising files that should reside on the environment type. Within the directory, is a mimicked UNIX filesystem. Files in, say /etc/awstats of reverse_proxy's files dir, should |
|
| 436 | +be found on the reverse proxy instances at /etc/awstats. |
|
| 437 | + |
|
| 438 | +Any scripts common to multiple environment scripts, may be found in the "repo", which is at the same level as the environment types directory, and contains only a mimicked file system (no users folder). These common scripts are added to an environment type, by creating symbolic links from the intended destination on the environment type to the script in the repo. In the example above, the mountnvmeswap.service link indicates the intended location and the contents of the file is the target of the symbolic link. |
|
| 439 | + |
|
| 440 | +The build-crontab-and-cp-files uses this structure to help setup an environment |
|
| 441 | +type. It builds the crontab file, by combining all the referenced crontab |
|
| 442 | +one-liners, storing a copy in the user's home directory and installing it to the specified user. It also copies across the contents of "files" to the corresponding location, de-refencing any symbolic links. |
|
| 443 | +The script should ideally be triggered using a function in `imageupgrade_functions.sh`, titled `build_crontab_and_setup_files`, that takes an environment type (see other arguments below), and temporarily copies (via scp) the environments_scripts folder. It then calls the build-crontab-and-cp-files script. |
|
| 444 | + |
|
| 445 | +This script has a couple of arguments and options. The most important are the arguments. |
|
| 446 | +1. Environment type. |
|
| 447 | +2. User with a checked out Git copy. |
|
| 448 | +3. The relative path within $2 to the Git copy. |
|
| 449 | +Ideally, we would have only a single checked out Git copy across all instances: one on the wiki user of the central. However, some crontabs require references to specific users' files, so we have the strings PATH_OF_GIT_HOME_DIR_TO_REPLACE & PATH_OF_HOME_DIR_TO_REPLACE, in the crontabs, as placeholders for the paths the string itself describes, which the build-crontab-and-cp-files script replaces with the right path. |
|
| 450 | +Have a look at the script itself for more details on the options and arguments. |
|
| 451 | + |
|
| 402 | 452 | |
| 403 | 453 | ## Automated SSH Key Management |
| 404 | 454 |