# cccjob: a program to create CCCma job strings
#   Larry Solheim Apr,2004

# Define a string to append to certain file names
STAMP := $(shell date "+%Y_%b%d_%H%M%S")

# Determine kernel type and machine name
MACH_TYPE  := $(shell uname -s|tr '[A-Z]' '[a-z]')
MACH_NAME  := $(word 1,$(subst ., ,$(shell uname -n|awk -F'.' '{print $1}' -)))
MACH_ALIAS := $(word 1,$(subst ., ,$(MACH_NAME)))

# Determine dns domain name
DOMAIN := $(subst int.cmc.,cmc.,$(word 2,$(shell grep -E 'search|domain' /etc/resolv.conf)))

LOCATION := $(word 1,$(subst ., ,$(DOMAIN)))
ifndef LOCATION
  $(error Unable to determine a value for LOCATION.)
endif

# SRCdir contains the cccjob git repository on the local machine (lxlp01)
# It is the working copy of this repo that will be sync'd with remote install locations
# The trailing "/" on SRCdir tells rsync to copy only the contents of the dir
# rather than the directory and all its contents (ie the dir name will not
# be created on the destination machine)
SRCdir := $(HOME)/src/cccjob/

# ARC_ROOT is a path to the root of the archive directory
ARC_ROOT := $(HOME)/src/cccjob/archive

# CCCJOB_ROOT is a path to the root of the installed cccjob directory tree
    CCCJOB_ROOT := $(CCRNSRC)/cccjob_dir/pub
rem_CCCJOB_ROOT := '~acrnsrc/cccjob_dir/pub'

# BETA_ROOT is the equivalent to CCCJOB_ROOT for beta testing
    BETA_ROOT := $(CCRNSRC)/cccjob_dir/beta
rem_BETA_ROOT := '~acrnsrc/cccjob_dir/beta'

# CURR_ROOT is used by the sync_lxlp01 target to syncronize either the "official"
# directory in CCCJOB_ROOT or the beta directory in BETA_ROOT
CURR_ROOT =

# SYNC_MAMCCC = yes means syncronize the cccjob_dir on mamccc at UofT
SYNC_MAMCCC := no

# This is the fully qualified domain name used when syncronizing files
# on the UofT machine mamccc
MAMCCC := mamccc.atmosp.physics.utoronto.ca

# Define the location of the local git repository for cccjob
LOCAL_GIT_REPO := $(HOME)/src/cccjob

# This will expand to the full pathname of the git mirror dir on the remote machine
# (either joule or lxwrk1) assuming acrnsrc is a valid user in that environment
REM_GIT_REPO := '~acrnsrc/cccjob_dir/cccjob.git'

# This is used by the "check" target to see what would happen if "sync_lxlp01" was invoked
DRY_RUN_OPT :=

# A command line definition (e.g. backup=off) will override the default for BACKUP_WITH_SYNC
ifdef backup
  BACKUP_WITH_SYNC := $(backup)
else
  BACKUP_WITH_SYNC := on
endif

# This help is the default target so that typing just "make" will not do anything destructive
.PHONY: help
help:
	@echo "Goals used to update cccjob source code are the following."
	@echo "make beta      ...syncronize $(SRCdir) with the BETA cccjob dir $(BETA_ROOT)"
	@echo "make install   ...syncronize $(SRCdir) with the OFFICIAL cccjob dir $(CCCJOB_ROOT) then mirror the git repo"
	@echo "make sync      ...syncronize $(SRCdir) with the OFFICIAL cccjob dir $(CCCJOB_ROOT) but do not mirror"
	@echo "make check     ...show what would be modified if sync were invoked, but make no changes"
	@echo "make mirror    ...mirror the local cccjob repo in $(LOCAL_GIT_REPO)"
	@echo "                  on joule:$(shell ssh joule echo $(REM_GIT_REPO))"
	@echo "                  on lxwrk1:$(shell ssh lxwrk1 echo $(REM_GIT_REPO))"
	@echo "make restore_beta ...restore the BETA cccjob dir from an archived directory"
	@echo "make restore      ...restore the OFFICIAL cccjob dir from an archived directory"
	@echo " "
	@echo "To disable backups add backup=off to the command line"
	@echo "To use the beta dir you need to set CCCJOB_ROOT=~acrnsrc/cccjob_dir/beta in your environment"

.PHONY: debug
debug:
	@echo "  MACH_TYPE  = $(MACH_TYPE)"
	@echo "  MACH_NAME  = $(MACH_NAME)"
	@echo "  MACH_ALIAS = $(MACH_ALIAS)"
	@echo "   LOCATION  = $(LOCATION)"
	@echo "       STAMP = $(STAMP)"
	@echo "      SRCdir = $(SRCdir)"
	@echo "    ARC_ROOT = $(ARC_ROOT)"
	@echo " CCCJOB_ROOT = $(CCCJOB_ROOT)"
	@echo "   BETA_ROOT = $(BETA_ROOT)"
	@echo "GIT_PATH_DOR = $(shell ssh joule  echo $(REM_GIT_REPO))"
	@echo "GIT_PATH_VIC = $(shell ssh lxwrk1 echo $(REM_GIT_REPO))"

# Syncronize targets

sync_lxlp01: backup
ifneq ($(MACH_ALIAS), lxlp01)
	$(error The sync_lxlp01 target may only be excuted on lxlp01)
endif
	@# Sync with the local CCRNSRC dir on lxlp01
	@echo "rsync ... $(SRCdir) $(CURR_ROOT)"
	@rsync -Ca $(DRY_RUN_OPT) --delete-excluded \
	  --chmod=Dg+rx,Fg+r,g+X               \
	  --include '/bin/'                    \
	  --include '/bin/cccjob'              \
	  --include '/bin/cccjob_driver'       \
	  --include '/bin/make_file_name_list' \
	  --include '/bin/data_file_lists'     \
	  --include '/bin/splice_job_string'   \
	  --include '/bin/check_jobs'          \
	  --include '/bin/ncgm2pdf'  \
	  --include '/bin/lsarc'     \
	  --include '/bin/lsdat'     \
	  --include '/bin/days_since'\
	  --include '/bin/qdump'     \
	  --include '/bin/qload'     \
	  --include '/bin/qtrans'    \
	  --include '/bin/qrun'      \
	  --include '/bin/mvcccd'    \
	  --include '/bin/jobdiff'    \
	  --include '/lib/'          \
	  --include '/lib/missing/'  \
	  --include '/lib/jobdefs/'  \
	  --include '/lib/jobdefs/*_jobdef'  \
	  --include '/lib/updates/'  \
	  --include '/lib/libdb_3.3.11_aix51-ppc-64/'  \
	  --include '/lib/libdb_3.3.11_aix51-ppc-64/libdb*'  \
	  --include '*.pm'           \
	  --include 'rcm_PARAMETERS' \
	  --include '*_update'       \
	  --exclude '**' $(SRCdir) $(CURR_ROOT)

backup:
	@# Back up any existing directory before running rsync unless this is a dry run
	@if [ x"$(BACKUP_WITH_SYNC)" = xon ]; then \
	  if [ -z "$(DRY_RUN_OPT)" ]; then \
	    if [ -n "$(CURR_ROOT)" -a -d $(CURR_ROOT)/bin -a -d $(CURR_ROOT)/lib ]; then \
	      bakdir=bak_$(STAMP); \
	      if [ $(CURR_ROOT) = $(BETA_ROOT) ]; then bakdir=beta_bak_$(STAMP); fi; \
	      rsync -Ca --chmod=go-rwx --delete-excluded $(CURR_ROOT)/ $(ARC_ROOT)/$$bakdir; \
	      echo "Backup is in $(ARC_ROOT)/$$bakdir"; \
	    fi; \
	  fi; \
	fi

# Invoke rsync with dry run options ...see what will be changed by the sync target
check: override      DRY_RUN_OPT := -v --dry-run --checksum
check: override BACKUP_WITH_SYNC := off
check: override        CURR_ROOT := $(CCCJOB_ROOT)
check: override    rem_CURR_ROOT := $(rem_CCCJOB_ROOT)
check: sync_lxlp01

sync_remote:
	@# After syncronizing the local CURR_ROOT, use it to syncronize remote sites
	@# The tailing "/" on the source dir is required so that only the contents
	@# of the source (basename) dir are transfered and not the dir itself
	@echo "remote:"
	rsync -Cav --include '*.a' --delete-excluded $(CURR_ROOT)/ lxwrk1:$(rem_CURR_ROOT)
	rsync -Cav --include '*.a' --delete-excluded $(CURR_ROOT)/ joule:$(rem_CURR_ROOT)

# Sync the official cccjob dir without updating and mirroring the git repo
sync: override     CURR_ROOT := $(CCCJOB_ROOT)
sync: override rem_CURR_ROOT := $(rem_CCCJOB_ROOT)
sync: sync_lxlp01 sync_remote

beta: override     CURR_ROOT := $(BETA_ROOT)
beta: override rem_CURR_ROOT := $(rem_BETA_ROOT)
beta: sync_lxlp01 sync_remote

install: override     CURR_ROOT := $(CCCJOB_ROOT)
install: override rem_CURR_ROOT := $(rem_CCCJOB_ROOT)
install: sync_lxlp01 sync_remote mirror
ifeq ($(SYNC_MAMCCC), yes)
	rsync -Ca --delete-excluded $(CURR_ROOT)/ $(MAMCCC):/home/acrnsrc/cccjob_dir
endif

# Restore targets

restore_lxlp01:
ifneq ($(MACH_ALIAS), lxlp01)
  $(error The restore_lxlp01 target may only be excuted on lxlp01)
endif
	@echo "Time sorted list of dirs in $(ARC_ROOT)"; ls -lrt $(ARC_ROOT); echo " "; \
	read -p "Enter the name of an archive directory found in this list:  " resdir; \
	if [ -n "$$resdir" -a -d "$(ARC_ROOT)/$$resdir" ]; then \
	  echo "Restoring files in $(CURR_ROOT) from files in $(ARC_ROOT)/$$resdir"; \
	  rsync -Ca --chmod=Dg+rx,Fg+r,g+X --delete-excluded $(ARC_ROOT)/$$resdir/ $(CURR_ROOT); \
	else \
	  echo "$$resdir is not a directory"; exit 1; \
	fi

restore_beta: override     CURR_ROOT := $(BETA_ROOT)
restore_beta: override rem_CURR_ROOT := $(rem_BETA_ROOT)
restore_beta: restore_lxlp01 sync_remote

restore: override     CURR_ROOT := $(CCCJOB_ROOT)
restore: override rem_CURR_ROOT := $(rem_CCCJOB_ROOT)
restore: restore_lxlp01 sync_remote

# Ensure that there are no uncommitted changes in the local git repo
check_local_git_repo: $(LOCAL_GIT_REPO)
	@echo "Checking for changes in $(LOCAL_GIT_REPO)"
	@cd $(LOCAL_GIT_REPO) && git diff-index --exit-code HEAD
	@echo "No changes. $(LOCAL_GIT_REPO) is up to date."

# Make sure that LOCAL_GIT_REPO is a valid directory name
$(LOCAL_GIT_REPO):
	test -d $(LOCAL_GIT_REPO)

# Push to remote git repositories but first check that there are no changes in the local repo
mirror: check_local_git_repo
ifneq ($(MACH_NAME), lxlp01)
        $(error The mirror target may only excute on lxlp01)
endif
	cd $(LOCAL_GIT_REPO) && \
	git push --mirror joule.cmc.ec.gc.ca:$(shell ssh joule echo $(REM_GIT_REPO)) && \
	git push --mirror lxwrk1.cccma.ec.gc.ca:$(shell ssh lxwrk1 echo $(REM_GIT_REPO))

# Recreate empty remote git repositories
# Only necessary when the remote repo becomes corrupt or goes missing

# This target will delete and then recreate the remote mirrored dir as an empty repo
# It can then be repopulated using the mirror target below
.PHONY: create_cccjob.git_dorval
create_cccjob.git_dorval:
ifneq ($(MACH_NAME), lxlp01)
        $(error The create_cccjob.git_dorval target may only excute on lxlp01)
endif
	ssh joule rm -fr $(REM_GIT_REPO) \&\& git init --shared=0755 --bare $(REM_GIT_REPO)

# This target will delete and then recreate the remote mirrored dir as an empty repo
# It can then be repopulated using the mirror target below
.PHONY: create_cccjob.git_vic
create_cccjob.git_vic:
ifneq ($(MACH_NAME), lxlp01)
        $(error The create_cccjob.git_vic target may only excute on lxlp01)
endif
	ssh lxwrk1 rm -fr $(REM_GIT_REPO) \&\& git init --shared=0755 --bare $(REM_GIT_REPO)
