Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,6 @@ jobs:
echo "http://localhost" # submitty url
echo "" # vcs url
echo "" # institution name
echo "y" # user create account
echo "" # sysadmin email
echo "" # where to report
echo "1" # PamAuth
Expand Down
124 changes: 50 additions & 74 deletions .setup/CONFIGURE_SUBMITTY.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
import pwd
import secrets
import shutil
import string
import tzlocal
import string
import tempfile


Expand All @@ -28,7 +28,10 @@ def get_ids(user):
raise SystemExit("ERROR: Could not find user: " + user)


def get_input(question, default=""):
def get_input(question, default="", use_default=False):
print(use_default)
if use_default:
return default
add = "[{}] ".format(default) if default != "" else ""
user = input("{}: {}".format(question, add)).strip()
if user == "":
Expand Down Expand Up @@ -61,9 +64,10 @@ def __call__(self, parser, namespace, values, option_string=None):
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('--debug', action='store_true', default=False, help='Configure Submitty to be in debug mode. '
'This should not be used in production!')
parser.add_argument('--setup-for-sample-courses', action='store_true', default=False,
help="Sets up Submitty for use with the sample courses. This is a Vagrant convenience "
"flag and should not be used in production!")
parser.add_argument('--dev-vm', action='store_true', default=False,
help="Sets up submitty for use with Vagrant for developers, not to be used for production")
parser.add_argument('--ci', action='store_true', default=False,
help="Sets up Submitty with parameters for CI, This should not be used in production.")
parser.add_argument('--worker', action='store_true', default=False, help='Configure Submitty with autograding only')
parser.add_argument('--install-dir', default='/usr/local/submitty', help='Set the install directory for Submitty')
parser.add_argument('--data-dir', default='/var/local/submitty', help='Set the data directory for Submitty')
Expand Down Expand Up @@ -157,6 +161,7 @@ def __call__(self, parser, namespace, values, option_string=None):
SETUP_INSTALL_DIR = os.path.join(SUBMITTY_INSTALL_DIR, '.setup')
SETUP_REPOSITORY_DIR = os.path.join(SUBMITTY_REPOSITORY, '.setup')

DEFAULTS_FILE = os.path.join(SETUP_REPOSITORY_DIR, 'defaults.json')
INSTALL_FILE = os.path.join(SETUP_INSTALL_DIR, 'INSTALL_SUBMITTY.sh')
CONFIGURATION_JSON = os.path.join(SETUP_INSTALL_DIR, 'submitty_conf.json')
SITE_CONFIG_DIR = os.path.join(SUBMITTY_INSTALL_DIR, "site", "config")
Expand All @@ -174,41 +179,12 @@ def __call__(self, parser, namespace, values, option_string=None):
'SamlAuthentication'
]

defaults = {
'database_host': 'localhost',
'database_port': 5432,
'database_user': 'submitty_dbuser',
'database_course_user': 'submitty_course_dbuser',
'submission_url': '',
'supervisor_user': 'submitty',
'vcs_url': '',
'authentication_method': 0,
'institution_name' : '',
'institution_homepage' : '',
'user_create_account' : False,
'timezone' : str(tzlocal.get_localzone()),
'submitty_admin_username': '',
'email_user': '',
'email_password': '',
'email_sender': 'submitty@myuniversity.edu',
'email_reply_to': 'submitty_do_not_reply@myuniversity.edu',
'email_server_hostname': 'mail.myuniversity.edu',
'email_server_port': 25,
'email_internal_domain': 'example.com',
'course_code_requirements': "Please follow your school's convention for course code.",
'sys_admin_email': '',
'sys_admin_url': '',
'ldap_options': {
'url': '',
'uid': '',
'bind_dn': ''
},
'saml_options': {
'name': '',
'username_attribute': ''
},
'course_material_file_upload_limit_mb': 100
}
defaults = {}
with open(DEFAULTS_FILE, 'r') as defaults_file:
defaults = json.load(defaults_file)
defaults['timezone'] = str(tzlocal.get_localzone())
if args.ci:
defaults['database_host'] = 'localhost'

loaded_defaults = {}
if os.path.isfile(CONFIGURATION_JSON):
Expand Down Expand Up @@ -249,81 +225,81 @@ def __call__(self, parser, namespace, values, option_string=None):

print('Hit enter to use default in []')
print()

USE_DEFAULT = args.dev_vm is True
if args.worker:
SUPERVISOR_USER = get_input('What is the id for your submitty user?', defaults['supervisor_user'])
SUPERVISOR_USER = get_input('What is the id for your submitty user?', defaults['supervisor_user'], USE_DEFAULT)
print('SUPERVISOR USER : {}'.format(SUPERVISOR_USER))
else:
DATABASE_HOST = get_input('What is the database host?', defaults['database_host'])
DATABASE_HOST = get_input('What is the database host?', defaults['database_host'], USE_DEFAULT)
print()

if not os.path.isdir(DATABASE_HOST):
DATABASE_PORT = int(get_input('What is the database port?', defaults['database_port']))
DATABASE_PORT = int(get_input('What is the database port?', defaults['database_port'], USE_DEFAULT))
print()
else:
DATABASE_PORT = defaults['database_port']

DATABASE_USER = get_input('What is the global database user/role?', defaults['database_user'])
DATABASE_USER = get_input('What is the global database user/role?', defaults['database_user'], USE_DEFAULT)
print()

default = ''
if 'database_password' in defaults and DATABASE_USER == defaults['database_user']:
default = '(Leave blank to use same password)'
DATABASE_PASS = get_input('What is the password for the global database user/role {}? {}'.format(DATABASE_USER, default))
DATABASE_PASS = get_input('What is the password for the global database user/role {}? {}'.format(DATABASE_USER, default), "", USE_DEFAULT)
if DATABASE_PASS == '' and DATABASE_USER == defaults['database_user'] and 'database_password' in defaults:
DATABASE_PASS = defaults['database_password']
print()

DATABASE_COURSE_USER = get_input('What is the course database user/role?', defaults['database_course_user'])
DATABASE_COURSE_USER = get_input('What is the course database user/role?', defaults['database_course_user'], USE_DEFAULT)
print()

default = ''
if 'database_course_password' in defaults and DATABASE_COURSE_USER == defaults['database_course_user']:
default = '(Leave blank to use same password)'
DATABASE_COURSE_PASSWORD = get_input('What is the password for the course database user/role {}? {}'.format(DATABASE_COURSE_USER, default))
DATABASE_COURSE_PASSWORD = get_input('What is the password for the course database user/role {}? {}'.format(DATABASE_COURSE_USER, default), "", USE_DEFAULT)
if DATABASE_COURSE_PASSWORD == '' and DATABASE_COURSE_USER == defaults['database_course_user'] and 'database_course_password' in defaults:
DATABASE_COURSE_PASSWORD = defaults['database_course_password']
print()

TIMEZONE = get_input('What timezone should Submitty use? (for a full list of supported timezones see http://php.net/manual/en/timezones.php)', defaults['timezone'])
TIMEZONE = get_input('What timezone should Submitty use? (for a full list of supported timezones see http://php.net/manual/en/timezones.php)', defaults['timezone'], USE_DEFAULT)
print()

DEFAULT_LOCALE = get_input('What default language should the Submitty site use?', 'en_US')
DEFAULT_LOCALE = get_input('What default language should the Submitty site use?', 'en_US', USE_DEFAULT)
print()

COURSE_MATERIAL_UPLOAD_LIMIT_MB = get_input('What is the maximum file upload size for course materials (in MB)?', defaults['course_material_file_upload_limit_mb'])
COURSE_MATERIAL_UPLOAD_LIMIT_MB = get_input('What is the maximum file upload size for course materials (in MB)?', defaults['course_material_file_upload_limit_mb'], USE_DEFAULT)
print()

SUBMISSION_URL = get_input('What is the url for submission? (ex: http://192.168.56.101 or '
'https://submitty.cs.rpi.edu)', defaults['submission_url']).rstrip('/')
'https://submitty.cs.rpi.edu)', defaults['submission_url'], USE_DEFAULT).rstrip('/')
print()

VCS_URL = get_input('What is the url for VCS? (Leave blank to default to submission url + {$vcs_type}) (ex: http://192.168.56.101/{$vcs_type} or https://submitty-vcs.cs.rpi.edu/{$vcs_type}', defaults['vcs_url']).rstrip('/')
VCS_URL = get_input('What is the url for VCS? (Leave blank to default to submission url + {$vcs_type}) (ex: http://192.168.56.101/{$vcs_type} or https://submitty-vcs.cs.rpi.edu/{$vcs_type}', defaults['vcs_url'], USE_DEFAULT).rstrip('/')
print()

INSTITUTION_NAME = get_input('What is the name of your institution? (Leave blank/type "none" if not desired)',
defaults['institution_name'])
defaults['institution_name'], USE_DEFAULT)
print()

if INSTITUTION_NAME == '' or INSTITUTION_NAME.isspace():
INSTITUTION_HOMEPAGE = ''
else:
INSTITUTION_HOMEPAGE = get_input("What is the url of your institution\'s homepage? "
'(Leave blank/type "none" if not desired)', defaults['institution_homepage'])
'(Leave blank/type "none" if not desired)', defaults['institution_homepage'], USE_DEFAULT)
if INSTITUTION_HOMEPAGE.lower() == "none":
INSTITUTION_HOMEPAGE = ''
print()

SYS_ADMIN_EMAIL = get_input("What is the email for system administration?", defaults['sys_admin_email'])
SYS_ADMIN_URL = get_input("Where to report problems with Submitty (url for help link)?", defaults['sys_admin_url'])
SYS_ADMIN_EMAIL = get_input("What is the email for system administration?", defaults['sys_admin_email'], USE_DEFAULT)
SYS_ADMIN_URL = get_input("Where to report problems with Submitty (url for help link)?", defaults['sys_admin_url'], USE_DEFAULT)

print('What authentication method to use:')
for i in range(len(authentication_methods)):
print(f"{i + 1}. {authentication_methods[i]}")

while True:
try:
auth = int(get_input('Enter number?', defaults['authentication_method'])) - 1
auth = int(get_input('Enter number?', defaults['authentication_method'], USE_DEFAULT)) - 1
except ValueError:
auth = -1
if auth in range(len(authentication_methods)):
Expand All @@ -341,13 +317,13 @@ def __call__(self, parser, namespace, values, option_string=None):
}
USER_CREATE_ACCOUNT = False
if AUTHENTICATION_METHOD == 'DatabaseAuthentication':
user_create_account = get_input("Allow users to create their own accounts? [y/n]", 'n')
user_create_account = get_input("Allow users to create their own accounts? [y/n]", 'n', USE_DEFAULT)
USER_CREATE_ACCOUNT = user_create_account.lower() in ['yes', 'y']
print()
if AUTHENTICATION_METHOD == 'LdapAuthentication':
LDAP_OPTIONS['url'] = get_input('Enter LDAP url?', LDAP_OPTIONS['url'])
LDAP_OPTIONS['uid'] = get_input('Enter LDAP UID?', LDAP_OPTIONS['uid'])
LDAP_OPTIONS['bind_dn'] = get_input('Enter LDAP bind_dn?', LDAP_OPTIONS['bind_dn'])
LDAP_OPTIONS['url'] = get_input('Enter LDAP url?', LDAP_OPTIONS['url'], USE_DEFAULT)
LDAP_OPTIONS['uid'] = get_input('Enter LDAP UID?', LDAP_OPTIONS['uid'], USE_DEFAULT)
LDAP_OPTIONS['bind_dn'] = get_input('Enter LDAP bind_dn?', LDAP_OPTIONS['bind_dn'], USE_DEFAULT)

default_auth_options = defaults.get('saml_options', dict())
SAML_OPTIONS = {
Expand All @@ -356,28 +332,28 @@ def __call__(self, parser, namespace, values, option_string=None):
}

if AUTHENTICATION_METHOD == 'SamlAuthentication':
SAML_OPTIONS['name'] = get_input('Enter name you would like shown to user for authentication?', SAML_OPTIONS['name'])
SAML_OPTIONS['username_attribute'] = get_input('Enter SAML username attribute?', SAML_OPTIONS['username_attribute'])
SAML_OPTIONS['name'] = get_input('Enter name you would like shown to user for authentication?', SAML_OPTIONS['name'], USE_DEFAULT)
SAML_OPTIONS['username_attribute'] = get_input('Enter SAML username attribute?', SAML_OPTIONS['username_attribute'], USE_DEFAULT)


CGI_URL = SUBMISSION_URL + '/cgi-bin'

SUBMITTY_ADMIN_USERNAME = get_input("What is the submitty admin username (optional)?", defaults['submitty_admin_username'])
SUBMITTY_ADMIN_USERNAME = get_input("What is the submitty admin username (optional)?", defaults['submitty_admin_username'], USE_DEFAULT)

while True:
is_email_enabled = get_input("Will Submitty use email notifications? [y/n]", 'y')
is_email_enabled = get_input("Will Submitty use email notifications? [y/n]", 'y', USE_DEFAULT)
if (is_email_enabled.lower() in ['yes', 'y']):
EMAIL_ENABLED = True
EMAIL_USER = get_input("What is the email user?", defaults['email_user'])
EMAIL_PASSWORD = get_input("What is the email password",defaults['email_password'])
EMAIL_SENDER = get_input("What is the email sender address (the address that will appear in the From: line)?",defaults['email_sender'])
EMAIL_REPLY_TO = get_input("What is the email reply to address?", defaults['email_reply_to'])
EMAIL_SERVER_HOSTNAME = get_input("What is the email server hostname?", defaults['email_server_hostname'])
EMAIL_USER = get_input("What is the email user?", defaults['email_user'], USE_DEFAULT)
EMAIL_PASSWORD = get_input("What is the email password",defaults['email_password'], USE_DEFAULT)
EMAIL_SENDER = get_input("What is the email sender address (the address that will appear in the From: line)?",defaults['email_sender'], USE_DEFAULT)
EMAIL_REPLY_TO = get_input("What is the email reply to address?", defaults['email_reply_to'], USE_DEFAULT)
EMAIL_SERVER_HOSTNAME = get_input("What is the email server hostname?", defaults['email_server_hostname'], USE_DEFAULT)
try:
EMAIL_SERVER_PORT = int(get_input("What is the email server port?", defaults['email_server_port']))
EMAIL_SERVER_PORT = int(get_input("What is the email server port?", defaults['email_server_port'], USE_DEFAULT))
except ValueError:
EMAIL_SERVER_PORT = defaults['email_server_port']
EMAIL_INTERNAL_DOMAIN = get_input("What is the internal email address format?", defaults['email_internal_domain'])
EMAIL_INTERNAL_DOMAIN = get_input("What is the internal email address format?", defaults['email_internal_domain'], USE_DEFAULT)
break

elif (is_email_enabled.lower() in ['no', 'n']):
Expand Down Expand Up @@ -541,7 +517,7 @@ def write(x=''):
if not args.worker:
if not os.path.isfile(WORKERS_JSON):
capabilities = ["default"]
if args.setup_for_sample_courses:
if args.dev_vm:
capabilities.extend(["cpp", "python", "et-cetera", "notebook", "unsupported"])

worker_dict = {
Expand Down
37 changes: 37 additions & 0 deletions .setup/defaults.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"database_host": "/var/run/postgresql",
"database_port": 5432,
"database_user": "submitty_dbuser",
"database_password": "submitty_dbuser",
"database_course_password": "submitty_dbuser",
"database_course_user": "submitty_course_dbuser",
"submission_url": "",
"supervisor_user": "submitty",
"vcs_url": "",
"authentication_method": 1,
"institution_name" : "",
"institution_homepage" : "",
"user_create_account" : false,
"timezone" : "America/New_York",
"submitty_admin_username": "",
"email_user": "",
"email_password": "",
"email_sender": "submitty@myuniversity.edu",
"email_reply_to": "submitty_do_not_reply@myuniversity.edu",
"email_server_hostname": "mail.myuniversity.edu",
"email_server_port": 25,
"email_internal_domain": "example.com",
"course_code_requirements": "Please follow your school's convention for course code.",
"sys_admin_email": "",
"sys_admin_url": "",
"ldap_options": {
"url": "",
"uid": "",
"bind_dn": ""
},
"saml_options": {
"name": "",
"username_attribute": ""
},
"course_material_file_upload_limit_mb": 100
}
24 changes: 1 addition & 23 deletions .setup/install_system.sh
Original file line number Diff line number Diff line change
Expand Up @@ -687,29 +687,7 @@ else
if [ -z "${SUBMISSION_URL}" ]; then
SUBMISSION_URL='http://192.168.56.101'
fi
echo -e "/var/run/postgresql
${DB_USER}
${DATABASE_PASSWORD}
${DB_COURSE_USER}
${DB_COURSE_PASSWORD}
America/New_York
en_US
100
${SUBMISSION_URL}


sysadmin@example.com
https://example.com
1
submitty-admin
y


submitty@vagrant
do-not-reply@vagrant
localhost
25
" | python3 ${SUBMITTY_REPOSITORY}/.setup/CONFIGURE_SUBMITTY.py --debug --setup-for-sample-courses --websocket-port ${WEBSOCKET_PORT}
python3 ${SUBMITTY_REPOSITORY}/.setup/CONFIGURE_SUBMITTY.py --debug --dev-vm --websocket-port ${WEBSOCKET_PORT}

# Set these manually as they're not asked about during CONFIGURE_SUBMITTY.py
sed -i -e 's/"url": ""/"url": "ldap:\/\/localhost"/g' ${SUBMITTY_INSTALL_DIR}/config/authentication.json
Expand Down
27 changes: 1 addition & 26 deletions .setup/testing/setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -47,32 +47,7 @@ chown ${PHP_USER}:${PHP_GROUP} ${SUBMITTY_DATA_DIR}
chmod -R 777 ${SUBMITTY_INSTALL_DIR}
chmod -R 777 ${SUBMITTY_DATA_DIR}

echo -e "localhost
5432
submitty_dbuser
submitty_dbuser
submitty_course_dbuser
submitty_course_dbuser
America/New_York
en_US
100
http://localhost


sysadmin@example.com
https://example.com
2
y


y


submitty@vagrant
do-not-reply@vagrant
localhost
25
" | python3 ${SUBMITTY_REPOSITORY}/.setup/CONFIGURE_SUBMITTY.py --debug --setup-for-sample-courses --install-dir $SUBMITTY_INSTALL_DIR --data-dir $SUBMITTY_DATA_DIR
python3 ${SUBMITTY_REPOSITORY}/.setup/CONFIGURE_SUBMITTY.py --debug --dev-vm --ci --install-dir $SUBMITTY_INSTALL_DIR --data-dir $SUBMITTY_DATA_DIR

bash -c "echo 'export PATH=${PATH}' >> /home/${PHP_USER}/.profile"
bash -c "echo 'export PATH=${PATH}' >> /home/${PHP_USER}/.bashrc"
Expand Down
Loading