2
0
mirror of https://github.com/frappe/bench.git synced 2024-11-14 17:24:04 +00:00
bench/vm/build.py

129 lines
4.1 KiB
Python
Raw Normal View History

2015-12-24 00:25:55 +00:00
"""
Builds a vm and puts it in ~/public with a latest.json that has its filename and md5sum
"""
# imports - standard imports
import os
import json
import stat
2018-03-05 07:46:34 +00:00
import errno
2018-03-31 18:07:40 +00:00
from shutil import rmtree
from distutils import spawn
from subprocess import check_output
2015-12-24 00:25:55 +00:00
2018-03-31 18:07:40 +00:00
NEW_FILES = []
BUILDS = ['Production', 'Developer']
PUBLIC_DIR = os.path.join(os.path.expanduser('~'), 'Public')
SYMLINKS = ['ERPNext-Production.ova', 'ERPNext-Dev.ova', 'ERPNext-Vagrant.box',
'ERPNext-Production.ova.md5', 'ERPNext-Dev.ova.md5', 'ERPNext-Vagrant.box.md5']
2015-12-24 00:25:55 +00:00
def main():
install_virtualbox()
install_packer()
2018-03-31 18:07:40 +00:00
cleanup()
2015-12-24 00:25:55 +00:00
build_vm()
2018-03-31 18:07:40 +00:00
generate_md5_hashes()
generate_symlinks()
delete_old_vms()
move_current_vms()
2015-12-24 00:25:55 +00:00
cleanup()
def install_virtualbox():
2018-03-31 18:07:40 +00:00
if not spawn.find_executable("virtualbox"):
check_output(['bench', 'install', 'virtualbox'])
def install_packer():
2019-06-14 09:44:21 +00:00
if not spawn.find_executable("packer") and not os.path.exists(os.path.join('/', 'opt', 'packer')):
2018-03-31 18:07:40 +00:00
check_output(['bench', 'install', 'packer'])
2018-03-31 18:07:40 +00:00
def silent_remove(name, is_dir=False):
'''
Method to safely remove a file or directory,
without throwing error if file doesn't exist
2018-03-31 18:07:40 +00:00
By default takes in file as input, for directory:
is_dir = True
'''
try:
if is_dir:
rmtree(name)
else:
os.remove(name)
except OSError as e:
if e.errno != errno.ENOENT: # errno.ENOENT = no such file or directory
raise # re-raise exception if a different error occurred
2015-12-24 00:25:55 +00:00
2018-03-31 18:07:40 +00:00
def cleanup():
silent_remove("Production Builds", is_dir=True)
silent_remove("Developer Builds", is_dir=True)
silent_remove("packer_virtualbox-iso_virtualbox-iso_md5.checksum")
2018-03-05 07:46:34 +00:00
2018-03-31 18:07:40 +00:00
def build_vm():
check_output(["packer", "build", "vm-production.json"])
check_output(["packer", "build", "vm-develop.json"])
2018-03-05 07:46:34 +00:00
2018-03-31 18:07:40 +00:00
def md5(build, file):
return check_output("md5sum '{} Builds/{}'".format(build, file), shell=True).split()[0]
def move_to_public(build, file):
NEW_FILES.append(file)
src = os.path.join('{} Builds/{}'.format(build, file))
dest = os.path.join(PUBLIC_DIR, file)
2015-12-24 00:25:55 +00:00
os.rename(src, dest)
2018-03-31 18:07:40 +00:00
# Make Public folder readable by others
2015-12-24 00:25:55 +00:00
st = os.stat(dest)
os.chmod(dest, st.st_mode | stat.S_IROTH)
2018-03-31 18:07:40 +00:00
def generate_md5_hashes():
for build in BUILDS:
for file in os.listdir('{} Builds'.format(build)):
2018-03-31 18:40:31 +00:00
if file.endswith(".ova") or file.endswith(".box"):
2018-03-31 18:07:40 +00:00
with open('{} Builds/{}.md5'.format(build, file), 'w') as f:
f.write(md5(build, file))
move_to_public(build, file)
move_to_public(build, '{}.md5'.format(file))
2015-12-24 00:25:55 +00:00
2018-03-31 18:07:40 +00:00
def generate_symlinks():
for file in NEW_FILES:
if 'md5' in file:
if 'Vagrant' in file:
silent_remove(os.path.join(PUBLIC_DIR, 'ERPNext-Vagrant.box.md5'))
os.symlink(os.path.join(PUBLIC_DIR, file),
os.path.join(PUBLIC_DIR, 'ERPNext-Vagrant.box.md5'))
elif 'Production' in file:
silent_remove(os.path.join(PUBLIC_DIR, 'ERPNext-Production.ova.md5'))
os.symlink(os.path.join(PUBLIC_DIR, file),
os.path.join(PUBLIC_DIR, 'ERPNext-Production.ova.md5'))
else: # Develop
silent_remove(os.path.join(PUBLIC_DIR, 'ERPNext-Dev.ova.md5'))
os.symlink(os.path.join(PUBLIC_DIR, file),
os.path.join(PUBLIC_DIR, 'ERPNext-Dev.ova.md5'))
else: # ova/box files
if 'Vagrant' in file:
silent_remove(os.path.join(PUBLIC_DIR, 'ERPNext-Vagrant.box'))
os.symlink(os.path.join(PUBLIC_DIR, file),
os.path.join(PUBLIC_DIR, 'ERPNext-Vagrant.box'))
elif 'Production' in file:
silent_remove(os.path.join(PUBLIC_DIR, 'ERPNext-Production.ova'))
os.symlink(os.path.join(PUBLIC_DIR, file),
os.path.join(PUBLIC_DIR, 'ERPNext-Production.ova'))
else: # Develop
silent_remove(os.path.join(PUBLIC_DIR, 'ERPNext-Dev.ova'))
os.symlink(os.path.join(PUBLIC_DIR, file),
os.path.join(PUBLIC_DIR, 'ERPNext-Dev.ova'))
2015-12-24 00:25:55 +00:00
2018-03-31 18:07:40 +00:00
def delete_old_vms():
silent_remove(os.path.join(PUBLIC_DIR, 'BACKUPS'), is_dir=True)
2015-12-24 00:25:55 +00:00
2018-03-31 18:07:40 +00:00
def move_current_vms():
os.mkdir(os.path.join(PUBLIC_DIR, 'BACKUPS'))
2018-03-31 18:07:40 +00:00
for file in os.listdir(PUBLIC_DIR):
2018-03-31 18:40:31 +00:00
if file in NEW_FILES or file in SYMLINKS or file == 'BACKUPS':
2018-03-31 18:07:40 +00:00
continue
src = os.path.join(PUBLIC_DIR, '{}'.format(file))
2018-03-31 18:40:31 +00:00
dest = os.path.join(PUBLIC_DIR, 'BACKUPS/{}'.format(file))
2018-03-31 18:07:40 +00:00
os.rename(src, dest)
2015-12-24 00:25:55 +00:00
if __name__ == "__main__":
main()