Sign inSign up

pmsipilot/demoinstance

By pmsipilot

•Updated about 1 month ago

Web interface offering on-demand virtual machines instances with lifetime limits.

Image
1

2.9K

pmsipilot/demoinstance repository overview

⁠Project DemoInstance

DemoInstance is web interface offering on-demand virtual machines instances with lifetime limits.

⁠Interface example

Image of Demoinstance

⁠Dependencies

Python Python Python

  • Python 2.7
  • PIP
  • NodeJS & NPM
  • An underlying database system:
    • SQLite
    • MySQL

⁠Building and setting up

In order to use DemoInstance, you can:

⁠Install backend service

In order to install DemoInstance backend service:

$ git clone [email protected]:pmsipilot/demoinstance.git
$ cd demoinstance/backend/
$ sudo python2 ./setup.py install
⁠Prepare frontend sources

In order to prepare frontend sources:

$ cd frontend
$ npm install
$ node_modules/gulp/bin/gulp.js
⁠Set up web server

In this example, we'll be using the nginx webserver⁠:

  • Install nginx (according to your operating system documentation)
  • Configure nginx virtualhost
  • Restart nginx

Virtualhost example:

server {
       listen 8080;
       root /opt/demoinstance/frontend/;
       index index.html;
       location /api {
                proxy_pass http://127.0.0.1:8081;
       }
       location / {
                try_files $uri $uri/ =404;
       }
       location /instance_image/ {
                alias /etc/demoinstance/instance_image/;
                try_files $uri $uri/ =404;
       }
}
  • In this example, the webserver is listening on port 8080, frontend files are stored in /opt/demoinstance/frontend, and backend is listening on port 8081.
  • All /api requests must be passed to demoinstance backend service
  • /instance_imagerequests points to /etc/demoinstance/instance_image/ in this example.
  • Other requests are fulfilled with previously prepared frontend source code files.

Then, you must configure DemoInstance backend.

⁠Configuration

DemoInstance have a single ini config file : config.ini In this file you have many section.

⁠DEFAULT
[DEFAULT]
log_level=DEBUG
security_type=open
ArgumentOptionalDescription
log_levelNolist of value here https://docs.python.org/2/library/logging.html#logging-levels⁠
security_typeNoValues "open" (public), "email" (check email before access), "auth_ldap" or "auth_fake" (test only)
providerNoValues "openstack" or "fake" (test only)
devYesDefault to False, raise http exception
⁠MAIL
[MAIL]
host=smtp.gmail.com
port=587
user=user
password=password
[email protected]
tls=yes
ArgumentOptionalDescription
hostNoSMTP Host
portYesSMTP Port default 25
userYesSMTP User
passwordYesSMTP Password
fromYesFrom mail default demoinstance@localhost
tlsYesSMTP is tls default no
⁠AUTH_LDAP

If you use security_type = auth_ldap

[AUTH_LDAP]
host=ldap://ldapOrActiveDirectoyHostname
bind_user=cn=read,OU=Users,dc=mydomain,dc=local
bind_password=readpassword
search_base=OU=Users,dc=abc-objectif,dc=local
login_attribute=sAMAccountName
email_attribute=mail
ArgumentOptionalDescription
hostNoLdap Host
bind_userYesLdap user to read ldap
bind_passwordYesLdap password
search_baseYesLimit valid user with this branch
login_attributeYesLdap attribute to use to login
email_attributeYesLdap attribute of email
adminYesList of admin login separate by coma
⁠PROV_OPENSTACK

If you use provider = openstack

[PROV_OPENSTACK]
user=user
password=password
tenant=project
url=http://srv-openstack:5000/v2.0
region=regionOne
ArgumentOptionalDescription
userNoopenstack user
passwordNoopenstack password
tenantNoopenstack tenant
urlNoopenstack keystone api url
regionYesopenstack region
networkYesopenstack network id
⁠HTTP
[HTTP]
port=8080
ArgumentOptionalDescription
portNointerface/api tcp port
⁠DATABASE
[DATABASE]
connection:mysql://root@localhost:3306/demo
ArgumentOptionalDescription
connectionNoSQLAlchemy connection string of database

Only tested with MySQL and SQLite

⁠IMAGE

[IMAGE] section is the template of any [IMAGE_].
You can define in this section variable shared with all [IMAGE_]. The [IMAGE] section do not define a runnable image, only section with [IMAGE_ImageName] format define runnable image.

Parameter in this section depends on which provider you are using. Moreover some parameters are used by DemoInstance itself

⁠config
ArgumentOptionalDescription
nameNoName of instance like "My cool app"
descNoLittle descrition like "This app is so cooooooool"
infoNoinfo display after the creation like : "Login/Password are<br />test/test""
time_defaultNoDefault instance life time in minute
time_max=80YesMax instance time life (activate time selection for user)
check_urlNourl to call to check if app is ready (%ip% is a placeholder with instance address)
soft_urlNourl of the app to redirect the user
max_instanceNomax number of instance
imgYesurl of picture. Can be in /instance_image or external link
poolyes(int) Pre start N instance, default 0
⁠Openstack image parameter

If you use provider = openstack you must / can add this parameter to your image configuration

ArgumentOptionalDescription
image_idNoOpenstack image id or name
flavor_idNoOpenstack flavor id or name
prefixNoOpenstack prefix name
user_datayesnova userdata to inject in the instance
metayesAdd meta to instance
⁠example

Example with only one instance:

[IMAGE]

[IMAGE_MYAPP]
name=MyAPP
desc=My first app
info=Login/Password are<br />test/test
img=/instance_image/example.png
image_id=MonImage1
flavor_id=m1.tiny
time_default=20
prefix=myapp_
check_url=http://%ip%/ok
soft_url=http://%ip%/
max_instance=10
pool=2
meta=disk=ssd,ram=ECC

Example with three instances

[IMAGE]
flavor_id=1

[IMAGE_MYAPP1]
name=MyAPP
desc=My first app
...

[IMAGE_MYAPP2]
name=MyNewAPP
desc=My second app
...


[IMAGE_MYAPP3]
name=MyLastAPP
desc=My last app
flavor_id=2
...

In this example just [IMAGE_MYAPP3] run with flavor_id=2 and other image run with flavor_id=1 defined in [IMAGE]

⁠Ini format Tips

Sometimes, you need a value to be on multi-line. To do that you can write your key:parameter like this:

user_data:#cloud-config
    password: mypassword
    chpasswd: { expire: False }
    ssh_pwauth: True

This is defined here : http://tools.ietf.org/html/rfc822.html⁠ on LONG HEADER FIELDS section

⁠Run Backend

/usr/local/bin/demoinstance -c /etc/demoinstance/config.ini

⁠Run w/ Docker

There is also a Docker Production-ready image: https://hub.docker.com/r/pmsipilot/demoinstance/⁠

docker run -v /path/to/config/and/instance_image:/etc/demoinstance/ -i pmsipilot/demoinstance
  • /etc/demoinstance/ must contain:
    • config.ini file
    • instance_image folder with instance images

⁠Init script

⁠Redhat/Centos

Template for Centos is avaible in ressources/rhel-init-demoinstance. Just link file to /etc/init.d.

ln -s /where/is/your/project /etc/init.d/demoinstance

Don't forget to add config file in /etc/sysconfig/demoinstance

cat <EOF /etc/sysconfig/demoinstance
# PID file
PIDFILE=/tmp/test.pid
# Log file
LOGFILE=/tmp/log.log
# Process's user
USER=demoinstance
# Demoinstance folder
DEMO_DIR=/opt/demoinstance
EOF
⁠Debian/Ubuntu

If you want this you can do it and make me a PR

⁠Contribute

If you want to contribute you're welcome. Just create issues or make some PR.

⁠Dev env

The development environment is built w/ Docker on top of the production-ready image, with docker-compose⁠

docker-compose up

A supervisord process will listen for changes in frontend files, and changes to backend source code will be directly applied.

⁠Run test

To run test just run this command on with an URL od demoinstance run with test/samples/config/config-fake.ini

python test.py -u -f -U http://127.0.0.1:8080
⁠Add auth system

To add a new auth system is really simple, just add a class in Demo/auth directory which is son of DemoAuth and just add 2 functions with this prototype :

    def __init__(self, config):
        pass
        
    #Must return email if ok or False
    def check_auth(self, user, password):
        pass

init parameter is just "config" which is a dictionnary of your config section.

Config section name must be your filename (without '.py') uppercase and your class name must be a transformation of your filename like this : 'auth_ldap.py => AuthLdap'

⁠Add a new provider

To add a new provider, write a class in Demo/provider which herit from DemoProv.

Tag summary

Content type

Image

Digest

sha256:23ed45bf9…

Size

303.3 MB

Last updated

about 1 month ago

docker pull pmsipilot/demoinstance