diff --git a/.gitignore b/.gitignore index 9a6f3b3..bc6e8fd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,118 +1,119 @@ -# Python compiled files -*.pyc -*.pyo -__pycache__/ -*.pyd - -# Virtual environments -venv/ -.env/ -.envrc -.Python -*.env - -# Django stuff -db.sqlite3 -*.sqlite3 -media/ -staticfiles/ - -# Logs -*.log -*.pot -*.py[cod] -*.pyd -*.sqlite3-shm -*.sqlite3-wal -*.cover -*.log - -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] -*$py.class - -# C extensions -*.so - -# Distribution / packaging -.Python -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -wheels/ -*.egg-info/ -.installed.cfg -*.egg -MANIFEST - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Django stuff: -*.pot -*.py[cod] -*.sqlite3 -/media -/static -/staticfiles - -# Coverage reports -htmlcov/ -.tox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*.cover -.hypothesis/ - -# Pytest -.cache/ -.pytest_cache/ - -# Jupyter Notebook -.ipynb_checkpoints - -# IDE files -.idea/ -.vscode/ -*.swp -*~ - -# macOS system files -.DS_Store - -# Windows thumbnail cache files -Thumbs.db -ehthumbs.db - -# pyenv -.python-version - -# Celery -celerybeat-schedule - -# Sphinx documentation -docs/_build/ - -# PyBuilder -target/ - -# Django migrations -*.log -*.pot -migrations/ - -# Local.env -*.env +# Python compiled files +*.pyc +*.pyo +__pycache__/ +*.pyd + +# Virtual environments +venv/ +.venv/ +.env/ +.envrc +.Python +*.env + +# Django stuff +db.sqlite3 +*.sqlite3 +media/ +staticfiles/ + +# Logs +*.log +*.pot +*.py[cod] +*.pyd +*.sqlite3-shm +*.sqlite3-wal +*.cover +*.log + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Django stuff: +*.pot +*.py[cod] +*.sqlite3 +/media +/static +/staticfiles + +# Coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ + +# Pytest +.cache/ +.pytest_cache/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IDE files +.idea/ +.vscode/ +*.swp +*~ + +# macOS system files +.DS_Store + +# Windows thumbnail cache files +Thumbs.db +ehthumbs.db + +# pyenv +.python-version + +# Celery +celerybeat-schedule + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Django migrations +*.log +*.pot +migrations/ + +# Local.env +*.env diff --git a/LICENSE b/LICENSE index 0dde1b9..99e7154 100644 --- a/LICENSE +++ b/LICENSE @@ -1,21 +1,21 @@ -MIT License - -Copyright (c) 2024 Apoorva Agrawal - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +MIT License + +Copyright (c) 2024 Apoorva Agrawal + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 3fca6e3..4ebcad1 100644 --- a/README.md +++ b/README.md @@ -1,8 +1 @@ -This is a repository for the ContainerOps project which aims to make a Universal Continuous Deployment Tool with Automated Containerization - - -Setup: -- navigate into the buildServer directory. -- activate the virtual environment (named .venv) -- Install the requirements using: pip install -r requirements.txt -- start the server: python manage.py runserver +This is a repository for the ContainerOps project which aims to make a Universal Continuous Deployment Tool with Automated Containerization diff --git a/buildServer/.venv-build/bin/Activate.ps1 b/buildServer/.venv-build/bin/Activate.ps1 new file mode 100644 index 0000000..b49d77b --- /dev/null +++ b/buildServer/.venv-build/bin/Activate.ps1 @@ -0,0 +1,247 @@ +<# +.Synopsis +Activate a Python virtual environment for the current PowerShell session. + +.Description +Pushes the python executable for a virtual environment to the front of the +$Env:PATH environment variable and sets the prompt to signify that you are +in a Python virtual environment. Makes use of the command line switches as +well as the `pyvenv.cfg` file values present in the virtual environment. + +.Parameter VenvDir +Path to the directory that contains the virtual environment to activate. The +default value for this is the parent of the directory that the Activate.ps1 +script is located within. + +.Parameter Prompt +The prompt prefix to display when this virtual environment is activated. By +default, this prompt is the name of the virtual environment folder (VenvDir) +surrounded by parentheses and followed by a single space (ie. '(.venv) '). + +.Example +Activate.ps1 +Activates the Python virtual environment that contains the Activate.ps1 script. + +.Example +Activate.ps1 -Verbose +Activates the Python virtual environment that contains the Activate.ps1 script, +and shows extra information about the activation as it executes. + +.Example +Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv +Activates the Python virtual environment located in the specified location. + +.Example +Activate.ps1 -Prompt "MyPython" +Activates the Python virtual environment that contains the Activate.ps1 script, +and prefixes the current prompt with the specified string (surrounded in +parentheses) while the virtual environment is active. + +.Notes +On Windows, it may be required to enable this Activate.ps1 script by setting the +execution policy for the user. You can do this by issuing the following PowerShell +command: + +PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser + +For more information on Execution Policies: +https://go.microsoft.com/fwlink/?LinkID=135170 + +#> +Param( + [Parameter(Mandatory = $false)] + [String] + $VenvDir, + [Parameter(Mandatory = $false)] + [String] + $Prompt +) + +<# Function declarations --------------------------------------------------- #> + +<# +.Synopsis +Remove all shell session elements added by the Activate script, including the +addition of the virtual environment's Python executable from the beginning of +the PATH variable. + +.Parameter NonDestructive +If present, do not remove this function from the global namespace for the +session. + +#> +function global:deactivate ([switch]$NonDestructive) { + # Revert to original values + + # The prior prompt: + if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) { + Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt + Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT + } + + # The prior PYTHONHOME: + if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) { + Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME + Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME + } + + # The prior PATH: + if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) { + Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH + Remove-Item -Path Env:_OLD_VIRTUAL_PATH + } + + # Just remove the VIRTUAL_ENV altogether: + if (Test-Path -Path Env:VIRTUAL_ENV) { + Remove-Item -Path env:VIRTUAL_ENV + } + + # Just remove VIRTUAL_ENV_PROMPT altogether. + if (Test-Path -Path Env:VIRTUAL_ENV_PROMPT) { + Remove-Item -Path env:VIRTUAL_ENV_PROMPT + } + + # Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether: + if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) { + Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force + } + + # Leave deactivate function in the global namespace if requested: + if (-not $NonDestructive) { + Remove-Item -Path function:deactivate + } +} + +<# +.Description +Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the +given folder, and returns them in a map. + +For each line in the pyvenv.cfg file, if that line can be parsed into exactly +two strings separated by `=` (with any amount of whitespace surrounding the =) +then it is considered a `key = value` line. The left hand string is the key, +the right hand is the value. + +If the value starts with a `'` or a `"` then the first and last character is +stripped from the value before being captured. + +.Parameter ConfigDir +Path to the directory that contains the `pyvenv.cfg` file. +#> +function Get-PyVenvConfig( + [String] + $ConfigDir +) { + Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg" + + # Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue). + $pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue + + # An empty map will be returned if no config file is found. + $pyvenvConfig = @{ } + + if ($pyvenvConfigPath) { + + Write-Verbose "File exists, parse `key = value` lines" + $pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath + + $pyvenvConfigContent | ForEach-Object { + $keyval = $PSItem -split "\s*=\s*", 2 + if ($keyval[0] -and $keyval[1]) { + $val = $keyval[1] + + # Remove extraneous quotations around a string value. + if ("'""".Contains($val.Substring(0, 1))) { + $val = $val.Substring(1, $val.Length - 2) + } + + $pyvenvConfig[$keyval[0]] = $val + Write-Verbose "Adding Key: '$($keyval[0])'='$val'" + } + } + } + return $pyvenvConfig +} + + +<# Begin Activate script --------------------------------------------------- #> + +# Determine the containing directory of this script +$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition +$VenvExecDir = Get-Item -Path $VenvExecPath + +Write-Verbose "Activation script is located in path: '$VenvExecPath'" +Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)" +Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)" + +# Set values required in priority: CmdLine, ConfigFile, Default +# First, get the location of the virtual environment, it might not be +# VenvExecDir if specified on the command line. +if ($VenvDir) { + Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values" +} +else { + Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir." + $VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/") + Write-Verbose "VenvDir=$VenvDir" +} + +# Next, read the `pyvenv.cfg` file to determine any required value such +# as `prompt`. +$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir + +# Next, set the prompt from the command line, or the config file, or +# just use the name of the virtual environment folder. +if ($Prompt) { + Write-Verbose "Prompt specified as argument, using '$Prompt'" +} +else { + Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value" + if ($pyvenvCfg -and $pyvenvCfg['prompt']) { + Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'" + $Prompt = $pyvenvCfg['prompt']; + } + else { + Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virtual environment)" + Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'" + $Prompt = Split-Path -Path $venvDir -Leaf + } +} + +Write-Verbose "Prompt = '$Prompt'" +Write-Verbose "VenvDir='$VenvDir'" + +# Deactivate any currently active virtual environment, but leave the +# deactivate function in place. +deactivate -nondestructive + +# Now set the environment variable VIRTUAL_ENV, used by many tools to determine +# that there is an activated venv. +$env:VIRTUAL_ENV = $VenvDir + +if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) { + + Write-Verbose "Setting prompt to '$Prompt'" + + # Set the prompt to include the env name + # Make sure _OLD_VIRTUAL_PROMPT is global + function global:_OLD_VIRTUAL_PROMPT { "" } + Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT + New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt + + function global:prompt { + Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) " + _OLD_VIRTUAL_PROMPT + } + $env:VIRTUAL_ENV_PROMPT = $Prompt +} + +# Clear PYTHONHOME +if (Test-Path -Path Env:PYTHONHOME) { + Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME + Remove-Item -Path Env:PYTHONHOME +} + +# Add the venv to the PATH +Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH +$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH" diff --git a/buildServer/.venv-build/bin/activate b/buildServer/.venv-build/bin/activate new file mode 100644 index 0000000..bab4279 --- /dev/null +++ b/buildServer/.venv-build/bin/activate @@ -0,0 +1,70 @@ +# This file must be used with "source bin/activate" *from bash* +# You cannot run it directly + +deactivate () { + # reset old environment variables + if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then + PATH="${_OLD_VIRTUAL_PATH:-}" + export PATH + unset _OLD_VIRTUAL_PATH + fi + if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then + PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}" + export PYTHONHOME + unset _OLD_VIRTUAL_PYTHONHOME + fi + + # Call hash to forget past commands. Without forgetting + # past commands the $PATH changes we made may not be respected + hash -r 2> /dev/null + + if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then + PS1="${_OLD_VIRTUAL_PS1:-}" + export PS1 + unset _OLD_VIRTUAL_PS1 + fi + + unset VIRTUAL_ENV + unset VIRTUAL_ENV_PROMPT + if [ ! "${1:-}" = "nondestructive" ] ; then + # Self destruct! + unset -f deactivate + fi +} + +# unset irrelevant variables +deactivate nondestructive + +# on Windows, a path can contain colons and backslashes and has to be converted: +if [ "${OSTYPE:-}" = "cygwin" ] || [ "${OSTYPE:-}" = "msys" ] ; then + # transform D:\path\to\venv to /d/path/to/venv on MSYS + # and to /cygdrive/d/path/to/venv on Cygwin + export VIRTUAL_ENV=$(cygpath /home/varshini-adurti/ContainerOps/buildServer/.venv-build) +else + # use the path as-is + export VIRTUAL_ENV=/home/varshini-adurti/ContainerOps/buildServer/.venv-build +fi + +_OLD_VIRTUAL_PATH="$PATH" +PATH="$VIRTUAL_ENV/"bin":$PATH" +export PATH + +# unset PYTHONHOME if set +# this will fail if PYTHONHOME is set to the empty string (which is bad anyway) +# could use `if (set -u; : $PYTHONHOME) ;` in bash +if [ -n "${PYTHONHOME:-}" ] ; then + _OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}" + unset PYTHONHOME +fi + +if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then + _OLD_VIRTUAL_PS1="${PS1:-}" + PS1='(.venv-build) '"${PS1:-}" + export PS1 + VIRTUAL_ENV_PROMPT='(.venv-build) ' + export VIRTUAL_ENV_PROMPT +fi + +# Call hash to forget past commands. Without forgetting +# past commands the $PATH changes we made may not be respected +hash -r 2> /dev/null diff --git a/buildServer/.venv-build/bin/activate.csh b/buildServer/.venv-build/bin/activate.csh new file mode 100644 index 0000000..d03adc9 --- /dev/null +++ b/buildServer/.venv-build/bin/activate.csh @@ -0,0 +1,27 @@ +# This file must be used with "source bin/activate.csh" *from csh*. +# You cannot run it directly. + +# Created by Davide Di Blasi . +# Ported to Python 3.3 venv by Andrew Svetlov + +alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; unsetenv VIRTUAL_ENV_PROMPT; test "\!:*" != "nondestructive" && unalias deactivate' + +# Unset irrelevant variables. +deactivate nondestructive + +setenv VIRTUAL_ENV /home/varshini-adurti/ContainerOps/buildServer/.venv-build + +set _OLD_VIRTUAL_PATH="$PATH" +setenv PATH "$VIRTUAL_ENV/"bin":$PATH" + + +set _OLD_VIRTUAL_PROMPT="$prompt" + +if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then + set prompt = '(.venv-build) '"$prompt" + setenv VIRTUAL_ENV_PROMPT '(.venv-build) ' +endif + +alias pydoc python -m pydoc + +rehash diff --git a/buildServer/.venv-build/bin/activate.fish b/buildServer/.venv-build/bin/activate.fish new file mode 100644 index 0000000..3a093b9 --- /dev/null +++ b/buildServer/.venv-build/bin/activate.fish @@ -0,0 +1,69 @@ +# This file must be used with "source /bin/activate.fish" *from fish* +# (https://fishshell.com/). You cannot run it directly. + +function deactivate -d "Exit virtual environment and return to normal shell environment" + # reset old environment variables + if test -n "$_OLD_VIRTUAL_PATH" + set -gx PATH $_OLD_VIRTUAL_PATH + set -e _OLD_VIRTUAL_PATH + end + if test -n "$_OLD_VIRTUAL_PYTHONHOME" + set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME + set -e _OLD_VIRTUAL_PYTHONHOME + end + + if test -n "$_OLD_FISH_PROMPT_OVERRIDE" + set -e _OLD_FISH_PROMPT_OVERRIDE + # prevents error when using nested fish instances (Issue #93858) + if functions -q _old_fish_prompt + functions -e fish_prompt + functions -c _old_fish_prompt fish_prompt + functions -e _old_fish_prompt + end + end + + set -e VIRTUAL_ENV + set -e VIRTUAL_ENV_PROMPT + if test "$argv[1]" != "nondestructive" + # Self-destruct! + functions -e deactivate + end +end + +# Unset irrelevant variables. +deactivate nondestructive + +set -gx VIRTUAL_ENV /home/varshini-adurti/ContainerOps/buildServer/.venv-build + +set -gx _OLD_VIRTUAL_PATH $PATH +set -gx PATH "$VIRTUAL_ENV/"bin $PATH + +# Unset PYTHONHOME if set. +if set -q PYTHONHOME + set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME + set -e PYTHONHOME +end + +if test -z "$VIRTUAL_ENV_DISABLE_PROMPT" + # fish uses a function instead of an env var to generate the prompt. + + # Save the current fish_prompt function as the function _old_fish_prompt. + functions -c fish_prompt _old_fish_prompt + + # With the original prompt function renamed, we can override with our own. + function fish_prompt + # Save the return status of the last command. + set -l old_status $status + + # Output the venv prompt; color taken from the blue of the Python logo. + printf "%s%s%s" (set_color 4B8BBE) '(.venv-build) ' (set_color normal) + + # Restore the return status of the previous command. + echo "exit $old_status" | . + # Output the original/"old" prompt. + _old_fish_prompt + end + + set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV" + set -gx VIRTUAL_ENV_PROMPT '(.venv-build) ' +end diff --git a/buildServer/.venv-build/bin/automat-visualize b/buildServer/.venv-build/bin/automat-visualize new file mode 100644 index 0000000..931f264 --- /dev/null +++ b/buildServer/.venv-build/bin/automat-visualize @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from automat._visualize import tool +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(tool()) diff --git a/buildServer/.venv-build/bin/cftp b/buildServer/.venv-build/bin/cftp new file mode 100644 index 0000000..3e59fcc --- /dev/null +++ b/buildServer/.venv-build/bin/cftp @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from twisted.conch.scripts.cftp import run +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(run()) diff --git a/buildServer/.venv-build/bin/ckeygen b/buildServer/.venv-build/bin/ckeygen new file mode 100644 index 0000000..5ffbc26 --- /dev/null +++ b/buildServer/.venv-build/bin/ckeygen @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from twisted.conch.scripts.ckeygen import run +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(run()) diff --git a/buildServer/.venv-build/bin/conch b/buildServer/.venv-build/bin/conch new file mode 100644 index 0000000..7c97adb --- /dev/null +++ b/buildServer/.venv-build/bin/conch @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from twisted.conch.scripts.conch import run +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(run()) diff --git a/buildServer/.venv-build/bin/daphne b/buildServer/.venv-build/bin/daphne new file mode 100644 index 0000000..d59f7fa --- /dev/null +++ b/buildServer/.venv-build/bin/daphne @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from daphne.cli import CommandLineInterface +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(CommandLineInterface.entrypoint()) diff --git a/buildServer/.venv-build/bin/django-admin b/buildServer/.venv-build/bin/django-admin new file mode 100644 index 0000000..6d4e838 --- /dev/null +++ b/buildServer/.venv-build/bin/django-admin @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from django.core.management import execute_from_command_line +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(execute_from_command_line()) diff --git a/buildServer/.venv-build/bin/dotenv b/buildServer/.venv-build/bin/dotenv new file mode 100644 index 0000000..91e4ca1 --- /dev/null +++ b/buildServer/.venv-build/bin/dotenv @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from dotenv.__main__ import cli +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(cli()) diff --git a/buildServer/.venv-build/bin/httpx b/buildServer/.venv-build/bin/httpx new file mode 100644 index 0000000..0f8c311 --- /dev/null +++ b/buildServer/.venv-build/bin/httpx @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from httpx import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/buildServer/.venv-build/bin/jp.py b/buildServer/.venv-build/bin/jp.py new file mode 100644 index 0000000..673923e --- /dev/null +++ b/buildServer/.venv-build/bin/jp.py @@ -0,0 +1,54 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 + +import sys +import json +import argparse +from pprint import pformat + +import jmespath +from jmespath import exceptions + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('expression') + parser.add_argument('-f', '--filename', + help=('The filename containing the input data. ' + 'If a filename is not given then data is ' + 'read from stdin.')) + parser.add_argument('--ast', action='store_true', + help=('Pretty print the AST, do not search the data.')) + args = parser.parse_args() + expression = args.expression + if args.ast: + # Only print the AST + expression = jmespath.compile(args.expression) + sys.stdout.write(pformat(expression.parsed)) + sys.stdout.write('\n') + return 0 + if args.filename: + with open(args.filename, 'r') as f: + data = json.load(f) + else: + data = sys.stdin.read() + data = json.loads(data) + try: + sys.stdout.write(json.dumps( + jmespath.search(expression, data), indent=4, ensure_ascii=False)) + sys.stdout.write('\n') + except exceptions.ArityError as e: + sys.stderr.write("invalid-arity: %s\n" % e) + return 1 + except exceptions.JMESPathTypeError as e: + sys.stderr.write("invalid-type: %s\n" % e) + return 1 + except exceptions.UnknownFunctionError as e: + sys.stderr.write("unknown-function: %s\n" % e) + return 1 + except exceptions.ParseError as e: + sys.stderr.write("syntax-error: %s\n" % e) + return 1 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/buildServer/.venv-build/bin/mailmail b/buildServer/.venv-build/bin/mailmail new file mode 100644 index 0000000..f257090 --- /dev/null +++ b/buildServer/.venv-build/bin/mailmail @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from twisted.mail.scripts.mailmail import run +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(run()) diff --git a/buildServer/.venv-build/bin/ngrok b/buildServer/.venv-build/bin/ngrok new file mode 100644 index 0000000..9810c0c --- /dev/null +++ b/buildServer/.venv-build/bin/ngrok @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pyngrok.ngrok import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/buildServer/.venv-build/bin/ngrok-asgi b/buildServer/.venv-build/bin/ngrok-asgi new file mode 100644 index 0000000..5b9b5b9 --- /dev/null +++ b/buildServer/.venv-build/bin/ngrok-asgi @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from ngrok import __main__ +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(__main__.asgi_cli()) diff --git a/buildServer/.venv-build/bin/normalizer b/buildServer/.venv-build/bin/normalizer new file mode 100644 index 0000000..6bf09cd --- /dev/null +++ b/buildServer/.venv-build/bin/normalizer @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from charset_normalizer.cli import cli_detect +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(cli_detect()) diff --git a/buildServer/.venv-build/bin/pip b/buildServer/.venv-build/bin/pip new file mode 100644 index 0000000..b004025 --- /dev/null +++ b/buildServer/.venv-build/bin/pip @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/buildServer/.venv-build/bin/pip3 b/buildServer/.venv-build/bin/pip3 new file mode 100644 index 0000000..b004025 --- /dev/null +++ b/buildServer/.venv-build/bin/pip3 @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/buildServer/.venv-build/bin/pip3.12 b/buildServer/.venv-build/bin/pip3.12 new file mode 100644 index 0000000..b004025 --- /dev/null +++ b/buildServer/.venv-build/bin/pip3.12 @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/buildServer/.venv-build/bin/pyhtmlizer b/buildServer/.venv-build/bin/pyhtmlizer new file mode 100644 index 0000000..a2d597b --- /dev/null +++ b/buildServer/.venv-build/bin/pyhtmlizer @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from twisted.scripts.htmlizer import run +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(run()) diff --git a/buildServer/.venv-build/bin/pyngrok b/buildServer/.venv-build/bin/pyngrok new file mode 100644 index 0000000..9810c0c --- /dev/null +++ b/buildServer/.venv-build/bin/pyngrok @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pyngrok.ngrok import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/buildServer/.venv-build/bin/pyrsa-decrypt b/buildServer/.venv-build/bin/pyrsa-decrypt new file mode 100644 index 0000000..94895ae --- /dev/null +++ b/buildServer/.venv-build/bin/pyrsa-decrypt @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from rsa.cli import decrypt +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(decrypt()) diff --git a/buildServer/.venv-build/bin/pyrsa-encrypt b/buildServer/.venv-build/bin/pyrsa-encrypt new file mode 100644 index 0000000..14a73dd --- /dev/null +++ b/buildServer/.venv-build/bin/pyrsa-encrypt @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from rsa.cli import encrypt +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(encrypt()) diff --git a/buildServer/.venv-build/bin/pyrsa-keygen b/buildServer/.venv-build/bin/pyrsa-keygen new file mode 100644 index 0000000..1672c5e --- /dev/null +++ b/buildServer/.venv-build/bin/pyrsa-keygen @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from rsa.cli import keygen +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(keygen()) diff --git a/buildServer/.venv-build/bin/pyrsa-priv2pub b/buildServer/.venv-build/bin/pyrsa-priv2pub new file mode 100644 index 0000000..95569ac --- /dev/null +++ b/buildServer/.venv-build/bin/pyrsa-priv2pub @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from rsa.util import private_to_public +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(private_to_public()) diff --git a/buildServer/.venv-build/bin/pyrsa-sign b/buildServer/.venv-build/bin/pyrsa-sign new file mode 100644 index 0000000..e0d5dd3 --- /dev/null +++ b/buildServer/.venv-build/bin/pyrsa-sign @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from rsa.cli import sign +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(sign()) diff --git a/buildServer/.venv-build/bin/pyrsa-verify b/buildServer/.venv-build/bin/pyrsa-verify new file mode 100644 index 0000000..60ceac2 --- /dev/null +++ b/buildServer/.venv-build/bin/pyrsa-verify @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from rsa.cli import verify +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(verify()) diff --git a/buildServer/.venv-build/bin/python b/buildServer/.venv-build/bin/python new file mode 120000 index 0000000..b8a0adb --- /dev/null +++ b/buildServer/.venv-build/bin/python @@ -0,0 +1 @@ +python3 \ No newline at end of file diff --git a/buildServer/.venv-build/bin/python3 b/buildServer/.venv-build/bin/python3 new file mode 120000 index 0000000..ae65fda --- /dev/null +++ b/buildServer/.venv-build/bin/python3 @@ -0,0 +1 @@ +/usr/bin/python3 \ No newline at end of file diff --git a/buildServer/.venv-build/bin/python3.12 b/buildServer/.venv-build/bin/python3.12 new file mode 120000 index 0000000..b8a0adb --- /dev/null +++ b/buildServer/.venv-build/bin/python3.12 @@ -0,0 +1 @@ +python3 \ No newline at end of file diff --git a/buildServer/.venv-build/bin/rst2html.py b/buildServer/.venv-build/bin/rst2html.py new file mode 100644 index 0000000..e4a149f --- /dev/null +++ b/buildServer/.venv-build/bin/rst2html.py @@ -0,0 +1,23 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 + +# $Id: rst2html.py 4564 2006-05-21 20:44:42Z wiemann $ +# Author: David Goodger +# Copyright: This module has been placed in the public domain. + +""" +A minimal front end to the Docutils Publisher, producing HTML. +""" + +try: + import locale + locale.setlocale(locale.LC_ALL, '') +except: + pass + +from docutils.core import publish_cmdline, default_description + + +description = ('Generates (X)HTML documents from standalone reStructuredText ' + 'sources. ' + default_description) + +publish_cmdline(writer_name='html', description=description) diff --git a/buildServer/.venv-build/bin/rst2html4.py b/buildServer/.venv-build/bin/rst2html4.py new file mode 100644 index 0000000..1e73534 --- /dev/null +++ b/buildServer/.venv-build/bin/rst2html4.py @@ -0,0 +1,26 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 + +# $Id: rst2html4.py 7994 2016-12-10 17:41:45Z milde $ +# Author: David Goodger +# Copyright: This module has been placed in the public domain. + +""" +A minimal front end to the Docutils Publisher, producing (X)HTML. + +The output conforms to XHTML 1.0 transitional +and almost to HTML 4.01 transitional (except for closing empty tags). +""" + +try: + import locale + locale.setlocale(locale.LC_ALL, '') +except: + pass + +from docutils.core import publish_cmdline, default_description + + +description = ('Generates (X)HTML documents from standalone reStructuredText ' + 'sources. ' + default_description) + +publish_cmdline(writer_name='html4', description=description) diff --git a/buildServer/.venv-build/bin/rst2html5.py b/buildServer/.venv-build/bin/rst2html5.py new file mode 100644 index 0000000..ec5b5e6 --- /dev/null +++ b/buildServer/.venv-build/bin/rst2html5.py @@ -0,0 +1,35 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 +# -*- coding: utf8 -*- +# :Copyright: © 2015 Günter Milde. +# :License: Released under the terms of the `2-Clause BSD license`_, in short: +# +# Copying and distribution of this file, with or without modification, +# are permitted in any medium without royalty provided the copyright +# notice and this notice are preserved. +# This file is offered as-is, without any warranty. +# +# .. _2-Clause BSD license: http://www.spdx.org/licenses/BSD-2-Clause +# +# Revision: $Revision: 8410 $ +# Date: $Date: 2019-11-04 22:14:43 +0100 (Mo, 04. Nov 2019) $ + +""" +A minimal front end to the Docutils Publisher, producing HTML 5 documents. + +The output also conforms to XHTML 1.0 transitional +(except for the doctype declaration). +""" + +try: + import locale # module missing in Jython + locale.setlocale(locale.LC_ALL, '') +except locale.Error: + pass + +from docutils.core import publish_cmdline, default_description + +description = (u'Generates HTML 5 documents from standalone ' + u'reStructuredText sources ' + + default_description) + +publish_cmdline(writer_name='html5', description=description) diff --git a/buildServer/.venv-build/bin/rst2latex.py b/buildServer/.venv-build/bin/rst2latex.py new file mode 100644 index 0000000..26bf92d --- /dev/null +++ b/buildServer/.venv-build/bin/rst2latex.py @@ -0,0 +1,26 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 + +# $Id: rst2latex.py 5905 2009-04-16 12:04:49Z milde $ +# Author: David Goodger +# Copyright: This module has been placed in the public domain. + +""" +A minimal front end to the Docutils Publisher, producing LaTeX. +""" + +try: + import locale + locale.setlocale(locale.LC_ALL, '') +except: + pass + +from docutils.core import publish_cmdline + +description = ('Generates LaTeX documents from standalone reStructuredText ' + 'sources. ' + 'Reads from (default is stdin) and writes to ' + ' (default is stdout). See ' + ' for ' + 'the full reference.') + +publish_cmdline(writer_name='latex', description=description) diff --git a/buildServer/.venv-build/bin/rst2man.py b/buildServer/.venv-build/bin/rst2man.py new file mode 100644 index 0000000..b0533a8 --- /dev/null +++ b/buildServer/.venv-build/bin/rst2man.py @@ -0,0 +1,26 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 + +# Author: +# Contact: grubert@users.sf.net +# Copyright: This module has been placed in the public domain. + +""" +man.py +====== + +This module provides a simple command line interface that uses the +man page writer to output from ReStructuredText source. +""" + +import locale +try: + locale.setlocale(locale.LC_ALL, '') +except: + pass + +from docutils.core import publish_cmdline, default_description +from docutils.writers import manpage + +description = ("Generates plain unix manual documents. " + default_description) + +publish_cmdline(writer=manpage.Writer(), description=description) diff --git a/buildServer/.venv-build/bin/rst2odt.py b/buildServer/.venv-build/bin/rst2odt.py new file mode 100644 index 0000000..072a701 --- /dev/null +++ b/buildServer/.venv-build/bin/rst2odt.py @@ -0,0 +1,30 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 + +# $Id: rst2odt.py 5839 2009-01-07 19:09:28Z dkuhlman $ +# Author: Dave Kuhlman +# Copyright: This module has been placed in the public domain. + +""" +A front end to the Docutils Publisher, producing OpenOffice documents. +""" + +import sys +try: + import locale + locale.setlocale(locale.LC_ALL, '') +except: + pass + +from docutils.core import publish_cmdline_to_binary, default_description +from docutils.writers.odf_odt import Writer, Reader + + +description = ('Generates OpenDocument/OpenOffice/ODF documents from ' + 'standalone reStructuredText sources. ' + default_description) + + +writer = Writer() +reader = Reader() +output = publish_cmdline_to_binary(reader=reader, writer=writer, + description=description) + diff --git a/buildServer/.venv-build/bin/rst2odt_prepstyles.py b/buildServer/.venv-build/bin/rst2odt_prepstyles.py new file mode 100644 index 0000000..901267d --- /dev/null +++ b/buildServer/.venv-build/bin/rst2odt_prepstyles.py @@ -0,0 +1,67 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 + +# $Id: rst2odt_prepstyles.py 8346 2019-08-26 12:11:32Z milde $ +# Author: Dave Kuhlman +# Copyright: This module has been placed in the public domain. + +""" +Fix a word-processor-generated styles.odt for odtwriter use: Drop page size +specifications from styles.xml in STYLE_FILE.odt. +""" + +# Author: Michael Schutte + +from __future__ import print_function + +from lxml import etree +import sys +import zipfile +from tempfile import mkstemp +import shutil +import os + +NAMESPACES = { + "style": "urn:oasis:names:tc:opendocument:xmlns:style:1.0", + "fo": "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" +} + + +def prepstyle(filename): + + zin = zipfile.ZipFile(filename) + styles = zin.read("styles.xml") + + root = etree.fromstring(styles) + for el in root.xpath("//style:page-layout-properties", + namespaces=NAMESPACES): + for attr in el.attrib: + if attr.startswith("{%s}" % NAMESPACES["fo"]): + del el.attrib[attr] + + tempname = mkstemp() + zout = zipfile.ZipFile(os.fdopen(tempname[0], "w"), "w", + zipfile.ZIP_DEFLATED) + + for item in zin.infolist(): + if item.filename == "styles.xml": + zout.writestr(item, etree.tostring(root)) + else: + zout.writestr(item, zin.read(item.filename)) + + zout.close() + zin.close() + shutil.move(tempname[1], filename) + + +def main(): + args = sys.argv[1:] + if len(args) != 1: + print(__doc__, file=sys.stderr) + print("Usage: %s STYLE_FILE.odt\n" % sys.argv[0], file=sys.stderr) + sys.exit(1) + filename = args[0] + prepstyle(filename) + + +if __name__ == '__main__': + main() diff --git a/buildServer/.venv-build/bin/rst2pseudoxml.py b/buildServer/.venv-build/bin/rst2pseudoxml.py new file mode 100644 index 0000000..fd1bad1 --- /dev/null +++ b/buildServer/.venv-build/bin/rst2pseudoxml.py @@ -0,0 +1,23 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 + +# $Id: rst2pseudoxml.py 4564 2006-05-21 20:44:42Z wiemann $ +# Author: David Goodger +# Copyright: This module has been placed in the public domain. + +""" +A minimal front end to the Docutils Publisher, producing pseudo-XML. +""" + +try: + import locale + locale.setlocale(locale.LC_ALL, '') +except: + pass + +from docutils.core import publish_cmdline, default_description + + +description = ('Generates pseudo-XML from standalone reStructuredText ' + 'sources (for testing purposes). ' + default_description) + +publish_cmdline(description=description) diff --git a/buildServer/.venv-build/bin/rst2s5.py b/buildServer/.venv-build/bin/rst2s5.py new file mode 100644 index 0000000..0e32cd2 --- /dev/null +++ b/buildServer/.venv-build/bin/rst2s5.py @@ -0,0 +1,24 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 + +# $Id: rst2s5.py 4564 2006-05-21 20:44:42Z wiemann $ +# Author: Chris Liechti +# Copyright: This module has been placed in the public domain. + +""" +A minimal front end to the Docutils Publisher, producing HTML slides using +the S5 template system. +""" + +try: + import locale + locale.setlocale(locale.LC_ALL, '') +except: + pass + +from docutils.core import publish_cmdline, default_description + + +description = ('Generates S5 (X)HTML slideshow documents from standalone ' + 'reStructuredText sources. ' + default_description) + +publish_cmdline(writer_name='s5', description=description) diff --git a/buildServer/.venv-build/bin/rst2xetex.py b/buildServer/.venv-build/bin/rst2xetex.py new file mode 100644 index 0000000..2deb76c --- /dev/null +++ b/buildServer/.venv-build/bin/rst2xetex.py @@ -0,0 +1,27 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 + +# $Id: rst2xetex.py 7847 2015-03-17 17:30:47Z milde $ +# Author: Guenter Milde +# Copyright: This module has been placed in the public domain. + +""" +A minimal front end to the Docutils Publisher, producing Lua/XeLaTeX code. +""" + +try: + import locale + locale.setlocale(locale.LC_ALL, '') +except: + pass + +from docutils.core import publish_cmdline + +description = ('Generates LaTeX documents from standalone reStructuredText ' + 'sources for compilation with the Unicode-aware TeX variants ' + 'XeLaTeX or LuaLaTeX. ' + 'Reads from (default is stdin) and writes to ' + ' (default is stdout). See ' + ' for ' + 'the full reference.') + +publish_cmdline(writer_name='xetex', description=description) diff --git a/buildServer/.venv-build/bin/rst2xml.py b/buildServer/.venv-build/bin/rst2xml.py new file mode 100644 index 0000000..fa4f036 --- /dev/null +++ b/buildServer/.venv-build/bin/rst2xml.py @@ -0,0 +1,23 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 + +# $Id: rst2xml.py 4564 2006-05-21 20:44:42Z wiemann $ +# Author: David Goodger +# Copyright: This module has been placed in the public domain. + +""" +A minimal front end to the Docutils Publisher, producing Docutils XML. +""" + +try: + import locale + locale.setlocale(locale.LC_ALL, '') +except: + pass + +from docutils.core import publish_cmdline, default_description + + +description = ('Generates Docutils-native XML from standalone ' + 'reStructuredText sources. ' + default_description) + +publish_cmdline(writer_name='xml', description=description) diff --git a/buildServer/.venv-build/bin/rstpep2html.py b/buildServer/.venv-build/bin/rstpep2html.py new file mode 100644 index 0000000..daaa57f --- /dev/null +++ b/buildServer/.venv-build/bin/rstpep2html.py @@ -0,0 +1,25 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 + +# $Id: rstpep2html.py 4564 2006-05-21 20:44:42Z wiemann $ +# Author: David Goodger +# Copyright: This module has been placed in the public domain. + +""" +A minimal front end to the Docutils Publisher, producing HTML from PEP +(Python Enhancement Proposal) documents. +""" + +try: + import locale + locale.setlocale(locale.LC_ALL, '') +except: + pass + +from docutils.core import publish_cmdline, default_description + + +description = ('Generates (X)HTML from reStructuredText-format PEP files. ' + + default_description) + +publish_cmdline(reader_name='pep', writer_name='pep_html', + description=description) diff --git a/buildServer/.venv-build/bin/sqlformat b/buildServer/.venv-build/bin/sqlformat new file mode 100644 index 0000000..dc7efb6 --- /dev/null +++ b/buildServer/.venv-build/bin/sqlformat @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from sqlparse.__main__ import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/buildServer/.venv-build/bin/tkconch b/buildServer/.venv-build/bin/tkconch new file mode 100644 index 0000000..a6d803b --- /dev/null +++ b/buildServer/.venv-build/bin/tkconch @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from twisted.conch.scripts.tkconch import run +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(run()) diff --git a/buildServer/.venv-build/bin/trial b/buildServer/.venv-build/bin/trial new file mode 100644 index 0000000..b09a133 --- /dev/null +++ b/buildServer/.venv-build/bin/trial @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from twisted.scripts.trial import run +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(run()) diff --git a/buildServer/.venv-build/bin/twist b/buildServer/.venv-build/bin/twist new file mode 100644 index 0000000..3f1e06e --- /dev/null +++ b/buildServer/.venv-build/bin/twist @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from twisted.application.twist._twist import Twist +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(Twist.main()) diff --git a/buildServer/.venv-build/bin/twistd b/buildServer/.venv-build/bin/twistd new file mode 100644 index 0000000..a34af26 --- /dev/null +++ b/buildServer/.venv-build/bin/twistd @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from twisted.scripts.twistd import run +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(run()) diff --git a/buildServer/.venv-build/bin/wamp b/buildServer/.venv-build/bin/wamp new file mode 100644 index 0000000..b69007e --- /dev/null +++ b/buildServer/.venv-build/bin/wamp @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from autobahn.__main__ import _main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(_main()) diff --git a/buildServer/.venv-build/bin/xbrnetwork b/buildServer/.venv-build/bin/xbrnetwork new file mode 100644 index 0000000..80a4d4a --- /dev/null +++ b/buildServer/.venv-build/bin/xbrnetwork @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from autobahn.xbr._cli import _main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(_main()) diff --git a/buildServer/.venv-build/bin/xbrnetwork-ui b/buildServer/.venv-build/bin/xbrnetwork-ui new file mode 100644 index 0000000..bc8ccbf --- /dev/null +++ b/buildServer/.venv-build/bin/xbrnetwork-ui @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/buildServer/.venv-build/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from autobahn.xbr._gui import _main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(_main()) diff --git a/buildServer/.venv-build/lib64 b/buildServer/.venv-build/lib64 new file mode 120000 index 0000000..7951405 --- /dev/null +++ b/buildServer/.venv-build/lib64 @@ -0,0 +1 @@ +lib \ No newline at end of file diff --git a/buildServer/.venv-build/pyvenv.cfg b/buildServer/.venv-build/pyvenv.cfg new file mode 100644 index 0000000..5000d12 --- /dev/null +++ b/buildServer/.venv-build/pyvenv.cfg @@ -0,0 +1,5 @@ +home = /usr/bin +include-system-site-packages = false +version = 3.12.3 +executable = /usr/bin/python3.12 +command = /usr/bin/python3 -m venv /home/varshini-adurti/ContainerOps/buildServer/.venv-build diff --git a/buildServer/Dockerfile b/buildServer/Dockerfile index 8996356..cd0bc0f 100644 --- a/buildServer/Dockerfile +++ b/buildServer/Dockerfile @@ -1,10 +1,25 @@ -FROM docker:dind +FROM python:3.11-slim -# Install git using apk -RUN apk add --no-cache git python3 py3-pip +# Set environment variables to prevent writing bytecode and reduce cache +ENV PYTHONUNBUFFERED=1 \ + PYTHONDONTWRITEBYTECODE=1 +# Set working directory WORKDIR /app -COPY main.py . -# Use JSON array for CMD -CMD ["sh", "-c", "git clone $GIT_URL && python3 main.py && cd $(basename $GIT_URL .git) && docker build -t $IMAGE_NAME . && docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD && docker tag $IMAGE_NAME $DOCKER_USERNAME/$IMAGE_NAME && docker push $DOCKER_USERNAME/$IMAGE_NAME"] +# Install dependencies required for building Python packages +RUN apt-get update && apt-get install -y --no-install-recommends \ + build-essential libpq-dev + + +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt daphne + +# Copy the rest of the application +COPY . . + +# Expose port +EXPOSE 8000 + +# Run Daphne ASGI server +CMD ["daphne", "-b", "0.0.0.0", "-p", "8000", "buildServer.asgi:application"] \ No newline at end of file diff --git a/buildServer/Dockerfile.final_deploy b/buildServer/Dockerfile.final_deploy new file mode 100644 index 0000000..8a53813 --- /dev/null +++ b/buildServer/Dockerfile.final_deploy @@ -0,0 +1,10 @@ +FROM docker:dind + +# Install git using apk +RUN apk add --no-cache git python3 py3-pip py3-dotenv + +WORKDIR /app +COPY main.py . + +# Use JSON array for CMD +CMD ["sh", "-c", "git clone $GIT_URL && python3 main.py && cd $(basename $GIT_URL .git) && docker build -t $IMAGE_NAME . && docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD && docker tag $IMAGE_NAME $DOCKER_USERNAME/$IMAGE_NAME && docker push $DOCKER_USERNAME/$IMAGE_NAME"] \ No newline at end of file diff --git a/buildServer/api/admin.py b/buildServer/api/admin.py index 8c38f3f..ea5d68b 100644 --- a/buildServer/api/admin.py +++ b/buildServer/api/admin.py @@ -1,3 +1,3 @@ -from django.contrib import admin - -# Register your models here. +from django.contrib import admin + +# Register your models here. diff --git a/buildServer/api/apps.py b/buildServer/api/apps.py index 66656fd..8e0045c 100644 --- a/buildServer/api/apps.py +++ b/buildServer/api/apps.py @@ -1,6 +1,6 @@ -from django.apps import AppConfig - - -class ApiConfig(AppConfig): - default_auto_field = 'django.db.models.BigAutoField' - name = 'api' +from django.apps import AppConfig + + +class ApiConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'api' diff --git a/buildServer/api/consumers.py b/buildServer/api/consumers.py new file mode 100644 index 0000000..7257261 --- /dev/null +++ b/buildServer/api/consumers.py @@ -0,0 +1,15 @@ +import json +from channels.generic.websocket import AsyncWebsocketConsumer + +class RunConsumer(AsyncWebsocketConsumer): + async def connect(self): + self.group_name = 'run_updates' + await self.channel_layer.group_add(self.group_name, self.channel_name) + await self.accept() + + async def disconnect(self, close_code): + await self.channel_layer.group_discard(self.group_name, self.channel_name) + + async def run_data(self, event): + # Send data to WebSocket + await self.send(text_data=json.dumps(event['data'])) \ No newline at end of file diff --git a/buildServer/api/decorators.py b/buildServer/api/decorators.py new file mode 100644 index 0000000..12505ab --- /dev/null +++ b/buildServer/api/decorators.py @@ -0,0 +1,21 @@ +from django.shortcuts import redirect +from social_django.models import UserSocialAuth +from asgiref.sync import sync_to_async + +from django.shortcuts import redirect +from social_django.models import UserSocialAuth +from asgiref.sync import sync_to_async +from functools import wraps + +def github_login_required(view_func): + def _wrapped_view(request, *args, **kwargs): + if request.user.is_authenticated: + try: + UserSocialAuth.objects.get(user=request.user, provider='github') + return view_func(request, *args, **kwargs) + except UserSocialAuth.DoesNotExist: + return redirect('social:begin', 'github') + else: + return redirect('api:login') + + return _wrapped_view diff --git a/buildServer/api/forms.py b/buildServer/api/forms.py index 95fc554..95e23fa 100644 --- a/buildServer/api/forms.py +++ b/buildServer/api/forms.py @@ -1,42 +1,42 @@ -from django import forms -from .models import User - -class SignupForm(forms.ModelForm): - confirm_password = forms.CharField(widget=forms.PasswordInput, label="Confirm Password") - - class Meta: - model = User - fields = ['email', 'username', 'password'] - labels = { - 'email': 'Email', - 'username': 'Create Username', - 'password': 'Create Password', - } - widgets = { - "password": forms.PasswordInput, - } - - def clean_confirm_password(self): - cleaned_data = super().clean() - password = cleaned_data.get('password') - confirm_password = cleaned_data.get('confirm_password') - - if not password or not confirm_password: - raise forms.ValidationError("Both password and confirm password fields are required.") - - if password != confirm_password: - raise forms.ValidationError("Passwords do not match.") - - return confirm_password - - - def save(self, commit=True): - user = super().save(commit=False) - user.set_password(self.cleaned_data["password"]) - if commit: - user.save() - return user - - - - +from django import forms +from .models import User + +class SignupForm(forms.ModelForm): + confirm_password = forms.CharField(widget=forms.PasswordInput, label="Confirm Password") + + class Meta: + model = User + fields = ['email', 'username', 'password'] + labels = { + 'email': 'Email', + 'username': 'Create Username', + 'password': 'Create Password', + } + widgets = { + "password": forms.PasswordInput, + } + + def clean_confirm_password(self): + cleaned_data = super().clean() + password = cleaned_data.get('password') + confirm_password = cleaned_data.get('confirm_password') + + if not password or not confirm_password: + raise forms.ValidationError("Both password and confirm password fields are required.") + + if password != confirm_password: + raise forms.ValidationError("Passwords do not match.") + + return confirm_password + + + def save(self, commit=True): + user = super().save(commit=False) + user.set_password(self.cleaned_data["password"]) + if commit: + user.save() + return user + + + + diff --git a/buildServer/api/models.py b/buildServer/api/models.py index e60cfa4..e4d468c 100644 --- a/buildServer/api/models.py +++ b/buildServer/api/models.py @@ -1,21 +1,30 @@ -from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin +from django.contrib.auth.models import AbstractUser, BaseUserManager, PermissionsMixin from django.db import models class CustomUserManager(BaseUserManager): - def create_user(self, email, password=None, **extra_fields): + def create_user(self, username, email, password=None, **extra_fields): if not email: - raise ValueError('The Email field must be set') + raise ValueError("Users must have an email address") + if not username: + raise ValueError("Users must have a username") + email = self.normalize_email(email) - user = self.model(email=email, **extra_fields) + user = self.model(username=username, email=email, **extra_fields) user.set_password(password) user.save(using=self._db) return user -class User(AbstractBaseUser): + def create_superuser(self, username,email,password=None, **extra_fields): + extra_fields.setdefault("is_superuser", True) + extra_fields.setdefault("is_staff", True) + return self.create_user(username=username, email=email, password=password, **extra_fields) + +class User(AbstractUser): email = models.EmailField(unique=True, blank=False) username = models.CharField(unique=True, max_length=150, blank=False) - + is_staff = models.BooleanField(default=False) + is_superuser=models.BooleanField(default=False) uid = models.AutoField(primary_key=True) objects = CustomUserManager() @@ -28,26 +37,23 @@ def __str__(self): return self.username -class RepoData(models.Model): - username = models.CharField(max_length=200) - git_url = models.URLField(blank=False) - - def __str__(self): - return self.username - class Deployments(models.Model): class StatusChoices(models.TextChoices): READY = "ready" BUILDING = "building" FAILED = "failed" DEPLOYED = "deployed" - - git_repo = models.ForeignKey(RepoData, on_delete=models.CASCADE) + + name= models.CharField(blank=True, max_length=200) + username = models.CharField(max_length=200) + git_url = models.URLField(blank=False) branch= models.CharField(max_length=100, default='main') deployed_domain = models.URLField(blank=True, null=False) + cmd = models.CharField(max_length=100, null=False) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) - + container_id = models.CharField(blank=True,null=False) + port= models.CharField(blank=True, null=False) status = models.CharField( max_length=20, choices = StatusChoices.choices, @@ -59,7 +65,7 @@ class StatusChoices(models.TextChoices): def __str__(self): deployment_details=[ f"Deployment by {self.user.username} | " - f"Repo: {self.git_repo} | " + f"GIT_URL: {self.git_url} | " f"Branch: {self.branch} | " f"Status: {self.status} | " ] @@ -67,12 +73,5 @@ def __str__(self): if(self.status=="deployed"): deployment_details.append(f"Domain: {self.deployed_domain} |") - return deployment_details - - - - - - - + return " ".join(deployment_details) diff --git a/buildServer/api/models_diagram.png b/buildServer/api/models_diagram.png deleted file mode 100644 index 9b42f4d..0000000 Binary files a/buildServer/api/models_diagram.png and /dev/null differ diff --git a/buildServer/api/routing.py b/buildServer/api/routing.py new file mode 100644 index 0000000..b7cdabc --- /dev/null +++ b/buildServer/api/routing.py @@ -0,0 +1,6 @@ +from django.urls import re_path +from . import consumers + +websocket_urlpatterns = [ + re_path(r'ws/data/$', consumers.RunConsumer.as_asgi()), +] \ No newline at end of file diff --git a/buildServer/api/templatetags/custom_tags.py b/buildServer/api/templatetags/custom_tags.py new file mode 100644 index 0000000..785c5a1 --- /dev/null +++ b/buildServer/api/templatetags/custom_tags.py @@ -0,0 +1,12 @@ +from django import template +from social_django.models import UserSocialAuth + +register = template.Library() + +@register.filter +def is_authenticated_with_github(user): + try: + UserSocialAuth.objects.get(user=user, provider='github') + return True + except UserSocialAuth.DoesNotExist: + return False diff --git a/buildServer/api/tests.py b/buildServer/api/tests.py index 7ce503c..de8bdc0 100644 --- a/buildServer/api/tests.py +++ b/buildServer/api/tests.py @@ -1,3 +1,3 @@ -from django.test import TestCase - -# Create your tests here. +from django.test import TestCase + +# Create your tests here. diff --git a/buildServer/api/urls.py b/buildServer/api/urls.py index 4573afe..e4c6caa 100644 --- a/buildServer/api/urls.py +++ b/buildServer/api/urls.py @@ -1,13 +1,22 @@ from django.contrib import admin from django.urls import path, include + from . import views + app_name="api" urlpatterns = [ path('signup/', views.create_user, name="signup"), path('login/', views.login_user, name="login"), path('logout/', views.logout_user, name="logout"), - path('fetch_giturl/', views.fetch_giturl, name='fetch_giturl'), + path('home/', views.home, name="home"), + path('fetch_repos/', views.fetch_repos, name='fetch_repos'), path('deploy/', views.run, name='deploy'), + path('redeploy/', views.redeploy, name='redeploy'), + path('new_project/', views.new_project, name='new_project'), + path('list_deployments/', views.list_deployments, name='list_deployments'), + path('github-webhook/', views.github_webhook, name='github-webhook'), + + ] diff --git a/buildServer/api/views.py b/buildServer/api/views.py index 9442d15..09dff4b 100644 --- a/buildServer/api/views.py +++ b/buildServer/api/views.py @@ -4,15 +4,56 @@ import os from django.shortcuts import render, redirect from django.http import JsonResponse +from django.urls import reverse from django.contrib.auth.decorators import login_required from django.shortcuts import render, redirect from django.contrib.auth import login, logout from django.contrib.auth.forms import AuthenticationForm from .forms import SignupForm -from .models import User +from .models import User, Deployments from django.views.decorators.csrf import csrf_exempt +from channels.layers import get_channel_layer +from asgiref.sync import sync_to_async, async_to_sync +import requests + +from social_django.models import UserSocialAuth +from .decorators import github_login_required + +import asyncio +from channels.db import database_sync_to_async +from django.core.exceptions import ObjectDoesNotExist +import httpx +from asgiref.sync import sync_to_async + + +GITHUB_WEBHOOK_URL = "https://71a5d10bc93409f27fb16e2b912d2ad8.serveo.net/api/github-webhook/" + +@github_login_required +def fetch_repos(request): + try: + social = UserSocialAuth.objects.get(user=request.user, provider='github') + access_token = social.extra_data.get('access_token') + + if not access_token: + return redirect('social:begin', backend='github') + + headers = {'Authorization': f'token {access_token}'} + response = requests.get('https://api.github.com/user/repos', headers=headers) + + if response.status_code == 200: + repos = response.json() + return render(request, 'repos.html', {'repos': repos}) + + elif response.status_code == 401: + return redirect('social:begin', backend='github') + + else: + error = response.json() + return render(request, 'error.html', {'error': error}) + except UserSocialAuth.DoesNotExist: + return redirect('social:begin', backend='github') def login_user(request): if request.method == 'POST': @@ -20,7 +61,7 @@ def login_user(request): if form.is_valid(): user = form.get_user() login(request, user) - return render(request, 'home.html') + return redirect('api:home') else: username = request.POST.get('username') @@ -49,89 +90,271 @@ def create_user(request): return render(request, 'signup.html', {'form': form}) +@login_required +def home(request): + return render(request, 'home.html') + +@github_login_required +def new_project(request): + git_url = request.GET.get('git_url') + return render(request, 'deploy_info.html', {'git_url': git_url}) @login_required def logout_user(request): logout(request) return redirect('/') +@login_required +def list_deployments(request): + deployments = Deployments.objects.all() + return render(request, 'deployments.html', {'deployments': deployments}) + @csrf_exempt +def github_webhook(request): + if request.method == "POST": + try: + print("GitHub Webhook received") + # print(f"Request headers: {request.headers}") + # print(f"Request body: {request.body}") + + # Parse the payload + try: + payload = json.loads(request.body.decode("utf-8")) + except json.JSONDecodeError as e: + return JsonResponse({"error": f"Invalid JSON payload: {str(e)}"}, status=400) + + # Get GitHub event type + event = request.headers.get("X-GitHub-Event") + print(f"GitHub Event: {event}") + + if event == "push": + try: + repo_url = payload["repository"]["clone_url"].rstrip(".git") + branch = payload["ref"].split("/")[-1] # Extract branch name + except KeyError as e: + return JsonResponse({"error": f"Missing expected field: {str(e)}"}, status=400) + + print(f"Received push event for {repo_url} on branch {branch}") + + # Find matching deployment + deployments = Deployments.objects.filter(git_url=repo_url, branch=branch).order_by('-id') + if not deployments: + return JsonResponse({"error": "No matching deployment found"}, status=404) + + # Redeploy the application + deployment = deployments.first() + redeploy_url = "http://localhost:8000/api/redeploy/" + redeploy_payload = { + "deployment_name": deployment.name, + "container_id": deployment.container_id + } + + response = requests.post(redeploy_url, data=redeploy_payload) + + if response.status_code == 200: + return JsonResponse({"status": "success", "message": "Redeployment triggered!"}) + else: + return JsonResponse({"status": "error", "message": "Redeployment failed!"}) + + return JsonResponse({"message": "Event received but not processed"}) + + except Exception as e: + print(f"Error occurred: {str(e)}") + return JsonResponse({"error": str(e)}, status=500) + + return JsonResponse({"error": "Invalid request method"}, status=400) + +@sync_to_async def run(request): if request.method == "POST": + try: - if request.content_type == "application/json": - body = json.loads(request.body) - github_url = body.get("githubUrl") - user_uid = body.get("user_id") - work=body.get("work")#work=deploy/redeploy - - # else: - # github_url = request.POST.get("githubUrl") - # work=request.POST.get("work") - # user = request.user - # username = user.username - # user_uid = user.uid - + # if request.content_type == "application/json": + # body = json.loads(request.body) + # github_url = body.get("github_url") + # user_uid = body.get("user_id") + # work=body.get("work")#work=deploy/redeploy + + github_url = request.POST.get("github_url") + cmd = request.POST.get("cmd") + work=request.POST.get("work") + proj_name = request.POST.get("Name") + + user = request.user + username = user.username + user_uid = user.uid + print(github_url, cmd) + docker_host = os.getenv("DOCKER_HOST") docker_user = os.getenv("DOCKER_USERNAME") docker_pass = os.getenv("DOCKER_PASSWORD") image_name = os.getenv("IMAGE_NAME") - cmd = os.getenv("CMD") + + # cmd = os.getenv("CMD") #env_content = os.getenv("ENV_CONTENT", "") env_content="PORT=3000" - github_url="https://github.com/Sahiiil1406/test-cops" - print(image_name) - + # github_url="https://github.com/Sahiiil1406/test-cops" + # print(image_name) + # Validate required parameters if not all([github_url, docker_user, docker_pass, image_name]): return JsonResponse({"status": "error", "message": "Missing required parameters."}) + #adding webhook for github + repo_parts = github_url.rstrip("/").split("/") + if len(repo_parts) < 2: + return JsonResponse({"status": "error", "message": "Invalid GitHub URL."}) + repo_owner = repo_parts[-2] + repo_name = repo_parts[-1] + + try: + social = UserSocialAuth.objects.get(user=request.user, provider='github') + access_token = social.extra_data.get('access_token') + if not access_token: + print("no token") + + except UserSocialAuth.DoesNotExist: + return JsonResponse({"status": "error", "message": "GitHub authentication required."}) + + headers = {"Authorization": f"token {access_token}", "Accept": "application/vnd.github.v3+json"} + webhooks_url = f"https://api.github.com/repos/{repo_owner}/{repo_name}/hooks" + response = requests.get(webhooks_url, headers=headers) + + if response.status_code == 200: + webhooks = response.json() + for webhook in webhooks: + if webhook["config"]["url"] == GITHUB_WEBHOOK_URL: + print("Webhook already exists.") + break + + else: + # Create a new webhook + payload = { + "name": "web", + "active": True, + "events": ["push"], # Trigger on push events + "config": { + "url": GITHUB_WEBHOOK_URL, + "content_type": "json", + "insecure_ssl": "0", + }, + } + webhook_response = requests.post(webhooks_url, headers=headers, json=payload) + if webhook_response.status_code == 201: + print("GitHub webhook created successfully.") + else: + print("Failed to create GitHub webhook:", webhook_response.json()) + + else: + print("Failed to fetch webhooks:", response.json()) + + ## + deployment = Deployments.objects.create( + + name=proj_name, + username=username, + git_url=github_url, + branch="main", + status=Deployments.StatusChoices.BUILDING, + user=user, + cmd=cmd, + + ) + print(f"Deployment created in db git=: {github_url}") + # try: # user = User.objects.get(uid=user_uid) # except User.DoesNotExist: # return JsonResponse({'error': 'User not found'}, status=404) - - + # Clone repository, build, and push image - client = docker.from_env() - + try: + client = docker.from_env() + print(f"Docker client initialized: {client}") + except docker.errors.DockerException as e: + + deployment.status = Deployments.StatusChoices.FAILED + deployment.save() + print(f"Error initializing Docker client: {str(e)}") + return JsonResponse({"status": "error", "message": f"Docker client error: {str(e)}"}) + + except Exception as e: + print(f"Unexpected error: {str(e)}") # build the image manually using docker build -t final_deploy . (before calling the run fn) - container = client.containers.run( - image='final_deploy', - detach=True, - environment={ - "GIT_URL": github_url, - "DOCKER_USERNAME": docker_user, - "DOCKER_PASSWORD": docker_pass, - "IMAGE_NAME": image_name, - "CMD":cmd, - "ENV_CONTENT":env_content - }, - volumes={"/var/run/docker.sock": {"bind": "/var/run/docker.sock", "mode": "rw"}}, - privileged=True, - ) + try: + container = client.containers.run( + image='final_deploy', + detach=True, + environment={ + "GIT_URL": github_url, + "DOCKER_USERNAME": docker_user, + "DOCKER_PASSWORD": docker_pass, + "IMAGE_NAME": image_name, + "CMD": cmd, + "ENV_CONTENT": env_content + }, + volumes={"/var/run/docker.sock": {"bind": "/var/run/docker.sock", "mode": "rw"}}, + privileged=True, + ) + print(f"Container started with ID: {container.id}") + + except docker.errors.APIError as e: + deployment.status = Deployments.StatusChoices.FAILED + deployment.save() + return JsonResponse({"status": "error", "message": f"Container error: {str(e)}"}) + + except docker.errors.ImageNotFound as e: + print(str(e)) + except Exception as e: + print(str(e)) + + channel_layer = get_channel_layer() + async_to_sync(channel_layer.group_send)( + 'run_updates', + { + 'type': 'run_data', # Matches consumer method + 'data': "Sending LOGS..." + } + ) # Stream logs + logs = container.logs(stream=True) logs_output = "" for log in logs: decoded_log = log.decode("utf-8") - logs_output += decoded_log - + async_to_sync(channel_layer.group_send)( + 'run_updates', + { + 'type': 'run_data', + 'data': decoded_log + } + ) + container.stop() container.remove() - #hit a URL to show success:url:http://172.25.96.1:8001/api/webhook,request type:POST,req.body:{id,image_name,image_port} + #hit a URL to show success:url: http://172.25.96.1:8001/api/webhook request type:POST,req.body:{id,image_name,image_port} payload = { "id": container.id, "image_name": image_name, "image_port": "3000", "work":work, } - + + try: webhook_url = "http://localhost:8001/api/webhook/" response = requests.post(webhook_url, json=payload) - print(response.json()) + + webhook_response = response.json() + final_container_id = webhook_response.get("container_id") + + if final_container_id: + deployment.container_id = final_container_id + deployment.status = Deployments.StatusChoices.DEPLOYED + deployment.save() + print(f"{deployment.name} has been successfully deployed! Container id: {final_container_id}") + except Exception as e: print(f"Failed to hit webhook URL: {str(e)}") @@ -152,6 +375,70 @@ def run(request): return JsonResponse({"status": "error", "message": "Invalid request method. Use POST."}) -@login_required -def fetch_giturl(request): - return render(request, 'fetch_giturl.html') \ No newline at end of file +@csrf_exempt +def redeploy(request): + if request.method == "POST": + + try: + deployment_name = request.POST.get("deployment_name") + container_id = request.POST.get("container_id") + image_name = os.getenv("IMAGE_NAME") + print(deployment_name, container_id) + + if not all([deployment_name, container_id]): + return JsonResponse({"status": "error", "message": "Missing required parameters."}) + + try: + deployment = Deployments.objects.get(name=deployment_name, container_id=container_id) + except Deployments.DoesNotExist: + return JsonResponse({"status": "error", "message": "Deployment not found."}) + + client = docker.from_env() + + container = client.containers.run( + image=image_name, + detach=True, + environment={ + "GIT_URL": deployment.git_url, + "CMD": deployment.cmd, + }, + volumes={"/var/run/docker.sock": {"bind": "/var/run/docker.sock", "mode": "rw"}}, + privileged=True, + ) + + # Trigger webhook + payload = { + "id": container.id, + "image_name": image_name, + "image_port": "3000", + "work": "redeploy", + } + + try: + webhook_url = "http://localhost:8001/api/webhook/" + response = requests.post(webhook_url, json=payload) + + webhook_response = response.json() + final_container_id = webhook_response.get("container_id") + + if final_container_id: + deployment.container_id = final_container_id + deployment.status = Deployments.StatusChoices.DEPLOYED + deployment.save() + return JsonResponse({ + "status": "success", + "message": "Container redeployed successfully.", + "containerId": final_container_id + }) + + except Exception as e: + return JsonResponse({ + "status": "error", + "message": f"Failed to hit webhook: {str(e)}" + }) + + except Exception as e: + return JsonResponse({"status": "error", "message": str(e)}) + + return JsonResponse({"status": "error", "message": "Invalid request method. Use POST."}) + diff --git a/buildServer/buildServer/asgi.py b/buildServer/buildServer/asgi.py index 2053c43..215efa1 100644 --- a/buildServer/buildServer/asgi.py +++ b/buildServer/buildServer/asgi.py @@ -6,11 +6,16 @@ For more information on this file, see https://docs.djangoproject.com/en/5.1/howto/deployment/asgi/ """ - import os - from django.core.asgi import get_asgi_application +from channels.routing import ProtocolTypeRouter, URLRouter +from api import routing os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'buildServer.settings') -application = get_asgi_application() +application = ProtocolTypeRouter({ + "http": get_asgi_application(), + "websocket": URLRouter( + routing.websocket_urlpatterns + ), +}) diff --git a/buildServer/buildServer/settings.py b/buildServer/buildServer/settings.py index de0d1d2..7dc2374 100644 --- a/buildServer/buildServer/settings.py +++ b/buildServer/buildServer/settings.py @@ -33,12 +33,13 @@ # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True -ALLOWED_HOSTS = [] +ALLOWED_HOSTS = ['*'] # Application definition INSTALLED_APPS = [ + 'daphne', # Required for WebSockets 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', @@ -46,8 +47,28 @@ 'django.contrib.messages', 'django.contrib.staticfiles', 'django_extensions', + 'social_django', + 'channels', 'api', + ] +ASGI_APPLICATION = "buildServer.asgi.application" +WSGI_APPLICATION = 'buildServer.wsgi.application' + +SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') +SECURE_BROWSER_XSS_FILTER = True +SESSION_COOKIE_AGE = 300 + + +DJANGO_CHANNEL_LAYERS = { + "default": { + "BACKEND": "channels.layers.InMemoryChannelLayer", + "CONFIG": { + "expiry": 300 + }, + }, +} + MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', @@ -57,6 +78,7 @@ 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', + 'social_django.middleware.SocialAuthExceptionMiddleware', ] ROOT_URLCONF = 'buildServer.urls' @@ -77,7 +99,26 @@ }, ] -WSGI_APPLICATION = 'buildServer.wsgi.application' +AUTHENTICATION_BACKENDS = [ + 'social_core.backends.github.GithubOAuth2', + 'django.contrib.auth.backends.ModelBackend', +] + +SOCIAL_AUTH_GITHUB_KEY = os.getenv('GITHUB_KEY') +SOCIAL_AUTH_GITHUB_SECRET = os.getenv('GITHUB_SECRET') +SOCIAL_AUTH_LOGIN_REDIRECT_URL = '/api/home' +SOCIAL_AUTH_COMPLETE_URL_NAME = 'social:complete' +SOCIAL_AUTH_GITHUB_SCOPE = ['public_repo', 'admin:repo_hook'] + +CSRF_TRUSTED_ORIGINS = ['https://github.com', 'https://api.github.com', "http://127.0.0.1"] +CSRF_COOKIE_SECURE = False +SESSION_COOKIE_SECURE = False + +CHANNEL_LAYERS = { + 'default': { + 'BACKEND': 'channels.layers.InMemoryChannelLayer', # For development + }, +} # Database @@ -91,6 +132,9 @@ 'PASSWORD': env('DB_PASSWORD'), 'HOST': env('HOST'), 'PORT': env('DB_PORT'), + 'OPTIONS': { + 'sslmode': 'require', + }, } } @@ -138,3 +182,5 @@ DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' AUTH_USER_MODEL= 'api.User' + + diff --git a/buildServer/buildServer/urls.py b/buildServer/buildServer/urls.py index d432147..af85d92 100644 --- a/buildServer/buildServer/urls.py +++ b/buildServer/buildServer/urls.py @@ -21,6 +21,9 @@ urlpatterns = [ path('admin/', admin.site.urls), - path('', views.home_page), + path('', views.start), + path('social-auth/', include('social_django.urls', namespace='social')), path('api/', include('api.urls')), + path('logs/', views.logs_view), + ] diff --git a/buildServer/buildServer/views.py b/buildServer/buildServer/views.py index d6df4fc..c0b3cca 100644 --- a/buildServer/buildServer/views.py +++ b/buildServer/buildServer/views.py @@ -2,7 +2,8 @@ from django.views.decorators.cache import never_cache -def home_page(request): - return render(request, 'home.html') - +def start(request): + return render(request, 'start.html') +def logs_view(request): + return render(request, "logs.html") \ No newline at end of file diff --git a/buildServer/buildServer/wsgi.py b/buildServer/buildServer/wsgi.py index d41e084..edf1fb6 100644 --- a/buildServer/buildServer/wsgi.py +++ b/buildServer/buildServer/wsgi.py @@ -1,16 +1,16 @@ -""" -WSGI config for buildServer project. - -It exposes the WSGI callable as a module-level variable named ``application``. - -For more information on this file, see -https://docs.djangoproject.com/en/5.1/howto/deployment/wsgi/ -""" - -import os - -from django.core.wsgi import get_wsgi_application - -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'buildServer.settings') - -application = get_wsgi_application() +""" +WSGI config for buildServer project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/5.1/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'buildServer.settings') + +application = get_wsgi_application() diff --git a/buildServer/main.py b/buildServer/main.py index eeda5b3..fdc4d50 100644 --- a/buildServer/main.py +++ b/buildServer/main.py @@ -1,14 +1,14 @@ import os git_url = os.getenv('GIT_URL') cmd=[os.getenv('CMD')] -print(f"Orrignal cmd: {cmd}") -cmd_list = cmd[0].split('#') +print(f"Orignal cmd: {cmd}") +cmd_list = cmd[0].split(' ') +print(cmd_list) cmd=f'["{cmd_list[0]}", "{cmd_list[1]}"]' print(f"Command: {cmd}") env_content=os.getenv('ENV_CONTENT') - print("Running python script to generate Dockerfile") def write_env_file(repo_path, env_content): env_path = os.path.join(repo_path, '.env') @@ -44,96 +44,96 @@ def generate_dockerfile(project_type, cmd, include_env): env_copy = "COPY .env ./\n" if include_env else "" templates = { 'node': f''' -# Node.js Dockerfile -FROM node:alpine -WORKDIR /app -COPY package*.json ./ -{env_copy}RUN npm install -COPY . . -EXPOSE 3000 -CMD {cmd} -''', + # Node.js Dockerfile + FROM node:alpine + WORKDIR /app + COPY package*.json ./ + {env_copy}RUN npm install + COPY . . + EXPOSE 3000 + CMD {cmd} + ''', 'python': f''' -# Python Dockerfile -FROM python:3.9-alpine -WORKDIR /app -COPY requirements.txt ./ -{env_copy}RUN pip install -r requirements.txt -COPY . . -CMD {cmd} -''', + # Python Dockerfile + FROM python:3.9-alpine + WORKDIR /app + COPY requirements.txt ./ + {env_copy}RUN pip install -r requirements.txt + COPY . . + CMD {cmd} + ''', 'java': f''' -# Java Dockerfile -FROM openjdk:11-jre-slim -WORKDIR /app -{env_copy}COPY . . -RUN javac Main.java -CMD {cmd} -''', - 'ruby': f''' -# Ruby Dockerfile -FROM ruby:3.0-alpine -WORKDIR /app -COPY Gemfile Gemfile.lock ./ -{env_copy}RUN bundle install -COPY . . -CMD {cmd} -''', + # Java Dockerfile + FROM openjdk:11-jre-slim + WORKDIR /app + {env_copy}COPY . . + RUN javac Main.java + CMD {cmd} + ''', + 'ruby': f''' + # Ruby Dockerfile + FROM ruby:3.0-alpine + WORKDIR /app + COPY Gemfile Gemfile.lock ./ + {env_copy}RUN bundle install + COPY . . + CMD {cmd} + ''', 'php': f''' -# PHP Dockerfile -FROM php:8.0-apache -WORKDIR /var/www/html -{env_copy}COPY . . -RUN docker-php-ext-install mysqli -CMD {cmd} -''', - 'go': f''' -# Go Dockerfile -FROM golang:1.17-alpine -WORKDIR /app -{env_copy}COPY . . -RUN go build -o main . -CMD {cmd} -''', + # PHP Dockerfile + FROM php:8.0-apache + WORKDIR /var/www/html + {env_copy}COPY . . + RUN docker-php-ext-install mysqli + CMD {cmd} + ''', + 'go': f''' + # Go Dockerfile + FROM golang:1.17-alpine + WORKDIR /app + {env_copy}COPY . . + RUN go build -o main . + CMD {cmd} + ''', 'rust': f''' -# Rust Dockerfile -FROM rust:1.65-alpine -WORKDIR /app -{env_copy}COPY . . -RUN cargo build --release -CMD {cmd} -''', + # Rust Dockerfile + FROM rust:1.65-alpine + WORKDIR /app + {env_copy}COPY . . + RUN cargo build --release + CMD {cmd} + ''', 'cpp': f''' -# C++ Dockerfile -FROM gcc:11-alpine -WORKDIR /app -{env_copy}COPY . . -RUN make -CMD {cmd} -''', + # C++ Dockerfile + FROM gcc:11-alpine + WORKDIR /app + {env_copy}COPY . . + RUN make + CMD {cmd} + ''', 'csharp': f''' -# C# Dockerfile -FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build -WORKDIR /app -{env_copy}COPY . . -RUN dotnet restore -RUN dotnet publish -c Release -o out -FROM mcr.microsoft.com/dotnet/aspnet:6.0 -WORKDIR /app -COPY --from=build /app/out . -CMD {cmd} -''', + # C# Dockerfile + FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build + WORKDIR /app + {env_copy}COPY . . + RUN dotnet restore + RUN dotnet publish -c Release -o out + FROM mcr.microsoft.com/dotnet/aspnet:6.0 + WORKDIR /app + COPY --from=build /app/out . + CMD {cmd} + ''', 'frontend': f''' -# Frontend Dockerfile -FROM node:16-alpine -WORKDIR /app -COPY package*.json ./ -{env_copy}RUN npm install -COPY . . -RUN npm run build -CMD {cmd} -''', - } + # Frontend Dockerfile + FROM node:16-alpine + WORKDIR /app + COPY package*.json ./ + {env_copy}RUN npm install + COPY . . + RUN npm run build + CMD {cmd} + ''', + } return templates.get(project_type, '# Unsupported project type. Please define a custom Dockerfile.') def save_dockerfile(repo_path, content): @@ -166,13 +166,14 @@ def auto_generate_dockerfile(repo_path, include_env=True): print(f"Dockerfile content:\n{dockerfile_content}") save_dockerfile(repo_path, dockerfile_content) -# Example Usage - +# Main script logic repo_name = git_url.split('/')[-1].replace('.git', '') repo_path = f'./{repo_name}' + include_env = True # Set to True if you want to include .env file print(repo_path) +os.makedirs(repo_path, exist_ok=True) write_env_file(repo_path,env_content ) print("ENV is completed.........") diff --git a/buildServer/manage.py b/buildServer/manage.py index 7dbe6c4..2a96d97 100755 --- a/buildServer/manage.py +++ b/buildServer/manage.py @@ -1,22 +1,22 @@ -#!/usr/bin/env python -"""Django's command-line utility for administrative tasks.""" -import os -import sys - - -def main(): - """Run administrative tasks.""" - os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'buildServer.settings') - try: - from django.core.management import execute_from_command_line - except ImportError as exc: - raise ImportError( - "Couldn't import Django. Are you sure it's installed and " - "available on your PYTHONPATH environment variable? Did you " - "forget to activate a virtual environment?" - ) from exc - execute_from_command_line(sys.argv) - - -if __name__ == '__main__': - main() +#!/usr/bin/env python +"""Django's command-line utility for administrative tasks.""" +import os +import sys + + +def main(): + """Run administrative tasks.""" + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'buildServer.settings') + try: + from django.core.management import execute_from_command_line + except ImportError as exc: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) from exc + execute_from_command_line(sys.argv) + + +if __name__ == '__main__': + main() diff --git a/buildServer/models.dot b/buildServer/models.dot index a23bbab..8243017 100644 --- a/buildServer/models.dot +++ b/buildServer/models.dot @@ -1,6 +1,6 @@ digraph model_graph { // Dotfile by Django-Extensions graph_models - // Created: 2025-01-11 17:02 + // Created: 2025-02-09 10:38 // Cli Options: api fontname = "Roboto" @@ -98,11 +98,11 @@ digraph model_graph { >] - api_models_RepoData [label=< + api_models_Deployments [label=< @@ -115,75 +115,57 @@ digraph model_graph { -
- RepoData + Deployments
- git_url + user - URLField + ForeignKey (username)
- username + branch CharField
- >] - - api_models_Deployments [label=< - - - - - - - @@ -222,9 +204,6 @@ digraph model_graph { api_models_User -> django_contrib_auth_base_user_AbstractBaseUser [label=" abstract\ninheritance"] [arrowhead=empty, arrowtail=none, dir=both]; - api_models_Deployments -> api_models_RepoData - [label=" git_repo (deployments)"] [arrowhead=none, arrowtail=dot, dir=both]; - api_models_Deployments -> api_models_User [label=" user (deployments)"] [arrowhead=none, arrowtail=dot, dir=both]; diff --git a/buildServer/requirements.txt b/buildServer/requirements.txt index ea63602..f70f877 100644 --- a/buildServer/requirements.txt +++ b/buildServer/requirements.txt @@ -4,7 +4,7 @@ botocore==1.35.79 certifi==2024.8.30 charset-normalizer==3.4.0 colorama==0.4.6 -Django==5.1.5 +Django==4.2.19 django-environ==0.12.0 django-extensions==3.2.3 djangorestframework==3.15.2 @@ -21,11 +21,17 @@ psycopg2-binary==2.9.10 pyasn1==0.6.1 python-dateutil==2.9.0.post0 PyYAML==6.0.2 -requests==2.32.3 +requests==2.29.0 rsa==4.7.2 s3transfer==0.10.4 six==1.17.0 smmap==5.0.1 sqlparse==0.5.2 typing_extensions==4.12.2 -urllib3==2.2.3 \ No newline at end of file +urllib3 +environ +channels +python-dotenv +social-auth-app-django +httpx +pyngrok diff --git a/buildServer/templates/deploy_info.html b/buildServer/templates/deploy_info.html new file mode 100644 index 0000000..91457c3 --- /dev/null +++ b/buildServer/templates/deploy_info.html @@ -0,0 +1,36 @@ +{% extends 'layout.html'%} +{% load static %} + +{% block title%} + New Project +{%endblock%} + + + +{%block content%} + +
+
New Project
+
+ {% csrf_token %} +

+ Github URL - {{git_url}} +

+ + + + + + + + +
+{% endblock %} diff --git a/buildServer/templates/deployment_status.html b/buildServer/templates/deployment_status.html new file mode 100644 index 0000000..eace793 --- /dev/null +++ b/buildServer/templates/deployment_status.html @@ -0,0 +1,46 @@ +{% extends 'layout.html'%} +{% block title%} + ContainerOps | Success +{%endblock%} + +{% block navbar %} + + + + ContainerOps + +
+ + +
+ + + +{%endblock%} + +{%block content%} + +
+ {% if message %} +

{{message}}

+ {% else %} +

Failure

+ {% endif%} +
+ +{% endblock %} diff --git a/buildServer/templates/deployments.html b/buildServer/templates/deployments.html new file mode 100644 index 0000000..e77c95f --- /dev/null +++ b/buildServer/templates/deployments.html @@ -0,0 +1,41 @@ +{% extends 'layout.html' %} +{% load static %} + +{% block title %} + Your Deployments +{% endblock %} + +{% block content %} +
+

Your Deployments

+
+ {% for deployment in deployments %} + +
+
{{ deployment.name }}
+ +

Container ID: {{ deployment.container_id }}

+ +

Status: {{ deployment.status }}

+ + +
+ {% csrf_token %} + + + + + +
+ + + {% endfor %} +
+ +
+{% endblock %} diff --git a/buildServer/templates/error.html b/buildServer/templates/error.html new file mode 100644 index 0000000..4c5a75a --- /dev/null +++ b/buildServer/templates/error.html @@ -0,0 +1,12 @@ +{% extends 'layout.html'%} + +{% block title%} + Error +{%endblock%} + +{%block content%} + +
+ 404. Error +
+{% endblock %} diff --git a/buildServer/templates/fetch_giturl.html b/buildServer/templates/fetch_giturl.html deleted file mode 100644 index ed80722..0000000 --- a/buildServer/templates/fetch_giturl.html +++ /dev/null @@ -1,24 +0,0 @@ -{% extends 'layout.html'%} -{% load static %} - -{% block title%} - Deploy -{%endblock%} - - - -{%block content%} - -
Github URL
- - {% csrf_token %} - - - - - -{% endblock %} \ No newline at end of file diff --git a/buildServer/templates/home.html b/buildServer/templates/home.html index 4ec3886..0e17890 100644 --- a/buildServer/templates/home.html +++ b/buildServer/templates/home.html @@ -1,48 +1,63 @@ {% extends 'layout.html'%} +{% load custom_tags %} + {% block title%} - Hello + ContainerOps | Home {%endblock%} {% block navbar %} - {% comment %} Have the logout button only when you have logged in {% endcomment %} - {%if user.is_authenticated%} - - - - | - - - - - | - - - - {%else%} - - - - | - - - - - | - - - {%endif%} + + ContainerOps + +
+ {% if user|is_authenticated_with_github %} + + {% else %} +
+ {% csrf_token %} + + + {% endif %} + + + +
+ {%endblock%} {%block content%} - {%if user.is_authenticated%} - Hii {{user.username}}! +
+

Build. Deploy. Repeat.

- {%else%} - Hello - {%endif%} -{% endblock %} \ No newline at end of file +
+ +{% endblock %} diff --git a/buildServer/templates/layout.html b/buildServer/templates/layout.html index d477e31..927f3e8 100644 --- a/buildServer/templates/layout.html +++ b/buildServer/templates/layout.html @@ -1,34 +1,41 @@ - -{% load static %} - - - - - - {% block title%} - - {%endblock%} - - - - - - - - - -
- {%block content%} - {% endblock %} -
- - + +{% load static %} + + + + + + {% block title%} + + {%endblock%} + + + + + + + + +
+ {%block content%} + {% endblock %} +
+ + \ No newline at end of file diff --git a/buildServer/templates/login.html b/buildServer/templates/login.html index a0e3fd3..42e0c07 100644 --- a/buildServer/templates/login.html +++ b/buildServer/templates/login.html @@ -8,13 +8,15 @@ {%block content%} - -
Login
- + +
+
Login
+ {% csrf_token %} {{form.as_p}} - + -{% endblock %} \ No newline at end of file +
+{% endblock %} diff --git a/buildServer/templates/logs.html b/buildServer/templates/logs.html new file mode 100644 index 0000000..9c82b5b --- /dev/null +++ b/buildServer/templates/logs.html @@ -0,0 +1,44 @@ +{% load static %} + + + + + + Live Logs + + + +

Live Logs

+
+ + + + diff --git a/buildServer/templates/new_proj.html b/buildServer/templates/new_proj.html new file mode 100644 index 0000000..e69de29 diff --git a/buildServer/templates/repos.html b/buildServer/templates/repos.html new file mode 100644 index 0000000..3f184af --- /dev/null +++ b/buildServer/templates/repos.html @@ -0,0 +1,49 @@ +{% extends 'layout.html'%} +{% load static %} + +{% block title%} + Choose Repository +{%endblock%} + +{% block content %} + +
+
Choose your Repository for Deployment
+
+
- - Deployments -
- id + container_id - BigAutoField + CharField
- git_repo - - ForeignKey (id) -
- user + created_at - ForeignKey (uid) + DateTimeField
- branch + deployed_domain - CharField + URLField
- created_at + git_url - DateTimeField + URLField
- deployed_domain + port - URLField + CharField
+ + + + + + + + + {%for repo in repos%} + + + + + + {%endfor%} + +
+ Repo Name + + Public/Private + + Import +
+ {{repo.name}} + + {{repo.visibility}} + + + + +
+ + + + +{% endblock %} \ No newline at end of file diff --git a/buildServer/templates/signup.html b/buildServer/templates/signup.html index 381e08f..9077bcb 100644 --- a/buildServer/templates/signup.html +++ b/buildServer/templates/signup.html @@ -1,20 +1,22 @@ -{% extends 'layout.html'%} -{% load static %} - -{% block title%} - Signup -{%endblock%} - - - -{%block content%} - -
Sign Up
-
- {% csrf_token %} - {{form.as_p}} - - -
- +{% extends 'layout.html'%} +{% load static %} + +{% block title%} + Signup +{%endblock%} + + + +{%block content%} +
+
Signup
+
+ {% csrf_token %} + {{form.as_p}} + + +
+ +

Already have an account? Login

+
{% endblock %} \ No newline at end of file diff --git a/buildServer/templates/start.html b/buildServer/templates/start.html new file mode 100644 index 0000000..35a9d8f --- /dev/null +++ b/buildServer/templates/start.html @@ -0,0 +1,49 @@ +{% extends 'layout.html'%} + +{% block title%} + ContainerOps | Home +{%endblock%} + +{% block navbar %} + + + + ContainerOps + +
+ + +
+ + +{%endblock%} + +{%block content%} + +
+

Welcome to ContainerOps !

+ +
+ +{% endblock %} diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..60cfee2 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,42 @@ +version: "3.8" + +networks: + app_network: + +volumes: + nginx_config: + +services: + nginx: + image: nginx:latest + container_name: nginx_proxy + network_mode: "host" # Full access to host network + volumes: + - nginx_config:/etc/nginx + restart: always + + build_server: + build: + context: ./buildServer + ports: + - "8000:8000" + volumes: + - ./buildServer:/app + - /var/run/docker.sock:/var/run/docker.sock + - nginx_config:/etc/nginx + restart: always + network_mode: "host" + + proxy_server: + build: + context: ./proxy_server + ports: + - "8001:8001" + volumes: + - ./proxy_server:/app + - /var/run/docker.sock:/var/run/docker.sock + - nginx_config:/etc/nginx + restart: always + network_mode: "host" + environment: + - ALLOWED_HOSTS=proxy_server,localhost,127.0.0.1,* \ No newline at end of file diff --git a/models_diagram.png b/models_diagram.png new file mode 100644 index 0000000..30b8e61 Binary files /dev/null and b/models_diagram.png differ diff --git a/proxy_server/.venv-proxy/bin/Activate.ps1 b/proxy_server/.venv-proxy/bin/Activate.ps1 new file mode 100644 index 0000000..b49d77b --- /dev/null +++ b/proxy_server/.venv-proxy/bin/Activate.ps1 @@ -0,0 +1,247 @@ +<# +.Synopsis +Activate a Python virtual environment for the current PowerShell session. + +.Description +Pushes the python executable for a virtual environment to the front of the +$Env:PATH environment variable and sets the prompt to signify that you are +in a Python virtual environment. Makes use of the command line switches as +well as the `pyvenv.cfg` file values present in the virtual environment. + +.Parameter VenvDir +Path to the directory that contains the virtual environment to activate. The +default value for this is the parent of the directory that the Activate.ps1 +script is located within. + +.Parameter Prompt +The prompt prefix to display when this virtual environment is activated. By +default, this prompt is the name of the virtual environment folder (VenvDir) +surrounded by parentheses and followed by a single space (ie. '(.venv) '). + +.Example +Activate.ps1 +Activates the Python virtual environment that contains the Activate.ps1 script. + +.Example +Activate.ps1 -Verbose +Activates the Python virtual environment that contains the Activate.ps1 script, +and shows extra information about the activation as it executes. + +.Example +Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv +Activates the Python virtual environment located in the specified location. + +.Example +Activate.ps1 -Prompt "MyPython" +Activates the Python virtual environment that contains the Activate.ps1 script, +and prefixes the current prompt with the specified string (surrounded in +parentheses) while the virtual environment is active. + +.Notes +On Windows, it may be required to enable this Activate.ps1 script by setting the +execution policy for the user. You can do this by issuing the following PowerShell +command: + +PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser + +For more information on Execution Policies: +https://go.microsoft.com/fwlink/?LinkID=135170 + +#> +Param( + [Parameter(Mandatory = $false)] + [String] + $VenvDir, + [Parameter(Mandatory = $false)] + [String] + $Prompt +) + +<# Function declarations --------------------------------------------------- #> + +<# +.Synopsis +Remove all shell session elements added by the Activate script, including the +addition of the virtual environment's Python executable from the beginning of +the PATH variable. + +.Parameter NonDestructive +If present, do not remove this function from the global namespace for the +session. + +#> +function global:deactivate ([switch]$NonDestructive) { + # Revert to original values + + # The prior prompt: + if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) { + Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt + Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT + } + + # The prior PYTHONHOME: + if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) { + Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME + Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME + } + + # The prior PATH: + if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) { + Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH + Remove-Item -Path Env:_OLD_VIRTUAL_PATH + } + + # Just remove the VIRTUAL_ENV altogether: + if (Test-Path -Path Env:VIRTUAL_ENV) { + Remove-Item -Path env:VIRTUAL_ENV + } + + # Just remove VIRTUAL_ENV_PROMPT altogether. + if (Test-Path -Path Env:VIRTUAL_ENV_PROMPT) { + Remove-Item -Path env:VIRTUAL_ENV_PROMPT + } + + # Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether: + if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) { + Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force + } + + # Leave deactivate function in the global namespace if requested: + if (-not $NonDestructive) { + Remove-Item -Path function:deactivate + } +} + +<# +.Description +Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the +given folder, and returns them in a map. + +For each line in the pyvenv.cfg file, if that line can be parsed into exactly +two strings separated by `=` (with any amount of whitespace surrounding the =) +then it is considered a `key = value` line. The left hand string is the key, +the right hand is the value. + +If the value starts with a `'` or a `"` then the first and last character is +stripped from the value before being captured. + +.Parameter ConfigDir +Path to the directory that contains the `pyvenv.cfg` file. +#> +function Get-PyVenvConfig( + [String] + $ConfigDir +) { + Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg" + + # Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue). + $pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue + + # An empty map will be returned if no config file is found. + $pyvenvConfig = @{ } + + if ($pyvenvConfigPath) { + + Write-Verbose "File exists, parse `key = value` lines" + $pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath + + $pyvenvConfigContent | ForEach-Object { + $keyval = $PSItem -split "\s*=\s*", 2 + if ($keyval[0] -and $keyval[1]) { + $val = $keyval[1] + + # Remove extraneous quotations around a string value. + if ("'""".Contains($val.Substring(0, 1))) { + $val = $val.Substring(1, $val.Length - 2) + } + + $pyvenvConfig[$keyval[0]] = $val + Write-Verbose "Adding Key: '$($keyval[0])'='$val'" + } + } + } + return $pyvenvConfig +} + + +<# Begin Activate script --------------------------------------------------- #> + +# Determine the containing directory of this script +$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition +$VenvExecDir = Get-Item -Path $VenvExecPath + +Write-Verbose "Activation script is located in path: '$VenvExecPath'" +Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)" +Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)" + +# Set values required in priority: CmdLine, ConfigFile, Default +# First, get the location of the virtual environment, it might not be +# VenvExecDir if specified on the command line. +if ($VenvDir) { + Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values" +} +else { + Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir." + $VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/") + Write-Verbose "VenvDir=$VenvDir" +} + +# Next, read the `pyvenv.cfg` file to determine any required value such +# as `prompt`. +$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir + +# Next, set the prompt from the command line, or the config file, or +# just use the name of the virtual environment folder. +if ($Prompt) { + Write-Verbose "Prompt specified as argument, using '$Prompt'" +} +else { + Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value" + if ($pyvenvCfg -and $pyvenvCfg['prompt']) { + Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'" + $Prompt = $pyvenvCfg['prompt']; + } + else { + Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virtual environment)" + Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'" + $Prompt = Split-Path -Path $venvDir -Leaf + } +} + +Write-Verbose "Prompt = '$Prompt'" +Write-Verbose "VenvDir='$VenvDir'" + +# Deactivate any currently active virtual environment, but leave the +# deactivate function in place. +deactivate -nondestructive + +# Now set the environment variable VIRTUAL_ENV, used by many tools to determine +# that there is an activated venv. +$env:VIRTUAL_ENV = $VenvDir + +if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) { + + Write-Verbose "Setting prompt to '$Prompt'" + + # Set the prompt to include the env name + # Make sure _OLD_VIRTUAL_PROMPT is global + function global:_OLD_VIRTUAL_PROMPT { "" } + Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT + New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt + + function global:prompt { + Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) " + _OLD_VIRTUAL_PROMPT + } + $env:VIRTUAL_ENV_PROMPT = $Prompt +} + +# Clear PYTHONHOME +if (Test-Path -Path Env:PYTHONHOME) { + Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME + Remove-Item -Path Env:PYTHONHOME +} + +# Add the venv to the PATH +Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH +$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH" diff --git a/proxy_server/.venv-proxy/bin/activate b/proxy_server/.venv-proxy/bin/activate new file mode 100644 index 0000000..66fbdfa --- /dev/null +++ b/proxy_server/.venv-proxy/bin/activate @@ -0,0 +1,70 @@ +# This file must be used with "source bin/activate" *from bash* +# You cannot run it directly + +deactivate () { + # reset old environment variables + if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then + PATH="${_OLD_VIRTUAL_PATH:-}" + export PATH + unset _OLD_VIRTUAL_PATH + fi + if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then + PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}" + export PYTHONHOME + unset _OLD_VIRTUAL_PYTHONHOME + fi + + # Call hash to forget past commands. Without forgetting + # past commands the $PATH changes we made may not be respected + hash -r 2> /dev/null + + if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then + PS1="${_OLD_VIRTUAL_PS1:-}" + export PS1 + unset _OLD_VIRTUAL_PS1 + fi + + unset VIRTUAL_ENV + unset VIRTUAL_ENV_PROMPT + if [ ! "${1:-}" = "nondestructive" ] ; then + # Self destruct! + unset -f deactivate + fi +} + +# unset irrelevant variables +deactivate nondestructive + +# on Windows, a path can contain colons and backslashes and has to be converted: +if [ "${OSTYPE:-}" = "cygwin" ] || [ "${OSTYPE:-}" = "msys" ] ; then + # transform D:\path\to\venv to /d/path/to/venv on MSYS + # and to /cygdrive/d/path/to/venv on Cygwin + export VIRTUAL_ENV=$(cygpath /home/varshini-adurti/ContainerOps/proxy_server/.venv-proxy) +else + # use the path as-is + export VIRTUAL_ENV=/home/varshini-adurti/ContainerOps/proxy_server/.venv-proxy +fi + +_OLD_VIRTUAL_PATH="$PATH" +PATH="$VIRTUAL_ENV/"bin":$PATH" +export PATH + +# unset PYTHONHOME if set +# this will fail if PYTHONHOME is set to the empty string (which is bad anyway) +# could use `if (set -u; : $PYTHONHOME) ;` in bash +if [ -n "${PYTHONHOME:-}" ] ; then + _OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}" + unset PYTHONHOME +fi + +if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then + _OLD_VIRTUAL_PS1="${PS1:-}" + PS1='(.venv-proxy) '"${PS1:-}" + export PS1 + VIRTUAL_ENV_PROMPT='(.venv-proxy) ' + export VIRTUAL_ENV_PROMPT +fi + +# Call hash to forget past commands. Without forgetting +# past commands the $PATH changes we made may not be respected +hash -r 2> /dev/null diff --git a/proxy_server/.venv-proxy/bin/activate.csh b/proxy_server/.venv-proxy/bin/activate.csh new file mode 100644 index 0000000..3eda2d2 --- /dev/null +++ b/proxy_server/.venv-proxy/bin/activate.csh @@ -0,0 +1,27 @@ +# This file must be used with "source bin/activate.csh" *from csh*. +# You cannot run it directly. + +# Created by Davide Di Blasi . +# Ported to Python 3.3 venv by Andrew Svetlov + +alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; unsetenv VIRTUAL_ENV_PROMPT; test "\!:*" != "nondestructive" && unalias deactivate' + +# Unset irrelevant variables. +deactivate nondestructive + +setenv VIRTUAL_ENV /home/varshini-adurti/ContainerOps/proxy_server/.venv-proxy + +set _OLD_VIRTUAL_PATH="$PATH" +setenv PATH "$VIRTUAL_ENV/"bin":$PATH" + + +set _OLD_VIRTUAL_PROMPT="$prompt" + +if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then + set prompt = '(.venv-proxy) '"$prompt" + setenv VIRTUAL_ENV_PROMPT '(.venv-proxy) ' +endif + +alias pydoc python -m pydoc + +rehash diff --git a/proxy_server/.venv-proxy/bin/activate.fish b/proxy_server/.venv-proxy/bin/activate.fish new file mode 100644 index 0000000..cd0bc8d --- /dev/null +++ b/proxy_server/.venv-proxy/bin/activate.fish @@ -0,0 +1,69 @@ +# This file must be used with "source /bin/activate.fish" *from fish* +# (https://fishshell.com/). You cannot run it directly. + +function deactivate -d "Exit virtual environment and return to normal shell environment" + # reset old environment variables + if test -n "$_OLD_VIRTUAL_PATH" + set -gx PATH $_OLD_VIRTUAL_PATH + set -e _OLD_VIRTUAL_PATH + end + if test -n "$_OLD_VIRTUAL_PYTHONHOME" + set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME + set -e _OLD_VIRTUAL_PYTHONHOME + end + + if test -n "$_OLD_FISH_PROMPT_OVERRIDE" + set -e _OLD_FISH_PROMPT_OVERRIDE + # prevents error when using nested fish instances (Issue #93858) + if functions -q _old_fish_prompt + functions -e fish_prompt + functions -c _old_fish_prompt fish_prompt + functions -e _old_fish_prompt + end + end + + set -e VIRTUAL_ENV + set -e VIRTUAL_ENV_PROMPT + if test "$argv[1]" != "nondestructive" + # Self-destruct! + functions -e deactivate + end +end + +# Unset irrelevant variables. +deactivate nondestructive + +set -gx VIRTUAL_ENV /home/varshini-adurti/ContainerOps/proxy_server/.venv-proxy + +set -gx _OLD_VIRTUAL_PATH $PATH +set -gx PATH "$VIRTUAL_ENV/"bin $PATH + +# Unset PYTHONHOME if set. +if set -q PYTHONHOME + set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME + set -e PYTHONHOME +end + +if test -z "$VIRTUAL_ENV_DISABLE_PROMPT" + # fish uses a function instead of an env var to generate the prompt. + + # Save the current fish_prompt function as the function _old_fish_prompt. + functions -c fish_prompt _old_fish_prompt + + # With the original prompt function renamed, we can override with our own. + function fish_prompt + # Save the return status of the last command. + set -l old_status $status + + # Output the venv prompt; color taken from the blue of the Python logo. + printf "%s%s%s" (set_color 4B8BBE) '(.venv-proxy) ' (set_color normal) + + # Restore the return status of the previous command. + echo "exit $old_status" | . + # Output the original/"old" prompt. + _old_fish_prompt + end + + set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV" + set -gx VIRTUAL_ENV_PROMPT '(.venv-proxy) ' +end diff --git a/proxy_server/.venv-proxy/bin/django-admin b/proxy_server/.venv-proxy/bin/django-admin new file mode 100644 index 0000000..759ff01 --- /dev/null +++ b/proxy_server/.venv-proxy/bin/django-admin @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/proxy_server/.venv-proxy/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from django.core.management import execute_from_command_line +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(execute_from_command_line()) diff --git a/proxy_server/.venv-proxy/bin/dotenv b/proxy_server/.venv-proxy/bin/dotenv new file mode 100644 index 0000000..206e001 --- /dev/null +++ b/proxy_server/.venv-proxy/bin/dotenv @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/proxy_server/.venv-proxy/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from dotenv.__main__ import cli +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(cli()) diff --git a/proxy_server/.venv-proxy/bin/jp.py b/proxy_server/.venv-proxy/bin/jp.py new file mode 100644 index 0000000..4673408 --- /dev/null +++ b/proxy_server/.venv-proxy/bin/jp.py @@ -0,0 +1,54 @@ +#!/home/varshini-adurti/ContainerOps/proxy_server/.venv-proxy/bin/python3 + +import sys +import json +import argparse +from pprint import pformat + +import jmespath +from jmespath import exceptions + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('expression') + parser.add_argument('-f', '--filename', + help=('The filename containing the input data. ' + 'If a filename is not given then data is ' + 'read from stdin.')) + parser.add_argument('--ast', action='store_true', + help=('Pretty print the AST, do not search the data.')) + args = parser.parse_args() + expression = args.expression + if args.ast: + # Only print the AST + expression = jmespath.compile(args.expression) + sys.stdout.write(pformat(expression.parsed)) + sys.stdout.write('\n') + return 0 + if args.filename: + with open(args.filename, 'r') as f: + data = json.load(f) + else: + data = sys.stdin.read() + data = json.loads(data) + try: + sys.stdout.write(json.dumps( + jmespath.search(expression, data), indent=4, ensure_ascii=False)) + sys.stdout.write('\n') + except exceptions.ArityError as e: + sys.stderr.write("invalid-arity: %s\n" % e) + return 1 + except exceptions.JMESPathTypeError as e: + sys.stderr.write("invalid-type: %s\n" % e) + return 1 + except exceptions.UnknownFunctionError as e: + sys.stderr.write("unknown-function: %s\n" % e) + return 1 + except exceptions.ParseError as e: + sys.stderr.write("syntax-error: %s\n" % e) + return 1 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/proxy_server/.venv-proxy/bin/normalizer b/proxy_server/.venv-proxy/bin/normalizer new file mode 100644 index 0000000..83b48c0 --- /dev/null +++ b/proxy_server/.venv-proxy/bin/normalizer @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/proxy_server/.venv-proxy/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from charset_normalizer.cli import cli_detect +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(cli_detect()) diff --git a/proxy_server/.venv-proxy/bin/pip b/proxy_server/.venv-proxy/bin/pip new file mode 100644 index 0000000..0029a35 --- /dev/null +++ b/proxy_server/.venv-proxy/bin/pip @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/proxy_server/.venv-proxy/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/proxy_server/.venv-proxy/bin/pip3 b/proxy_server/.venv-proxy/bin/pip3 new file mode 100644 index 0000000..0029a35 --- /dev/null +++ b/proxy_server/.venv-proxy/bin/pip3 @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/proxy_server/.venv-proxy/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/proxy_server/.venv-proxy/bin/pip3.12 b/proxy_server/.venv-proxy/bin/pip3.12 new file mode 100644 index 0000000..0029a35 --- /dev/null +++ b/proxy_server/.venv-proxy/bin/pip3.12 @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/proxy_server/.venv-proxy/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/proxy_server/.venv-proxy/bin/pyrsa-decrypt b/proxy_server/.venv-proxy/bin/pyrsa-decrypt new file mode 100644 index 0000000..d11a2ba --- /dev/null +++ b/proxy_server/.venv-proxy/bin/pyrsa-decrypt @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/proxy_server/.venv-proxy/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from rsa.cli import decrypt +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(decrypt()) diff --git a/proxy_server/.venv-proxy/bin/pyrsa-encrypt b/proxy_server/.venv-proxy/bin/pyrsa-encrypt new file mode 100644 index 0000000..cdc043c --- /dev/null +++ b/proxy_server/.venv-proxy/bin/pyrsa-encrypt @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/proxy_server/.venv-proxy/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from rsa.cli import encrypt +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(encrypt()) diff --git a/proxy_server/.venv-proxy/bin/pyrsa-keygen b/proxy_server/.venv-proxy/bin/pyrsa-keygen new file mode 100644 index 0000000..17f0196 --- /dev/null +++ b/proxy_server/.venv-proxy/bin/pyrsa-keygen @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/proxy_server/.venv-proxy/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from rsa.cli import keygen +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(keygen()) diff --git a/proxy_server/.venv-proxy/bin/pyrsa-priv2pub b/proxy_server/.venv-proxy/bin/pyrsa-priv2pub new file mode 100644 index 0000000..a1c04d8 --- /dev/null +++ b/proxy_server/.venv-proxy/bin/pyrsa-priv2pub @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/proxy_server/.venv-proxy/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from rsa.util import private_to_public +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(private_to_public()) diff --git a/proxy_server/.venv-proxy/bin/pyrsa-sign b/proxy_server/.venv-proxy/bin/pyrsa-sign new file mode 100644 index 0000000..5d57a09 --- /dev/null +++ b/proxy_server/.venv-proxy/bin/pyrsa-sign @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/proxy_server/.venv-proxy/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from rsa.cli import sign +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(sign()) diff --git a/proxy_server/.venv-proxy/bin/pyrsa-verify b/proxy_server/.venv-proxy/bin/pyrsa-verify new file mode 100644 index 0000000..5360fcb --- /dev/null +++ b/proxy_server/.venv-proxy/bin/pyrsa-verify @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/proxy_server/.venv-proxy/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from rsa.cli import verify +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(verify()) diff --git a/proxy_server/.venv-proxy/bin/python b/proxy_server/.venv-proxy/bin/python new file mode 120000 index 0000000..b8a0adb --- /dev/null +++ b/proxy_server/.venv-proxy/bin/python @@ -0,0 +1 @@ +python3 \ No newline at end of file diff --git a/proxy_server/.venv-proxy/bin/python3 b/proxy_server/.venv-proxy/bin/python3 new file mode 120000 index 0000000..ae65fda --- /dev/null +++ b/proxy_server/.venv-proxy/bin/python3 @@ -0,0 +1 @@ +/usr/bin/python3 \ No newline at end of file diff --git a/proxy_server/.venv-proxy/bin/python3.12 b/proxy_server/.venv-proxy/bin/python3.12 new file mode 120000 index 0000000..b8a0adb --- /dev/null +++ b/proxy_server/.venv-proxy/bin/python3.12 @@ -0,0 +1 @@ +python3 \ No newline at end of file diff --git a/proxy_server/.venv-proxy/bin/rst2html.py b/proxy_server/.venv-proxy/bin/rst2html.py new file mode 100644 index 0000000..dccbc3a --- /dev/null +++ b/proxy_server/.venv-proxy/bin/rst2html.py @@ -0,0 +1,23 @@ +#!/home/varshini-adurti/ContainerOps/proxy_server/.venv-proxy/bin/python3 + +# $Id: rst2html.py 4564 2006-05-21 20:44:42Z wiemann $ +# Author: David Goodger +# Copyright: This module has been placed in the public domain. + +""" +A minimal front end to the Docutils Publisher, producing HTML. +""" + +try: + import locale + locale.setlocale(locale.LC_ALL, '') +except: + pass + +from docutils.core import publish_cmdline, default_description + + +description = ('Generates (X)HTML documents from standalone reStructuredText ' + 'sources. ' + default_description) + +publish_cmdline(writer_name='html', description=description) diff --git a/proxy_server/.venv-proxy/bin/rst2html4.py b/proxy_server/.venv-proxy/bin/rst2html4.py new file mode 100644 index 0000000..ace48c5 --- /dev/null +++ b/proxy_server/.venv-proxy/bin/rst2html4.py @@ -0,0 +1,26 @@ +#!/home/varshini-adurti/ContainerOps/proxy_server/.venv-proxy/bin/python3 + +# $Id: rst2html4.py 7994 2016-12-10 17:41:45Z milde $ +# Author: David Goodger +# Copyright: This module has been placed in the public domain. + +""" +A minimal front end to the Docutils Publisher, producing (X)HTML. + +The output conforms to XHTML 1.0 transitional +and almost to HTML 4.01 transitional (except for closing empty tags). +""" + +try: + import locale + locale.setlocale(locale.LC_ALL, '') +except: + pass + +from docutils.core import publish_cmdline, default_description + + +description = ('Generates (X)HTML documents from standalone reStructuredText ' + 'sources. ' + default_description) + +publish_cmdline(writer_name='html4', description=description) diff --git a/proxy_server/.venv-proxy/bin/rst2html5.py b/proxy_server/.venv-proxy/bin/rst2html5.py new file mode 100644 index 0000000..5454ab6 --- /dev/null +++ b/proxy_server/.venv-proxy/bin/rst2html5.py @@ -0,0 +1,35 @@ +#!/home/varshini-adurti/ContainerOps/proxy_server/.venv-proxy/bin/python3 +# -*- coding: utf8 -*- +# :Copyright: © 2015 Günter Milde. +# :License: Released under the terms of the `2-Clause BSD license`_, in short: +# +# Copying and distribution of this file, with or without modification, +# are permitted in any medium without royalty provided the copyright +# notice and this notice are preserved. +# This file is offered as-is, without any warranty. +# +# .. _2-Clause BSD license: http://www.spdx.org/licenses/BSD-2-Clause +# +# Revision: $Revision: 8410 $ +# Date: $Date: 2019-11-04 22:14:43 +0100 (Mo, 04. Nov 2019) $ + +""" +A minimal front end to the Docutils Publisher, producing HTML 5 documents. + +The output also conforms to XHTML 1.0 transitional +(except for the doctype declaration). +""" + +try: + import locale # module missing in Jython + locale.setlocale(locale.LC_ALL, '') +except locale.Error: + pass + +from docutils.core import publish_cmdline, default_description + +description = (u'Generates HTML 5 documents from standalone ' + u'reStructuredText sources ' + + default_description) + +publish_cmdline(writer_name='html5', description=description) diff --git a/proxy_server/.venv-proxy/bin/rst2latex.py b/proxy_server/.venv-proxy/bin/rst2latex.py new file mode 100644 index 0000000..3bd1830 --- /dev/null +++ b/proxy_server/.venv-proxy/bin/rst2latex.py @@ -0,0 +1,26 @@ +#!/home/varshini-adurti/ContainerOps/proxy_server/.venv-proxy/bin/python3 + +# $Id: rst2latex.py 5905 2009-04-16 12:04:49Z milde $ +# Author: David Goodger +# Copyright: This module has been placed in the public domain. + +""" +A minimal front end to the Docutils Publisher, producing LaTeX. +""" + +try: + import locale + locale.setlocale(locale.LC_ALL, '') +except: + pass + +from docutils.core import publish_cmdline + +description = ('Generates LaTeX documents from standalone reStructuredText ' + 'sources. ' + 'Reads from (default is stdin) and writes to ' + ' (default is stdout). See ' + ' for ' + 'the full reference.') + +publish_cmdline(writer_name='latex', description=description) diff --git a/proxy_server/.venv-proxy/bin/rst2man.py b/proxy_server/.venv-proxy/bin/rst2man.py new file mode 100644 index 0000000..bf3611f --- /dev/null +++ b/proxy_server/.venv-proxy/bin/rst2man.py @@ -0,0 +1,26 @@ +#!/home/varshini-adurti/ContainerOps/proxy_server/.venv-proxy/bin/python3 + +# Author: +# Contact: grubert@users.sf.net +# Copyright: This module has been placed in the public domain. + +""" +man.py +====== + +This module provides a simple command line interface that uses the +man page writer to output from ReStructuredText source. +""" + +import locale +try: + locale.setlocale(locale.LC_ALL, '') +except: + pass + +from docutils.core import publish_cmdline, default_description +from docutils.writers import manpage + +description = ("Generates plain unix manual documents. " + default_description) + +publish_cmdline(writer=manpage.Writer(), description=description) diff --git a/proxy_server/.venv-proxy/bin/rst2odt.py b/proxy_server/.venv-proxy/bin/rst2odt.py new file mode 100644 index 0000000..e68612f --- /dev/null +++ b/proxy_server/.venv-proxy/bin/rst2odt.py @@ -0,0 +1,30 @@ +#!/home/varshini-adurti/ContainerOps/proxy_server/.venv-proxy/bin/python3 + +# $Id: rst2odt.py 5839 2009-01-07 19:09:28Z dkuhlman $ +# Author: Dave Kuhlman +# Copyright: This module has been placed in the public domain. + +""" +A front end to the Docutils Publisher, producing OpenOffice documents. +""" + +import sys +try: + import locale + locale.setlocale(locale.LC_ALL, '') +except: + pass + +from docutils.core import publish_cmdline_to_binary, default_description +from docutils.writers.odf_odt import Writer, Reader + + +description = ('Generates OpenDocument/OpenOffice/ODF documents from ' + 'standalone reStructuredText sources. ' + default_description) + + +writer = Writer() +reader = Reader() +output = publish_cmdline_to_binary(reader=reader, writer=writer, + description=description) + diff --git a/proxy_server/.venv-proxy/bin/rst2odt_prepstyles.py b/proxy_server/.venv-proxy/bin/rst2odt_prepstyles.py new file mode 100644 index 0000000..8558507 --- /dev/null +++ b/proxy_server/.venv-proxy/bin/rst2odt_prepstyles.py @@ -0,0 +1,67 @@ +#!/home/varshini-adurti/ContainerOps/proxy_server/.venv-proxy/bin/python3 + +# $Id: rst2odt_prepstyles.py 8346 2019-08-26 12:11:32Z milde $ +# Author: Dave Kuhlman +# Copyright: This module has been placed in the public domain. + +""" +Fix a word-processor-generated styles.odt for odtwriter use: Drop page size +specifications from styles.xml in STYLE_FILE.odt. +""" + +# Author: Michael Schutte + +from __future__ import print_function + +from lxml import etree +import sys +import zipfile +from tempfile import mkstemp +import shutil +import os + +NAMESPACES = { + "style": "urn:oasis:names:tc:opendocument:xmlns:style:1.0", + "fo": "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" +} + + +def prepstyle(filename): + + zin = zipfile.ZipFile(filename) + styles = zin.read("styles.xml") + + root = etree.fromstring(styles) + for el in root.xpath("//style:page-layout-properties", + namespaces=NAMESPACES): + for attr in el.attrib: + if attr.startswith("{%s}" % NAMESPACES["fo"]): + del el.attrib[attr] + + tempname = mkstemp() + zout = zipfile.ZipFile(os.fdopen(tempname[0], "w"), "w", + zipfile.ZIP_DEFLATED) + + for item in zin.infolist(): + if item.filename == "styles.xml": + zout.writestr(item, etree.tostring(root)) + else: + zout.writestr(item, zin.read(item.filename)) + + zout.close() + zin.close() + shutil.move(tempname[1], filename) + + +def main(): + args = sys.argv[1:] + if len(args) != 1: + print(__doc__, file=sys.stderr) + print("Usage: %s STYLE_FILE.odt\n" % sys.argv[0], file=sys.stderr) + sys.exit(1) + filename = args[0] + prepstyle(filename) + + +if __name__ == '__main__': + main() diff --git a/proxy_server/.venv-proxy/bin/rst2pseudoxml.py b/proxy_server/.venv-proxy/bin/rst2pseudoxml.py new file mode 100644 index 0000000..cfa15c9 --- /dev/null +++ b/proxy_server/.venv-proxy/bin/rst2pseudoxml.py @@ -0,0 +1,23 @@ +#!/home/varshini-adurti/ContainerOps/proxy_server/.venv-proxy/bin/python3 + +# $Id: rst2pseudoxml.py 4564 2006-05-21 20:44:42Z wiemann $ +# Author: David Goodger +# Copyright: This module has been placed in the public domain. + +""" +A minimal front end to the Docutils Publisher, producing pseudo-XML. +""" + +try: + import locale + locale.setlocale(locale.LC_ALL, '') +except: + pass + +from docutils.core import publish_cmdline, default_description + + +description = ('Generates pseudo-XML from standalone reStructuredText ' + 'sources (for testing purposes). ' + default_description) + +publish_cmdline(description=description) diff --git a/proxy_server/.venv-proxy/bin/rst2s5.py b/proxy_server/.venv-proxy/bin/rst2s5.py new file mode 100644 index 0000000..fd1be36 --- /dev/null +++ b/proxy_server/.venv-proxy/bin/rst2s5.py @@ -0,0 +1,24 @@ +#!/home/varshini-adurti/ContainerOps/proxy_server/.venv-proxy/bin/python3 + +# $Id: rst2s5.py 4564 2006-05-21 20:44:42Z wiemann $ +# Author: Chris Liechti +# Copyright: This module has been placed in the public domain. + +""" +A minimal front end to the Docutils Publisher, producing HTML slides using +the S5 template system. +""" + +try: + import locale + locale.setlocale(locale.LC_ALL, '') +except: + pass + +from docutils.core import publish_cmdline, default_description + + +description = ('Generates S5 (X)HTML slideshow documents from standalone ' + 'reStructuredText sources. ' + default_description) + +publish_cmdline(writer_name='s5', description=description) diff --git a/proxy_server/.venv-proxy/bin/rst2xetex.py b/proxy_server/.venv-proxy/bin/rst2xetex.py new file mode 100644 index 0000000..724f478 --- /dev/null +++ b/proxy_server/.venv-proxy/bin/rst2xetex.py @@ -0,0 +1,27 @@ +#!/home/varshini-adurti/ContainerOps/proxy_server/.venv-proxy/bin/python3 + +# $Id: rst2xetex.py 7847 2015-03-17 17:30:47Z milde $ +# Author: Guenter Milde +# Copyright: This module has been placed in the public domain. + +""" +A minimal front end to the Docutils Publisher, producing Lua/XeLaTeX code. +""" + +try: + import locale + locale.setlocale(locale.LC_ALL, '') +except: + pass + +from docutils.core import publish_cmdline + +description = ('Generates LaTeX documents from standalone reStructuredText ' + 'sources for compilation with the Unicode-aware TeX variants ' + 'XeLaTeX or LuaLaTeX. ' + 'Reads from (default is stdin) and writes to ' + ' (default is stdout). See ' + ' for ' + 'the full reference.') + +publish_cmdline(writer_name='xetex', description=description) diff --git a/proxy_server/.venv-proxy/bin/rst2xml.py b/proxy_server/.venv-proxy/bin/rst2xml.py new file mode 100644 index 0000000..2fe11e7 --- /dev/null +++ b/proxy_server/.venv-proxy/bin/rst2xml.py @@ -0,0 +1,23 @@ +#!/home/varshini-adurti/ContainerOps/proxy_server/.venv-proxy/bin/python3 + +# $Id: rst2xml.py 4564 2006-05-21 20:44:42Z wiemann $ +# Author: David Goodger +# Copyright: This module has been placed in the public domain. + +""" +A minimal front end to the Docutils Publisher, producing Docutils XML. +""" + +try: + import locale + locale.setlocale(locale.LC_ALL, '') +except: + pass + +from docutils.core import publish_cmdline, default_description + + +description = ('Generates Docutils-native XML from standalone ' + 'reStructuredText sources. ' + default_description) + +publish_cmdline(writer_name='xml', description=description) diff --git a/proxy_server/.venv-proxy/bin/rstpep2html.py b/proxy_server/.venv-proxy/bin/rstpep2html.py new file mode 100644 index 0000000..14b64c4 --- /dev/null +++ b/proxy_server/.venv-proxy/bin/rstpep2html.py @@ -0,0 +1,25 @@ +#!/home/varshini-adurti/ContainerOps/proxy_server/.venv-proxy/bin/python3 + +# $Id: rstpep2html.py 4564 2006-05-21 20:44:42Z wiemann $ +# Author: David Goodger +# Copyright: This module has been placed in the public domain. + +""" +A minimal front end to the Docutils Publisher, producing HTML from PEP +(Python Enhancement Proposal) documents. +""" + +try: + import locale + locale.setlocale(locale.LC_ALL, '') +except: + pass + +from docutils.core import publish_cmdline, default_description + + +description = ('Generates (X)HTML from reStructuredText-format PEP files. ' + + default_description) + +publish_cmdline(reader_name='pep', writer_name='pep_html', + description=description) diff --git a/proxy_server/.venv-proxy/bin/sqlformat b/proxy_server/.venv-proxy/bin/sqlformat new file mode 100644 index 0000000..364ffdd --- /dev/null +++ b/proxy_server/.venv-proxy/bin/sqlformat @@ -0,0 +1,8 @@ +#!/home/varshini-adurti/ContainerOps/proxy_server/.venv-proxy/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from sqlparse.__main__ import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/proxy_server/.venv-proxy/lib64 b/proxy_server/.venv-proxy/lib64 new file mode 120000 index 0000000..7951405 --- /dev/null +++ b/proxy_server/.venv-proxy/lib64 @@ -0,0 +1 @@ +lib \ No newline at end of file diff --git a/proxy_server/.venv-proxy/pyvenv.cfg b/proxy_server/.venv-proxy/pyvenv.cfg new file mode 100644 index 0000000..9da264e --- /dev/null +++ b/proxy_server/.venv-proxy/pyvenv.cfg @@ -0,0 +1,5 @@ +home = /usr/bin +include-system-site-packages = false +version = 3.12.3 +executable = /usr/bin/python3.12 +command = /usr/bin/python3 -m venv /home/varshini-adurti/ContainerOps/proxy_server/.venv-proxy diff --git a/proxy_server/Dockerfile b/proxy_server/Dockerfile new file mode 100644 index 0000000..0074583 --- /dev/null +++ b/proxy_server/Dockerfile @@ -0,0 +1,18 @@ +FROM python:3.11-slim + +ENV PYTHONUNBUFFERED=1 \ + PYTHONDONTWRITEBYTECODE=1 + +WORKDIR /app + +RUN apt-get update && apt-get install -y --no-install-recommends \ + build-essential libpq-dev + +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt daphne + +COPY . . + +EXPOSE 8001 + +CMD ["python", "manage.py", "runserver", "0.0.0.0:8001"] \ No newline at end of file diff --git a/proxy_server/api/admin.py b/proxy_server/api/admin.py index 8c38f3f..ea5d68b 100644 --- a/proxy_server/api/admin.py +++ b/proxy_server/api/admin.py @@ -1,3 +1,3 @@ -from django.contrib import admin - -# Register your models here. +from django.contrib import admin + +# Register your models here. diff --git a/proxy_server/api/apps.py b/proxy_server/api/apps.py index 66656fd..8e0045c 100644 --- a/proxy_server/api/apps.py +++ b/proxy_server/api/apps.py @@ -1,6 +1,6 @@ -from django.apps import AppConfig - - -class ApiConfig(AppConfig): - default_auto_field = 'django.db.models.BigAutoField' - name = 'api' +from django.apps import AppConfig + + +class ApiConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'api' diff --git a/proxy_server/api/models.py b/proxy_server/api/models.py index 71a8362..fd18c6e 100644 --- a/proxy_server/api/models.py +++ b/proxy_server/api/models.py @@ -1,3 +1,3 @@ -from django.db import models - -# Create your models here. +from django.db import models + +# Create your models here. diff --git a/proxy_server/api/store.py b/proxy_server/api/store.py index c2e4e8a..df0ddeb 100644 --- a/proxy_server/api/store.py +++ b/proxy_server/api/store.py @@ -1,3 +1,3 @@ -#create a mapping to store id:PORT -store = {} +#create a mapping to store id:PORT +store = {} PORT=4000; \ No newline at end of file diff --git a/proxy_server/api/tests.py b/proxy_server/api/tests.py index 7ce503c..de8bdc0 100644 --- a/proxy_server/api/tests.py +++ b/proxy_server/api/tests.py @@ -1,3 +1,3 @@ -from django.test import TestCase - -# Create your tests here. +from django.test import TestCase + +# Create your tests here. diff --git a/proxy_server/api/urls.py b/proxy_server/api/urls.py index 3331a12..ee8293c 100644 --- a/proxy_server/api/urls.py +++ b/proxy_server/api/urls.py @@ -1,7 +1,7 @@ -from django.contrib import admin -from django.urls import path -from .views import webhook - -urlpatterns = [ - path('webhook/',webhook,name='webhook'), +from django.contrib import admin +from django.urls import path +from .views import webhook + +urlpatterns = [ + path('webhook/',webhook,name='webhook'), ] \ No newline at end of file diff --git a/proxy_server/api/views.py b/proxy_server/api/views.py index 13ea7f3..25228ee 100644 --- a/proxy_server/api/views.py +++ b/proxy_server/api/views.py @@ -6,6 +6,9 @@ from .store import PORT import os import docker + +# import threading + # Create your views here. def update_nginx_config(config_file, base_url, conditions): @@ -41,7 +44,122 @@ def update_nginx_config(config_file, base_url, conditions): with open(config_file, "w") as file: file.write("\n".join(data)) - +# def run_in_background(data, base_url): +# global PORT +# client = docker.from_env() + +# try: +# if data['work'] == 'redeploy': + +# old_id = data['id'] + +# if old_id in store: +# port = store[old_id] + + +# old_container = client.containers.get(old_id) +# old_container.stop() +# old_container.remove() + + +# new_container = client.containers.run( +# data['image_name'], +# detach=True, +# ports={data['image_port']: port} +# ) + + +# store[new_container.id] = port +# print(f"Redeployed {data['image_name']} on port {port}") + +# else: +# print("Old container not found in store.") + +# else: +# new_container = client.containers.run( +# data['image_name'], +# detach=True, +# ports={data['image_port']: PORT} +# ) + + +# store[new_container.id] = PORT +# PORT += 1 +# print(f"Deployed new container on port {PORT - 1}") + + +# threading.Thread( +# target=update_nginx_config, +# args=("./test", base_url, store) +# ).start() + +# except Exception as e: +# print(f"Error in Docker operation: {str(e)}") + + +# @csrf_exempt +# def webhook(request): +# if request.method == 'POST': +# print("Webhook called") + +# try: +# data = json.loads(request.body) +# base_url = "http://172.25.96.1" + +# threading.Thread( +# target=run_in_background, +# args=(data, base_url) +# ).start() +# return JsonResponse({"status": "accepted", "message": "Deployment started in the background."}, status=202) + +# except Exception as e: +# return JsonResponse({"status": "error", "message": str(e)}, status=500) + +# return JsonResponse({"status": "error", "message": "Invalid request method"}, status=400) + + + +# def stop_container(request): +# if request.method == 'POST': +# try: +# data = json.loads(request.body) +# container_id = data['id'] + +# def stop_in_background(): +# client = docker.from_env() +# try: +# if container_id in store: +# # Stop and remove the container +# container = client.containers.get(container_id) +# container.stop() +# container.remove() + +# # Remove the entry from the store +# del store[container_id] + +# # Update NGINX config in background +# threading.Thread( +# target=update_nginx_config, +# args=("./test", "http://172.25.96.1", store) +# ).start() + +# print(f"Container {container_id} stopped and removed.") + +# except Exception as e: +# print(f"Error stopping container {container_id}: {str(e)}") + +# # Run in background +# threading.Thread(target=stop_in_background).start() + +# # Return immediate response +# return JsonResponse({"status": "accepted", "message": "Container stop initiated."}, status=202) + +# except Exception as e: +# return JsonResponse({"status": "error", "message": str(e)}, status=500) + +# return JsonResponse({"status": "error", "message": "Invalid request method"}, status=400) + + @csrf_exempt def webhook(request): global PORT @@ -61,17 +179,17 @@ def webhook(request): #remove the container client.containers.get(id).remove() #rerun the container - client.containers.run(data['image_name'],detach=True,ports={data['image_port']:port}) - return JsonResponse({"status": "ok"}) + new_container = client.containers.run(data['image_name'],detach=True,ports={data['image_port']:port}) + return JsonResponse({"status": "ok", "container_id": new_container.id}) - client.containers.run(data['image_name'],detach=True,ports={data['image_port']:PORT}) + new_container = client.containers.run(data['image_name'],detach=True,ports={data['image_port']:PORT}) #update the store store[data['id']] = PORT PORT+=1 #update the nginx configuration update_nginx_config("./test","http://172.25.96.1",store) - return JsonResponse({"status": "ok"}) + return JsonResponse({"status": "ok", "container_id": new_container.id}) def stop_container(request): if(request.method=='POST'): diff --git a/proxy_server/manage.py b/proxy_server/manage.py index 6eb25da..414b1eb 100755 --- a/proxy_server/manage.py +++ b/proxy_server/manage.py @@ -1,22 +1,22 @@ -#!/usr/bin/env python -"""Django's command-line utility for administrative tasks.""" -import os -import sys - - -def main(): - """Run administrative tasks.""" - os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'proxy_server.settings') - try: - from django.core.management import execute_from_command_line - except ImportError as exc: - raise ImportError( - "Couldn't import Django. Are you sure it's installed and " - "available on your PYTHONPATH environment variable? Did you " - "forget to activate a virtual environment?" - ) from exc - execute_from_command_line(sys.argv) - - -if __name__ == '__main__': - main() +#!/usr/bin/env python +"""Django's command-line utility for administrative tasks.""" +import os +import sys + + +def main(): + """Run administrative tasks.""" + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'proxy_server.settings') + try: + from django.core.management import execute_from_command_line + except ImportError as exc: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) from exc + execute_from_command_line(sys.argv) + + +if __name__ == '__main__': + main() diff --git a/proxy_server/proxy_server/asgi.py b/proxy_server/proxy_server/asgi.py index e7592fc..b16a94b 100644 --- a/proxy_server/proxy_server/asgi.py +++ b/proxy_server/proxy_server/asgi.py @@ -1,16 +1,16 @@ -""" -ASGI config for proxy_server project. - -It exposes the ASGI callable as a module-level variable named ``application``. - -For more information on this file, see -https://docs.djangoproject.com/en/5.1/howto/deployment/asgi/ -""" - -import os - -from django.core.asgi import get_asgi_application - -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'proxy_server.settings') - -application = get_asgi_application() +""" +ASGI config for proxy_server project. + +It exposes the ASGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/5.1/howto/deployment/asgi/ +""" + +import os + +from django.core.asgi import get_asgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'proxy_server.settings') + +application = get_asgi_application() diff --git a/proxy_server/proxy_server/settings.py b/proxy_server/proxy_server/settings.py index 03f19ab..b8110bc 100644 --- a/proxy_server/proxy_server/settings.py +++ b/proxy_server/proxy_server/settings.py @@ -1,125 +1,125 @@ -""" -Django settings for proxy_server project. - -Generated by 'django-admin startproject' using Django 5.1.4. - -For more information on this file, see -https://docs.djangoproject.com/en/5.1/topics/settings/ - -For the full list of settings and their values, see -https://docs.djangoproject.com/en/5.1/ref/settings/ -""" - -from pathlib import Path - -# Build paths inside the project like this: BASE_DIR / 'subdir'. -BASE_DIR = Path(__file__).resolve().parent.parent - -APPEND_SLASH=False -# Quick-start development settings - unsuitable for production -# See https://docs.djangoproject.com/en/5.1/howto/deployment/checklist/ - -# SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = 'django-insecure-ii%8v%i6$4w8)m_l4)$zf=fy1zt6eg*axs4qggu^=7j_tk0=ls' - -# SECURITY WARNING: don't run with debug turned on in production! -DEBUG = True - -ALLOWED_HOSTS = [] - - -# Application definition - -INSTALLED_APPS = [ - 'django.contrib.admin', - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.messages', - 'django.contrib.staticfiles', - 'api', - "rest_framework", -] - -MIDDLEWARE = [ - 'django.middleware.security.SecurityMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.clickjacking.XFrameOptionsMiddleware', -] - -ROOT_URLCONF = 'proxy_server.urls' - -TEMPLATES = [ - { - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [], - 'APP_DIRS': True, - 'OPTIONS': { - 'context_processors': [ - 'django.template.context_processors.debug', - 'django.template.context_processors.request', - 'django.contrib.auth.context_processors.auth', - 'django.contrib.messages.context_processors.messages', - ], - }, - }, -] - -WSGI_APPLICATION = 'proxy_server.wsgi.application' - - -# Database -# https://docs.djangoproject.com/en/5.1/ref/settings/#databases - -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': BASE_DIR / 'db.sqlite3', - } -} - - -# Password validation -# https://docs.djangoproject.com/en/5.1/ref/settings/#auth-password-validators - -AUTH_PASSWORD_VALIDATORS = [ - { - 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', - }, - { - 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', - }, - { - 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', - }, - { - 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', - }, -] - - -# Internationalization -# https://docs.djangoproject.com/en/5.1/topics/i18n/ - -LANGUAGE_CODE = 'en-us' - -TIME_ZONE = 'UTC' - -USE_I18N = True - -USE_TZ = True - - -# Static files (CSS, JavaScript, Images) -# https://docs.djangoproject.com/en/5.1/howto/static-files/ - -STATIC_URL = 'static/' - -# Default primary key field type -# https://docs.djangoproject.com/en/5.1/ref/settings/#default-auto-field - -DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' +""" +Django settings for proxy_server project. + +Generated by 'django-admin startproject' using Django 5.1.4. + +For more information on this file, see +https://docs.djangoproject.com/en/5.1/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/5.1/ref/settings/ +""" + +from pathlib import Path + +# Build paths inside the project like this: BASE_DIR / 'subdir'. +BASE_DIR = Path(__file__).resolve().parent.parent + +APPEND_SLASH=False +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/5.1/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = 'django-insecure-ii%8v%i6$4w8)m_l4)$zf=fy1zt6eg*axs4qggu^=7j_tk0=ls' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = [] + + +# Application definition + +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'api', + "rest_framework", +] + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'proxy_server.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'proxy_server.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/5.1/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': BASE_DIR / 'db.sqlite3', + } +} + + +# Password validation +# https://docs.djangoproject.com/en/5.1/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/5.1/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'UTC' + +USE_I18N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/5.1/howto/static-files/ + +STATIC_URL = 'static/' + +# Default primary key field type +# https://docs.djangoproject.com/en/5.1/ref/settings/#default-auto-field + +DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' diff --git a/proxy_server/proxy_server/urls.py b/proxy_server/proxy_server/urls.py index 8fc0aab..5c43cb0 100644 --- a/proxy_server/proxy_server/urls.py +++ b/proxy_server/proxy_server/urls.py @@ -1,23 +1,23 @@ -""" -URL configuration for proxy_server project. - -The `urlpatterns` list routes URLs to views. For more information please see: - https://docs.djangoproject.com/en/5.1/topics/http/urls/ -Examples: -Function views - 1. Add an import: from my_app import views - 2. Add a URL to urlpatterns: path('', views.home, name='home') -Class-based views - 1. Add an import: from other_app.views import Home - 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') -Including another URLconf - 1. Import the include() function: from django.urls import include, path - 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) -""" -from django.contrib import admin -from django.urls import path,include - -urlpatterns = [ - path('admin/', admin.site.urls), - path('api/',include('api.urls')) -] +""" +URL configuration for proxy_server project. + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/5.1/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: path('', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') +Including another URLconf + 1. Import the include() function: from django.urls import include, path + 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) +""" +from django.contrib import admin +from django.urls import path,include + +urlpatterns = [ + path('admin/', admin.site.urls), + path('api/',include('api.urls')) +] diff --git a/proxy_server/proxy_server/wsgi.py b/proxy_server/proxy_server/wsgi.py index 3241607..edcb962 100644 --- a/proxy_server/proxy_server/wsgi.py +++ b/proxy_server/proxy_server/wsgi.py @@ -1,16 +1,16 @@ -""" -WSGI config for proxy_server project. - -It exposes the WSGI callable as a module-level variable named ``application``. - -For more information on this file, see -https://docs.djangoproject.com/en/5.1/howto/deployment/wsgi/ -""" - -import os - -from django.core.wsgi import get_wsgi_application - -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'proxy_server.settings') - -application = get_wsgi_application() +""" +WSGI config for proxy_server project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/5.1/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'proxy_server.settings') + +application = get_wsgi_application() diff --git a/proxy_server/requirements.txt b/proxy_server/requirements.txt index 68cea46..ac9b121 100644 --- a/proxy_server/requirements.txt +++ b/proxy_server/requirements.txt @@ -4,23 +4,33 @@ botocore==1.35.79 certifi==2024.8.30 charset-normalizer==3.4.0 colorama==0.4.6 -Django==5.1.5 +Django==4.2.19 +django-environ==0.12.0 +django-extensions==3.2.3 djangorestframework==3.15.2 docker==7.1.0 docutils==0.16 +environ==1.0 gitdb==4.0.11 GitPython==3.1.43 idna==3.10 jmespath==1.0.1 localstack-client==2.7 +psycopg==3.2.4 +psycopg2-binary==2.9.10 pyasn1==0.6.1 python-dateutil==2.9.0.post0 PyYAML==6.0.2 -requests==2.32.3 +requests==2.29.0 rsa==4.7.2 s3transfer==0.10.4 six==1.17.0 smmap==5.0.1 sqlparse==0.5.2 typing_extensions==4.12.2 -urllib3==2.2.3 +urllib3 +environ +channels +python-dotenv +social-auth-app-django +docker diff --git a/proxy_server/test b/proxy_server/test index ceb650a..068741e 100644 --- a/proxy_server/test +++ b/proxy_server/test @@ -4,8 +4,7 @@ events { http { map $subdomain $upstream { - 611883b794f67e5f82fd7e28ba580f483ac6bdb1bc3b9fde8d683acf61b5331f http://172.25.96.1:4000; - 7dc4c894da2f612a6b0b688710bffafde3fb28e2003d151385744f50d2263822 http://172.25.96.1:4001; + f9970c027dc596afb4805f6201969114846e928bdcf060717cdf1217ee8fa568 http://172.25.96.1:4000; default ""; }