├── .gitignore ├── Dockerfile ├── Dockerfile-demo ├── LICENSE ├── Makefile ├── README.md ├── ansible_playbook ├── __init__.py ├── deploy.yml ├── hosts ├── requirements.yml ├── roles │ └── skip │ │ ├── defaults │ │ └── main.yml │ │ └── tasks │ │ └── main.yml ├── runplaybook.py ├── shared │ └── after-symlink.yml ├── skip.yml └── version.yml ├── demo ├── Dockerfile-Tomcat ├── bootstrap.sh ├── clean_all.sh ├── docker-compose-common.yml ├── docker-compose.yml ├── files │ ├── code │ │ └── etc │ │ │ ├── ansible │ │ │ └── roles │ │ │ │ └── carlosbuenosvinos.ansistrano-deploy │ │ │ │ ├── .gitignore │ │ │ │ ├── .travis.yml │ │ │ │ ├── LICENSE │ │ │ │ ├── README.md │ │ │ │ ├── TESTING.md │ │ │ │ ├── Vagrantfile │ │ │ │ ├── ansible.cfg │ │ │ │ ├── defaults │ │ │ │ └── main.yml │ │ │ │ ├── docs │ │ │ │ ├── ansistrano-flow.png │ │ │ │ └── figure.md │ │ │ │ ├── example │ │ │ │ ├── my-app │ │ │ │ │ └── index.html │ │ │ │ └── my-playbook │ │ │ │ │ ├── ansible.cfg │ │ │ │ │ ├── deploy.yml │ │ │ │ │ ├── hosts │ │ │ │ │ └── rollback.yml │ │ │ │ ├── meta │ │ │ │ ├── .galaxy_install_info │ │ │ │ └── main.yml │ │ │ │ ├── tasks │ │ │ │ ├── anon-stats.yml │ │ │ │ ├── cleanup.yml │ │ │ │ ├── empty.yml │ │ │ │ ├── main.yml │ │ │ │ ├── rsync-deploy.yml │ │ │ │ ├── setup.yml │ │ │ │ ├── symlink-shared.yml │ │ │ │ ├── symlink.yml │ │ │ │ ├── update-code.yml │ │ │ │ └── update-code │ │ │ │ │ ├── copy.yml │ │ │ │ │ ├── copy_unarchive.yml │ │ │ │ │ ├── download.yml │ │ │ │ │ ├── download_unarchive.yml │ │ │ │ │ ├── git.yml │ │ │ │ │ ├── rsync.yml │ │ │ │ │ ├── s3.yml │ │ │ │ │ ├── s3_unarchive.yml │ │ │ │ │ └── unarchive.yml │ │ │ │ └── test │ │ │ │ ├── tasks │ │ │ │ ├── create-internal-paths.yml │ │ │ │ └── create-shared-paths.yml │ │ │ │ └── test.yml │ │ │ └── ssh │ │ │ └── ssh_config │ ├── db │ │ └── docker-entrypoint-initdb.d │ │ │ └── tars.sql │ ├── shared │ │ └── ssh │ │ │ ├── authorized_keys │ │ │ ├── id_rsa │ │ │ └── id_rsa.pub │ └── tomcat │ │ └── etc │ │ ├── ssh │ │ ├── ssh_host_rsa_key │ │ └── ssh_host_rsa_key.pub │ │ ├── supervisord.d │ │ ├── ssh.ini │ │ └── tomcat.ini │ │ └── yum.repos.d │ │ └── CentOS-Epel.repo └── init.sh ├── doc └── images │ ├── API-Application-C.png │ ├── API-Application-List.png │ ├── API-Group-C.png │ ├── API-Group-List.png │ ├── API-Group-RD.png │ ├── API-Group-U.png │ ├── API-Package-C.png │ ├── API-Package-List.png │ ├── API-Server-C.png │ ├── API-Server-List.png │ ├── Admin-Application-New.png │ ├── Admin-Application-RDL.png │ ├── Admin-Group-CU.png │ ├── Admin-Group-RDL.png │ ├── Admin-Overview.png │ ├── Admin-Package-New1-CU.png │ ├── Admin-Package-New2-1.png │ ├── Admin-Package-New2-2.png │ ├── Admin-Package-RDL.png │ ├── Admin-Server-CU.png │ ├── Admin-Server-RDL.png │ ├── Demo-Screenshots-Deployment-Configure.png │ ├── Demo-Screenshots-Deployment-Init.png │ ├── Demo-Screenshots-Deployment-Packages.png │ ├── Demo-Screenshots-Deployment.png │ ├── Demo-Screenshots-Web.png │ ├── Demo-Services.png │ ├── Development-Docker-Configure-DB.png │ ├── Development-Docker-Finish.png │ ├── Development-Docker-Services.png │ └── Development-Screenshots-Web.png ├── docker-compose-frontend.yml ├── docker-compose.yml ├── manage.py ├── requirements ├── base.txt ├── local.txt └── production.txt ├── rest_client ├── __init__.py ├── clients │ ├── __init__.py │ ├── core.py │ ├── es.py │ └── salt.py ├── decorators.py ├── exceptions.py └── utils.py ├── roll_engine ├── __init__.py ├── celery.py ├── constants.py ├── db.py ├── exceptions.py ├── factory.py ├── fsm │ ├── __init__.py │ ├── batch.py │ ├── deployment.py │ └── target.py ├── mixins.py ├── models │ ├── __init__.py │ ├── actions.py │ ├── base.py │ ├── batches.py │ ├── configs.py │ ├── deployments.py │ └── targets.py ├── tasks.py └── utils │ ├── __init__.py │ └── log.py ├── setup.cfg ├── setup.py ├── tars ├── __init__.py ├── api │ ├── __init__.py │ ├── decorators.py │ ├── filters.py │ ├── permissions.py │ ├── serializers │ │ ├── __init__.py │ │ ├── application.py │ │ ├── base.py │ │ ├── deployment.py │ │ └── server.py │ ├── tests │ │ ├── __init__.py │ │ ├── test_application.py │ │ ├── test_deployment.py │ │ └── test_group.py │ ├── urls.py │ ├── utils.py │ └── views │ │ ├── __init__.py │ │ ├── application.py │ │ ├── deployment.py │ │ ├── log.py │ │ └── server.py ├── application │ ├── __init__.py │ ├── admin.py │ └── models.py ├── deployment │ ├── __init__.py │ ├── admin.py │ ├── constants.py │ ├── fsm.py │ ├── mixins.py │ ├── models │ │ ├── __init__.py │ │ ├── actions.py │ │ ├── batches.py │ │ ├── configs.py │ │ ├── deployments.py │ │ └── targets.py │ ├── tasks.py │ └── templatetags │ │ ├── __init__.py │ │ └── app_filters.py ├── engine │ ├── __init__.py │ └── celery_app.py ├── exceptions.py ├── middleware │ └── __init__.py ├── server │ ├── __init__.py │ ├── admin.py │ ├── agency.py │ ├── lb.py │ ├── models.py │ └── verify.py ├── settings │ ├── __init__.py │ ├── base.py │ ├── docker.py │ ├── environments.py │ └── local.py.example ├── surface │ ├── __init__.py │ ├── decorators.py │ ├── static │ │ ├── .jsbeautifyrc │ │ ├── admin │ │ │ ├── img │ │ │ │ ├── changelist-bg.gif │ │ │ │ ├── changelist-bg_rtl.gif │ │ │ │ ├── default-bg-reverse.gif │ │ │ │ ├── default-bg.gif │ │ │ │ ├── deleted-overlay.gif │ │ │ │ ├── gis │ │ │ │ │ ├── move_vertex_off.png │ │ │ │ │ └── move_vertex_on.png │ │ │ │ ├── icon-no.gif │ │ │ │ ├── icon-unknown.gif │ │ │ │ ├── icon-yes.gif │ │ │ │ ├── icon_addlink.gif │ │ │ │ ├── icon_alert.gif │ │ │ │ ├── icon_calendar.gif │ │ │ │ ├── icon_changelink.gif │ │ │ │ ├── icon_clock.gif │ │ │ │ ├── icon_deletelink.gif │ │ │ │ ├── icon_error.gif │ │ │ │ ├── icon_searchbox.png │ │ │ │ ├── icon_success.gif │ │ │ │ ├── inline-delete-8bit.png │ │ │ │ ├── inline-delete.png │ │ │ │ ├── inline-restore-8bit.png │ │ │ │ ├── inline-restore.png │ │ │ │ ├── inline-splitter-bg.gif │ │ │ │ ├── nav-bg-grabber.gif │ │ │ │ ├── nav-bg-reverse.gif │ │ │ │ ├── nav-bg-selected.gif │ │ │ │ ├── nav-bg.gif │ │ │ │ ├── selector-icons.gif │ │ │ │ ├── selector-search.gif │ │ │ │ ├── sorting-icons.gif │ │ │ │ ├── tooltag-add.png │ │ │ │ └── tooltag-arrowright.png │ │ │ └── js │ │ │ │ ├── LICENSE-JQUERY.txt │ │ │ │ ├── SelectBox.js │ │ │ │ ├── SelectFilter2.js │ │ │ │ ├── actions.js │ │ │ │ ├── actions.min.js │ │ │ │ ├── admin │ │ │ │ ├── DateTimeShortcuts.js │ │ │ │ └── RelatedObjectLookups.js │ │ │ │ ├── calendar.js │ │ │ │ ├── collapse.js │ │ │ │ ├── collapse.min.js │ │ │ │ ├── core.js │ │ │ │ ├── inlines.js │ │ │ │ ├── inlines.min.js │ │ │ │ ├── jquery.init.js │ │ │ │ ├── jquery.js │ │ │ │ ├── jquery.min.js │ │ │ │ ├── prepopulate.js │ │ │ │ ├── prepopulate.min.js │ │ │ │ ├── timeparse.js │ │ │ │ └── urlify.js │ │ ├── bower.json │ │ ├── django_extensions │ │ │ ├── img │ │ │ │ └── indicator.gif │ │ │ └── js │ │ │ │ ├── jquery-1.7.2.min.js │ │ │ │ ├── jquery.ajaxQueue.js │ │ │ │ ├── jquery.autocomplete.js │ │ │ │ └── jquery.bgiframe.min.js │ │ ├── gulpfile.js │ │ ├── jre │ │ │ ├── jsvm.js │ │ │ └── src │ │ │ │ ├── main │ │ │ │ └── js │ │ │ │ │ ├── atom │ │ │ │ │ └── misc │ │ │ │ │ │ └── Launcher.js │ │ │ │ │ └── js │ │ │ │ │ ├── awt │ │ │ │ │ ├── Audo.js │ │ │ │ │ ├── Button.js │ │ │ │ │ ├── Canvas.js │ │ │ │ │ ├── Choice.js │ │ │ │ │ ├── Color.js │ │ │ │ │ ├── Component.js │ │ │ │ │ ├── Container.js │ │ │ │ │ ├── Date.js │ │ │ │ │ ├── Dialog.js │ │ │ │ │ ├── Field.js │ │ │ │ │ ├── Frame.js │ │ │ │ │ ├── GridPanel.js │ │ │ │ │ ├── Hidden.js │ │ │ │ │ ├── Image.js │ │ │ │ │ ├── Label.js │ │ │ │ │ ├── List.js │ │ │ │ │ ├── Menu.js │ │ │ │ │ ├── Panel.js │ │ │ │ │ ├── ProgressBar.js │ │ │ │ │ ├── Radio.js │ │ │ │ │ ├── Spinner.js │ │ │ │ │ ├── TabPanel.js │ │ │ │ │ ├── Text.js │ │ │ │ │ ├── TextArea.js │ │ │ │ │ ├── TextField.js │ │ │ │ │ ├── Time.js │ │ │ │ │ ├── Tree.js │ │ │ │ │ ├── TreePanel.js │ │ │ │ │ ├── Video.js │ │ │ │ │ └── Window.js │ │ │ │ │ ├── dom │ │ │ │ │ └── Document.js │ │ │ │ │ ├── io │ │ │ │ │ ├── Console.js │ │ │ │ │ ├── PrintWriter.js │ │ │ │ │ └── Writer.js │ │ │ │ │ ├── lang │ │ │ │ │ ├── Array.js │ │ │ │ │ ├── Boolean.js │ │ │ │ │ ├── Class.js │ │ │ │ │ ├── ClassLoader.js │ │ │ │ │ ├── ClassNotFoundException.js │ │ │ │ │ ├── CloneNotSupportedException.js │ │ │ │ │ ├── Error.js │ │ │ │ │ ├── EvalError.js │ │ │ │ │ ├── Exception.js │ │ │ │ │ ├── Function.js │ │ │ │ │ ├── IllegalAccessException.js │ │ │ │ │ ├── IllegalArgumentException.js │ │ │ │ │ ├── IllegalStateException.js │ │ │ │ │ ├── IndexOutOfBoundsException.js │ │ │ │ │ ├── InternalError.js │ │ │ │ │ ├── NoSuchFieldException.js │ │ │ │ │ ├── NoSuchMethodException.js │ │ │ │ │ ├── NullPointerException.js │ │ │ │ │ ├── Number.js │ │ │ │ │ ├── Object.js │ │ │ │ │ ├── RangeError.js │ │ │ │ │ ├── ReferenceError.js │ │ │ │ │ ├── RegExp.js │ │ │ │ │ ├── String.js │ │ │ │ │ ├── StringBuffer.js │ │ │ │ │ ├── SyntaxError.js │ │ │ │ │ ├── System.js │ │ │ │ │ ├── Throwable.js │ │ │ │ │ ├── TypeError.js │ │ │ │ │ ├── URIError.js │ │ │ │ │ ├── UnsupportedOperationException.js │ │ │ │ │ └── reflect │ │ │ │ │ │ ├── Constructor.js │ │ │ │ │ │ ├── Field.js │ │ │ │ │ │ ├── InvocationTargetException.js │ │ │ │ │ │ ├── Method.js │ │ │ │ │ │ └── Modifier.js │ │ │ │ │ ├── net │ │ │ │ │ ├── Http.js │ │ │ │ │ ├── HttpURLConnection.js │ │ │ │ │ ├── Rest.js │ │ │ │ │ ├── URLClassLoader.js │ │ │ │ │ └── URLConnection.js │ │ │ │ │ ├── test │ │ │ │ │ ├── Assert.js │ │ │ │ │ ├── AssertionError.js │ │ │ │ │ └── TestCase.js │ │ │ │ │ ├── text │ │ │ │ │ ├── DateFormat.js │ │ │ │ │ ├── DateFormatSymbols.js │ │ │ │ │ ├── FieldPosition.js │ │ │ │ │ ├── Format.js │ │ │ │ │ └── SimpleDateFormat.js │ │ │ │ │ └── util │ │ │ │ │ ├── ArrayList.js │ │ │ │ │ ├── Arrays.js │ │ │ │ │ ├── Calendar.js │ │ │ │ │ ├── Collection.js │ │ │ │ │ ├── Date.js │ │ │ │ │ ├── Entry.js │ │ │ │ │ ├── EntrySet.js │ │ │ │ │ ├── GregorianCalendar.js │ │ │ │ │ ├── HashIterator.js │ │ │ │ │ ├── HashMap.js │ │ │ │ │ ├── HashSet.js │ │ │ │ │ ├── Iterator.js │ │ │ │ │ ├── KeyIterator.js │ │ │ │ │ ├── KeySet.js │ │ │ │ │ ├── LinkIterator.js │ │ │ │ │ ├── List.js │ │ │ │ │ ├── Map.js │ │ │ │ │ ├── NoSuchElementException.js │ │ │ │ │ ├── Properties.js │ │ │ │ │ ├── Queue.js │ │ │ │ │ ├── Set.js │ │ │ │ │ ├── Stack.js │ │ │ │ │ ├── TreeMap.js │ │ │ │ │ ├── TreeSet.js │ │ │ │ │ ├── ValueIterator.js │ │ │ │ │ └── ValueList.js │ │ │ │ └── test │ │ │ │ ├── html │ │ │ │ └── index.html │ │ │ │ └── js │ │ │ │ └── js │ │ │ │ ├── lang │ │ │ │ ├── TestOOP.js │ │ │ │ ├── TestObject.js │ │ │ │ ├── TestStringBuffer.js │ │ │ │ └── reflect │ │ │ │ │ ├── TestClass.js │ │ │ │ │ ├── TestField.js │ │ │ │ │ └── TestMethod.js │ │ │ │ ├── model │ │ │ │ ├── Animal.js │ │ │ │ └── Dog.js │ │ │ │ ├── text │ │ │ │ └── TestDateFormat.js │ │ │ │ └── util │ │ │ │ ├── TestArrayList.js │ │ │ │ ├── TestCalendar.js │ │ │ │ ├── TestDate.js │ │ │ │ ├── TestGregorianCalendar.js │ │ │ │ ├── TestHashMap.js │ │ │ │ ├── TestHashSet.js │ │ │ │ ├── TestList.js │ │ │ │ └── TestMap.js │ │ ├── logo.ico │ │ ├── package.json │ │ ├── pom.json │ │ ├── rest_framework │ │ │ ├── fonts │ │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ │ ├── glyphicons-halflings-regular.svg │ │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ │ └── glyphicons-halflings-regular.woff │ │ │ ├── img │ │ │ │ ├── glyphicons-halflings-white.png │ │ │ │ ├── glyphicons-halflings.png │ │ │ │ └── grid.png │ │ │ └── js │ │ │ │ ├── bootstrap.min.js │ │ │ │ ├── default.js │ │ │ │ ├── jquery-1.8.1-min.js │ │ │ │ └── prettify-min.js │ │ ├── rest_framework_swagger │ │ │ ├── images │ │ │ │ ├── logo_small.png │ │ │ │ ├── pet_store_api.png │ │ │ │ ├── throbber.gif │ │ │ │ └── wordnik_api.png │ │ │ ├── swagger-ui.js │ │ │ └── swagger-ui.min.js │ │ └── src │ │ │ └── main │ │ │ ├── css │ │ │ ├── animate.css │ │ │ ├── animate.less │ │ │ ├── beautifybox.css │ │ │ ├── beautifybox.less │ │ │ ├── bubbles.css │ │ │ ├── bubbles.less │ │ │ ├── bxslider.css │ │ │ ├── bxslider.less │ │ │ ├── components.css │ │ │ ├── components.less │ │ │ ├── contentflow.css │ │ │ ├── contentflow.less │ │ │ ├── countdown.css │ │ │ ├── countdown.less │ │ │ ├── cover.css │ │ │ ├── cover.less │ │ │ ├── easypie.css │ │ │ ├── easypie.less │ │ │ ├── flowstep.css │ │ │ ├── flowstep.less │ │ │ ├── histories.css │ │ │ ├── histories.less │ │ │ ├── index.css │ │ │ ├── index.less │ │ │ ├── notification.css │ │ │ ├── notification.less │ │ │ ├── plumb.css │ │ │ ├── plumb.less │ │ │ ├── sidebar.css │ │ │ ├── sidebar.less │ │ │ ├── tars.css │ │ │ └── tars.less │ │ │ ├── images │ │ │ ├── 1x1_0.5_black.png │ │ │ ├── 404-lg.png │ │ │ ├── 404-md.png │ │ │ ├── 404-sm.png │ │ │ ├── 404-xs.png │ │ │ ├── arrow-bottom-left.png │ │ │ ├── arrow-bottom-left2.png │ │ │ ├── arrow-bottom-right.png │ │ │ ├── arrow-bottom-right2.png │ │ │ ├── arrow-top-left.png │ │ │ ├── arrow-top-left2.png │ │ │ ├── arrow-top-right.png │ │ │ ├── arrow-top-right2.png │ │ │ ├── bg_noise.png │ │ │ ├── bg_stitch.png │ │ │ ├── blank.gif │ │ │ ├── body_bg.gif │ │ │ ├── bxslider │ │ │ │ ├── bx_loader.gif │ │ │ │ ├── clog-36.png │ │ │ │ └── controls.png │ │ │ ├── chart │ │ │ │ └── circlepin-30.png │ │ │ ├── ctrl-up-down.png │ │ │ ├── goback.png │ │ │ ├── loader.gif │ │ │ ├── loading.gif │ │ │ ├── lockscreen.png │ │ │ ├── logo.ico │ │ │ ├── logo.png │ │ │ ├── postmark.png │ │ │ ├── resource │ │ │ │ ├── lockscreen.png │ │ │ │ └── uc_user.png │ │ │ ├── rm-36.png │ │ │ ├── scrollbar_white.png │ │ │ ├── sleep-lg.png │ │ │ ├── slider_white.png │ │ │ ├── tars.png │ │ │ ├── uc_user.png │ │ │ ├── upload │ │ │ │ └── user │ │ │ │ │ ├── photo-user.png │ │ │ │ │ └── zhuoluo.jpg │ │ │ └── xmon-36.png │ │ │ ├── js │ │ │ └── com │ │ │ │ ├── ctrip │ │ │ │ └── tars │ │ │ │ │ ├── Portal.js │ │ │ │ │ ├── app │ │ │ │ │ └── App.js │ │ │ │ │ ├── apps │ │ │ │ │ ├── Apps.js │ │ │ │ │ ├── Service.js │ │ │ │ │ └── multi │ │ │ │ │ │ ├── Apps.js │ │ │ │ │ │ └── filter │ │ │ │ │ │ └── MonitorStatus.js │ │ │ │ │ ├── base │ │ │ │ │ ├── DefaultService.js │ │ │ │ │ ├── PaginationService.js │ │ │ │ │ ├── SegmentService.js │ │ │ │ │ └── Service.js │ │ │ │ │ ├── batches │ │ │ │ │ └── Batches.js │ │ │ │ │ ├── component │ │ │ │ │ ├── Command.js │ │ │ │ │ ├── Dragmove.js │ │ │ │ │ ├── IAjax.js │ │ │ │ │ ├── ICheckbox.js │ │ │ │ │ ├── IContentFlow.js │ │ │ │ │ ├── IFlow.js │ │ │ │ │ ├── IFlow2.js │ │ │ │ │ ├── IForm.js │ │ │ │ │ ├── IPlumb.js │ │ │ │ │ ├── IScroll.js │ │ │ │ │ ├── ISearch.js │ │ │ │ │ ├── ISlider.js │ │ │ │ │ ├── angular │ │ │ │ │ │ ├── accordion │ │ │ │ │ │ │ └── Accordion.js │ │ │ │ │ │ ├── action │ │ │ │ │ │ │ └── Action.js │ │ │ │ │ │ ├── bubble │ │ │ │ │ │ │ └── Bubble.js │ │ │ │ │ │ ├── contentflow │ │ │ │ │ │ │ └── ContentFlow.js │ │ │ │ │ │ ├── countdown │ │ │ │ │ │ │ └── Countdown.js │ │ │ │ │ │ ├── cover │ │ │ │ │ │ │ └── Cover.js │ │ │ │ │ │ ├── d3 │ │ │ │ │ │ │ └── Tree.js │ │ │ │ │ │ ├── expander │ │ │ │ │ │ │ └── Expander.js │ │ │ │ │ │ ├── flowstep │ │ │ │ │ │ │ └── Flowstep.js │ │ │ │ │ │ ├── flp │ │ │ │ │ │ │ └── Flp.js │ │ │ │ │ │ ├── iButton │ │ │ │ │ │ │ └── iButton.js │ │ │ │ │ │ ├── ink │ │ │ │ │ │ │ └── Ink.js │ │ │ │ │ │ ├── layout │ │ │ │ │ │ │ └── Concern.js │ │ │ │ │ │ ├── notification │ │ │ │ │ │ │ └── Notification.js │ │ │ │ │ │ ├── pagination │ │ │ │ │ │ │ └── Pagination.js │ │ │ │ │ │ ├── percent │ │ │ │ │ │ │ ├── Bar.js │ │ │ │ │ │ │ ├── Easypie.js │ │ │ │ │ │ │ └── Pie.js │ │ │ │ │ │ ├── popout │ │ │ │ │ │ │ └── Popouts.js │ │ │ │ │ │ ├── postmark │ │ │ │ │ │ │ └── Postmark.js │ │ │ │ │ │ ├── sidebar │ │ │ │ │ │ │ └── Sidebar.js │ │ │ │ │ │ ├── slider │ │ │ │ │ │ │ └── IonRange.js │ │ │ │ │ │ ├── tabpanel │ │ │ │ │ │ │ └── Tabpanel.js │ │ │ │ │ │ ├── tooltip │ │ │ │ │ │ │ └── Tooltip.js │ │ │ │ │ │ └── tween │ │ │ │ │ │ │ ├── Menu.js │ │ │ │ │ │ │ ├── Share.js │ │ │ │ │ │ │ └── Show.js │ │ │ │ │ └── chart │ │ │ │ │ │ ├── Bar.js │ │ │ │ │ │ ├── Easypie.js │ │ │ │ │ │ ├── Highcharts.js │ │ │ │ │ │ ├── Pie.js │ │ │ │ │ │ └── Stock.js │ │ │ │ │ ├── config │ │ │ │ │ ├── Config.js │ │ │ │ │ └── Service.js │ │ │ │ │ ├── console │ │ │ │ │ ├── Console.js │ │ │ │ │ └── Service.js │ │ │ │ │ ├── controller │ │ │ │ │ ├── Dispatcher.js │ │ │ │ │ ├── Index.js │ │ │ │ │ └── Root.js │ │ │ │ │ ├── deployments │ │ │ │ │ ├── Parallel.js │ │ │ │ │ ├── Serial.js │ │ │ │ │ ├── Single.js │ │ │ │ │ ├── Tabs.js │ │ │ │ │ └── tabs │ │ │ │ │ │ └── Tabpanel.js │ │ │ │ │ ├── events │ │ │ │ │ └── Events.js │ │ │ │ │ ├── exceptions │ │ │ │ │ └── Exceptions.js │ │ │ │ │ ├── filter │ │ │ │ │ └── Filter.js │ │ │ │ │ ├── group │ │ │ │ │ ├── Command.js │ │ │ │ │ ├── CommandGroup.js │ │ │ │ │ ├── Contribution.js │ │ │ │ │ ├── Group.js │ │ │ │ │ ├── Service.js │ │ │ │ │ ├── rollback │ │ │ │ │ │ ├── Cancel.js │ │ │ │ │ │ ├── CommandGroup.js │ │ │ │ │ │ ├── Confirm.js │ │ │ │ │ │ ├── Controller.js │ │ │ │ │ │ └── Service.js │ │ │ │ │ └── rollout │ │ │ │ │ │ ├── Cancel.js │ │ │ │ │ │ ├── CommandGroup.js │ │ │ │ │ │ ├── Confirm.js │ │ │ │ │ │ ├── Controller.js │ │ │ │ │ │ ├── Next.js │ │ │ │ │ │ ├── Previous.js │ │ │ │ │ │ └── Settings.js │ │ │ │ │ ├── groups │ │ │ │ │ ├── Groups.js │ │ │ │ │ └── Service.js │ │ │ │ │ ├── header │ │ │ │ │ └── Header.js │ │ │ │ │ ├── histories │ │ │ │ │ ├── Histories.js │ │ │ │ │ └── Service.js │ │ │ │ │ ├── model │ │ │ │ │ ├── Application.js │ │ │ │ │ ├── DeploymentTargetSteps.js │ │ │ │ │ ├── Flowstep.js │ │ │ │ │ ├── Group.js │ │ │ │ │ ├── Notification.js │ │ │ │ │ ├── Runtime.js │ │ │ │ │ └── User.js │ │ │ │ │ ├── navigator │ │ │ │ │ └── Navigator.js │ │ │ │ │ ├── packages │ │ │ │ │ ├── Packages.js │ │ │ │ │ └── Service.js │ │ │ │ │ ├── plumb │ │ │ │ │ └── Plumb.js │ │ │ │ │ ├── progress │ │ │ │ │ ├── Components.js │ │ │ │ │ ├── Deploying.js │ │ │ │ │ ├── Progress.js │ │ │ │ │ └── Working.js │ │ │ │ │ ├── security │ │ │ │ │ └── Security.js │ │ │ │ │ ├── servers │ │ │ │ │ ├── Servers.js │ │ │ │ │ └── Service.js │ │ │ │ │ ├── subscriptions │ │ │ │ │ └── Subscription.js │ │ │ │ │ ├── util │ │ │ │ │ ├── Angular.js │ │ │ │ │ ├── Chart.js │ │ │ │ │ ├── Common.js │ │ │ │ │ ├── Csrf.js │ │ │ │ │ ├── Fridge.js │ │ │ │ │ ├── Id.js │ │ │ │ │ ├── Jquery.js │ │ │ │ │ ├── LocalStorage.js │ │ │ │ │ ├── SegmentTable.js │ │ │ │ │ ├── Slot.js │ │ │ │ │ └── Watch.js │ │ │ │ │ ├── welcome │ │ │ │ │ └── Welcome.js │ │ │ │ │ └── xmon │ │ │ │ │ └── Xmon.js │ │ │ │ └── highstock │ │ │ │ ├── DraggablePoints.js │ │ │ │ └── Theme.js │ │ │ ├── skin │ │ │ ├── default │ │ │ │ └── css │ │ │ │ │ ├── skin.css │ │ │ │ │ └── skin.less │ │ │ ├── fat │ │ │ │ └── css │ │ │ │ │ ├── skin.css │ │ │ │ │ └── skin.less │ │ │ ├── skins.less │ │ │ ├── test │ │ │ │ └── css │ │ │ │ │ ├── skin.css │ │ │ │ │ └── skin.less │ │ │ └── uat │ │ │ │ └── css │ │ │ │ ├── skin.css │ │ │ │ └── skin.less │ │ │ └── template │ │ │ ├── 404.html │ │ │ ├── apps.html │ │ │ ├── cis.html │ │ │ ├── deployment.html │ │ │ ├── deployment │ │ │ └── tabpanel.html │ │ │ ├── dialog │ │ │ ├── batches.html │ │ │ ├── rollback.html │ │ │ ├── rollback │ │ │ │ └── preview.html │ │ │ ├── rollout.html │ │ │ └── rollout │ │ │ │ ├── 1.html │ │ │ │ ├── 2.html │ │ │ │ └── 3.html │ │ │ ├── group.html │ │ │ ├── groups.html │ │ │ ├── index.html │ │ │ ├── login.html │ │ │ ├── parallel.html │ │ │ ├── pools.html │ │ │ ├── serial.html │ │ │ └── single.html │ ├── templates │ │ ├── OnService.html │ │ ├── admin │ │ │ ├── 404.html │ │ │ ├── 500.html │ │ │ ├── actions.html │ │ │ ├── app_index.html │ │ │ ├── auth │ │ │ │ └── user │ │ │ │ │ ├── add_form.html │ │ │ │ │ └── change_password.html │ │ │ ├── base.html │ │ │ ├── base_site.html │ │ │ ├── change_form.html │ │ │ ├── change_list.html │ │ │ ├── change_list_results.html │ │ │ ├── date_hierarchy.html │ │ │ ├── delete_confirmation.html │ │ │ ├── delete_selected_confirmation.html │ │ │ ├── edit_inline │ │ │ │ ├── stacked.html │ │ │ │ └── tabular.html │ │ │ ├── filter.html │ │ │ ├── includes │ │ │ │ └── fieldset.html │ │ │ ├── index.html │ │ │ ├── invalid_setup.html │ │ │ ├── login.html │ │ │ ├── object_history.html │ │ │ ├── pagination.html │ │ │ ├── popup_response.html │ │ │ ├── prepopulated_fields_js.html │ │ │ ├── search_form.html │ │ │ └── submit_line.html │ │ ├── constance_change_list.html │ │ ├── index.html │ │ ├── settings.html │ │ └── surface_login.html │ ├── urls.py │ └── views.py ├── urls.py ├── utils.py └── wsgi.py └── tools ├── celeryd ├── celeryd.conf ├── celeryd.conf.j2 ├── deploy.sh ├── maintain.sh ├── restart.sh ├── tarsd └── tarsd.ini /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:2.7 2 | ENV PYTHONUNBUFFERED 1 3 | ADD requirements /requirements 4 | RUN pip install -r requirements/local.txt --trusted-host pypi.douban.com 5 | RUN mkdir /code 6 | WORKDIR /code 7 | ADD ./ /code/ 8 | 9 | -------------------------------------------------------------------------------- /Dockerfile-demo: -------------------------------------------------------------------------------- 1 | FROM python:2.7 2 | ENV PYTHONUNBUFFERED 1 3 | ADD requirements /requirements 4 | 5 | RUN pip install -r /requirements/local.txt --trusted-host pypi.douban.com 6 | 7 | RUN mkdir /code 8 | WORKDIR /code 9 | 10 | COPY demo/files/shared/ssh/id_rsa.pub /root/.ssh/id_rsa.pub 11 | COPY demo/files/shared/ssh/id_rsa /root/.ssh/id_rsa 12 | COPY demo/files/shared/ssh/authorized_keys /root/.ssh/authorized_keys 13 | 14 | RUN chmod 600 /root/.ssh/authorized_keys 15 | RUN chmod 600 /root/.ssh/id_rsa 16 | 17 | RUN chown -R root:root /root/.ssh 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Docker bootstrap 2 | 3 | Requirements 4 | 5 | - docker and docker-compose 6 | - GNU make 7 | 8 | Preperations 9 | 10 | ``` bash 11 | cp tars/settings/local.py.example tars/settings/local.py 12 | ``` 13 | 14 | Just type 15 | 16 | ``` bash 17 | make docker_bootstrap 18 | ``` 19 | 20 | Then, please visit http://localhost:8000 to access Tars 21 | 22 | # Frontend 23 | 24 | Build frontend 25 | 26 | ```bash 27 | make frontend 28 | ``` 29 | 30 | Build frontend using docker, please ensure container exit code is 0 31 | 32 | ```bash 33 | make frontend_docker 34 | ``` 35 | 36 | If failed to install bower components, please try branch `demo/static_embedded` 37 | 38 | # Docker demo 39 | 40 | ``` bash 41 | ./demo/bootstrap.sh 42 | ``` 43 | 44 | Demo admin account: 45 | 46 | * username: admin 47 | * password: nomoresecrete 48 | -------------------------------------------------------------------------------- /ansible_playbook/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/ansible_playbook/__init__.py -------------------------------------------------------------------------------- /ansible_playbook/deploy.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Deploy for tomcat app 3 | hosts: all 4 | remote_user: "{{ login_user }}" 5 | sudo: True 6 | vars: 7 | # ansistrano_deploy_from: "/Users/cy/vagrant/tarstest/tars" 8 | ansistrano_release_version: "{{ release_version }}" 9 | ansistrano_deploy_via: "download_unarchive" 10 | ansistrano_get_url: "{{ package_url }}" 11 | ansistrano_allow_anonymous_stats: False 12 | ansistrano_after_symlink_tasks_file: "{{ playbook_dir }}/shared/after-symlink.yml" 13 | roles: 14 | - { role: carlosbuenosvinos.ansistrano-deploy } 15 | -------------------------------------------------------------------------------- /ansible_playbook/hosts: -------------------------------------------------------------------------------- 1 | [all:vars] 2 | env=matrix 3 | login_user=root 4 | gulp_target_env=matrix 5 | 6 | 7 | [webservers] 8 | 10.18.5.26 9 | -------------------------------------------------------------------------------- /ansible_playbook/requirements.yml: -------------------------------------------------------------------------------- 1 | # ansible-galaxy install -r requirements.yml 2 | 3 | # carlosbuenosvinos.ansistrano-deploy 4 | - src: carlosbuenosvinos.ansistrano-deploy -------------------------------------------------------------------------------- /ansible_playbook/roles/skip/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Path where the code must be deployed to 3 | ansistrano_deploy_to: "/var/www/my-app" 4 | 5 | # Folder name for the releases 6 | ansistrano_version_dir: "releases" 7 | 8 | # Softlink name for the current release 9 | ansistrano_current_dir: "current" 10 | -------------------------------------------------------------------------------- /ansible_playbook/roles/skip/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # ansible-playbook skip.yml -i hosts -e release_version=222 -e package_url="http://tomcat.apache.org/tomcat-6.0-doc/appdev/sample/sample.war" -e ansistrano_after_symlink_tasks_file="{{ playbook_dir }}/shared/after-symlink.yml" 2 | - name: ANSISTRANO | Check if current 3 | shell: readlink {{ ansistrano_deploy_to }}/{{ ansistrano_current_dir }} | grep -e '/{{ release_version }}$' 4 | -------------------------------------------------------------------------------- /ansible_playbook/shared/after-symlink.yml: -------------------------------------------------------------------------------- 1 | # Performs symlink exchange 2 | - name: ANSISTRANO | Ensure tomcat webapps ROOT link 3 | file: 4 | state: link 5 | path: "/usr/share/tomcat/webapps/ROOT" 6 | src: "{{ ansistrano_deploy_to }}/{{ ansistrano_current_dir }}" 7 | 8 | # - name: ANSISTRANO | Ensure tomcat restarted 9 | # service: name=tomcat state=restarted 10 | 11 | - name: Manage the state of a program or group of programs running via supervisord 12 | supervisorctl: name=tomcat state=restarted 13 | -------------------------------------------------------------------------------- /ansible_playbook/skip.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Check can skip deploy for tomcat app 3 | hosts: all 4 | remote_user: "{{ login_user }}" 5 | sudo: True 6 | vars: 7 | # ansistrano_deploy_from: "/Users/cy/vagrant/tarstest/tars" 8 | ansistrano_release_version: "{{ release_version }}" 9 | ansistrano_deploy_via: "download" 10 | ansistrano_get_url: "{{ package_url }}" 11 | ansistrano_allow_anonymous_stats: False 12 | roles: 13 | - { role: skip } 14 | -------------------------------------------------------------------------------- /ansible_playbook/version.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/ansible_playbook/version.yml -------------------------------------------------------------------------------- /demo/Dockerfile-Tomcat: -------------------------------------------------------------------------------- 1 | FROM centos:7 2 | 3 | COPY files/tomcat/etc/yum.repos.d/CentOS-Epel.repo /etc/yum.repos.d/CentOS-Epel.repo 4 | 5 | # Install software 6 | RUN yum install -y sudo net-tools openssh-server openssh-clients supervisor tomcat unzip 7 | 8 | # Manage ssh key 9 | RUN mkdir -p /root/.ssh 10 | 11 | COPY files/shared/ssh/id_rsa.pub /root/.ssh/id_rsa.pub 12 | COPY files/shared/ssh/id_rsa /root/.ssh/id_rsa 13 | COPY files/shared/ssh/authorized_keys /root/.ssh/authorized_keys 14 | COPY files/tomcat/etc/ssh/ssh_host_rsa_key /etc/ssh/ssh_host_rsa_key 15 | COPY files/tomcat/etc/ssh/ssh_host_rsa_key.pub /etc/ssh/ssh_host_rsa_key.pub 16 | 17 | RUN chmod 600 /root/.ssh/authorized_keys 18 | RUN chmod 600 /root/.ssh/id_rsa 19 | RUN chmod 600 /etc/ssh/ssh_host_rsa_key 20 | 21 | RUN chown -R root:root /root/.ssh 22 | RUN chown -R root:root /etc/ssh/ 23 | 24 | # Clean all 25 | RUN yum clean all 26 | 27 | CMD [ "supervisord", "-n" ] 28 | -------------------------------------------------------------------------------- /demo/bootstrap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | cd $(dirname $0) 6 | 7 | ./init.sh 8 | 9 | docker-compose -f ../docker-compose-frontend.yml up 10 | 11 | docker-compose up -d db 12 | 13 | echo Ensure db instance is started... 14 | sleep 20s 15 | 16 | docker-compose build && docker-compose up 17 | 18 | echo "Please visit http://localhost:8000 to access Tars, Enjoy it :)" 19 | -------------------------------------------------------------------------------- /demo/clean_all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cd $(dirname $0) 3 | 4 | docker-compose stop 5 | docker-compose down --rmi local -v 6 | 7 | cd - 8 | -------------------------------------------------------------------------------- /demo/docker-compose-common.yml: -------------------------------------------------------------------------------- 1 | server: 2 | build: . 3 | dockerfile: Dockerfile-Tomcat 4 | volumes: 5 | - ./files/tomcat/etc/supervisord.d/:/etc/supervisord.d 6 | 7 | code: 8 | build: .. 9 | dockerfile: Dockerfile-demo 10 | volumes: 11 | - ../:/code 12 | - ./files/code/etc/ssh/ssh_config:/etc/ssh/ssh_config 13 | - ./files/code/etc/ansible/roles:/etc/ansible/roles 14 | -------------------------------------------------------------------------------- /demo/files/code/etc/ansible/roles/carlosbuenosvinos.ansistrano-deploy/.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | 3 | ### Vagrant template 4 | .vagrant/ 5 | 6 | ### JetBrains template 7 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio 8 | 9 | *.iml 10 | 11 | ## Directory-based project format: 12 | .idea/ 13 | # if you remove the above rule, at least ignore the following: 14 | 15 | # User-specific stuff: 16 | # .idea/workspace.xml 17 | # .idea/tasks.xml 18 | # .idea/dictionaries 19 | 20 | # Sensitive or high-churn files: 21 | # .idea/dataSources.ids 22 | # .idea/dataSources.xml 23 | # .idea/sqlDataSources.xml 24 | # .idea/dynamic.xml 25 | # .idea/uiDesigner.xml 26 | 27 | # Gradle: 28 | # .idea/gradle.xml 29 | # .idea/libraries 30 | 31 | # Mongo Explorer plugin: 32 | # .idea/mongoSettings.xml 33 | 34 | ## File-based project format: 35 | *.ipr 36 | *.iws 37 | 38 | ## Plugin-specific files: 39 | 40 | # IntelliJ 41 | /out/ 42 | 43 | # mpeltonen/sbt-idea plugin 44 | .idea_modules/ 45 | 46 | # JIRA plugin 47 | atlassian-ide-plugin.xml 48 | 49 | # Crashlytics plugin (for Android Studio and IntelliJ) 50 | com_crashlytics_export_strings.xml 51 | crashlytics.properties 52 | crashlytics-build.properties 53 | 54 | -------------------------------------------------------------------------------- /demo/files/code/etc/ansible/roles/carlosbuenosvinos.ansistrano-deploy/.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | sudo: required 3 | dist: trusty 4 | 5 | matrix: 6 | include: 7 | - env: ANSIBLE_VERSION=1.8.4 8 | - env: ANSIBLE_VERSION=1.9.5 9 | - env: ANSIBLE_VERSION=2.1.0 10 | 11 | before_install: 12 | - sudo apt-get -y install software-properties-common 13 | - sudo apt-get -y install python-pip 14 | - sudo pip install ansible==$ANSIBLE_VERSION 15 | - ansible --version 16 | 17 | script: 18 | - echo localhost > inventory 19 | - ansible-playbook -i inventory --connection=local --sudo -v test/test.yml 20 | 21 | notifications: 22 | webhooks: https://galaxy.ansible.com/api/v1/notifications/ -------------------------------------------------------------------------------- /demo/files/code/etc/ansible/roles/carlosbuenosvinos.ansistrano-deploy/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014-2016 Carlos Buenosvinos 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /demo/files/code/etc/ansible/roles/carlosbuenosvinos.ansistrano-deploy/TESTING.md: -------------------------------------------------------------------------------- 1 | Testing locally with Ansible 2.x 2 | ================================ 3 | 4 | git clone git@github.com:ansistrano/deploy.git 5 | cd deploy 6 | vagrant up 7 | cd example/my-playbook 8 | ansible-playbook deploy.yml -i hosts -------------------------------------------------------------------------------- /demo/files/code/etc/ansible/roles/carlosbuenosvinos.ansistrano-deploy/Vagrantfile: -------------------------------------------------------------------------------- 1 | Vagrant.configure("2") do |config| 2 | config.vm.define 'web01' do |config| 3 | config.vm.box = 'ubuntu/trusty64' 4 | config.vm.hostname = 'web01' 5 | config.vm.synced_folder '.', '/vagrant', disabled: true 6 | end 7 | 8 | config.vm.define 'web02' do |config| 9 | config.vm.box = 'ubuntu/trusty64' 10 | config.vm.hostname = 'web02' 11 | config.vm.synced_folder '.', '/vagrant', disabled: true 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /demo/files/code/etc/ansible/roles/carlosbuenosvinos.ansistrano-deploy/ansible.cfg: -------------------------------------------------------------------------------- 1 | [defaults] 2 | roles_path = ../ -------------------------------------------------------------------------------- /demo/files/code/etc/ansible/roles/carlosbuenosvinos.ansistrano-deploy/docs/ansistrano-flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/demo/files/code/etc/ansible/roles/carlosbuenosvinos.ansistrano-deploy/docs/ansistrano-flow.png -------------------------------------------------------------------------------- /demo/files/code/etc/ansible/roles/carlosbuenosvinos.ansistrano-deploy/docs/figure.md: -------------------------------------------------------------------------------- 1 | http://yuml.me/edit/5473b608 2 | -------------------------------------------------------------------------------- /demo/files/code/etc/ansible/roles/carlosbuenosvinos.ansistrano-deploy/example/my-app/index.html: -------------------------------------------------------------------------------- 1 | This is the main file of the project, I know it's not too much, but it will :) -------------------------------------------------------------------------------- /demo/files/code/etc/ansible/roles/carlosbuenosvinos.ansistrano-deploy/example/my-playbook/ansible.cfg: -------------------------------------------------------------------------------- 1 | [defaults] 2 | host_key_checking=False -------------------------------------------------------------------------------- /demo/files/code/etc/ansible/roles/carlosbuenosvinos.ansistrano-deploy/example/my-playbook/deploy.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Deploy example app to my-server.com 3 | hosts: all 4 | vars: 5 | ansistrano_deploy_from: "{{ playbook_dir }}/../my-app" 6 | ansistrano_deploy_to: "/tmp/my-app.com" 7 | ansistrano_keep_releases: 3 8 | # There seems to be an issue with rsync in vagrant 9 | ansistrano_deploy_via: copy 10 | roles: 11 | - { role: carlosbuenosvinos.ansistrano-deploy } -------------------------------------------------------------------------------- /demo/files/code/etc/ansible/roles/carlosbuenosvinos.ansistrano-deploy/example/my-playbook/hosts: -------------------------------------------------------------------------------- 1 | web01 ansible_user=vagrant ansible_port=2222 ansible_host=127.0.0.1 ansible_ssh_private_key_file=../../.vagrant/machines/web01/virtualbox/private_key 2 | web02 ansible_user=vagrant ansible_port=2200 ansible_host=127.0.0.1 ansible_ssh_private_key_file=../../.vagrant/machines/web02/virtualbox/private_key -------------------------------------------------------------------------------- /demo/files/code/etc/ansible/roles/carlosbuenosvinos.ansistrano-deploy/example/my-playbook/rollback.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Rollback example app to my-server.com 3 | hosts: all 4 | vars: 5 | ansistrano_deploy_to: "/tmp/my-app.com" 6 | roles: 7 | - { role: carlosbuenosvinos.ansistrano-rollback } -------------------------------------------------------------------------------- /demo/files/code/etc/ansible/roles/carlosbuenosvinos.ansistrano-deploy/meta/.galaxy_install_info: -------------------------------------------------------------------------------- 1 | {install_date: 'Thu Nov 3 10:37:28 2016', version: 1.10.1} 2 | -------------------------------------------------------------------------------- /demo/files/code/etc/ansible/roles/carlosbuenosvinos.ansistrano-deploy/meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | galaxy_info: 3 | author: ansistrano 4 | description: Ansible role to deploy scripting applications like PHP, Python, Ruby, etc. in a Capistrano style 5 | company: Ansistrano 6 | license: MIT 7 | min_ansible_version: 1.8 8 | platforms: 9 | - name: EL 10 | versions: 11 | - all 12 | - name: GenericUNIX 13 | versions: 14 | - all 15 | - name: Fedora 16 | versions: 17 | - all 18 | - name: opensuse 19 | versions: 20 | - all 21 | - name: Amazon 22 | versions: 23 | - all 24 | - name: GenericBSD 25 | versions: 26 | - all 27 | - name: FreeBSD 28 | versions: 29 | - all 30 | - name: Ubuntu 31 | versions: 32 | - all 33 | - name: SLES 34 | versions: 35 | - all 36 | - name: GenericLinux 37 | versions: 38 | - all 39 | - name: Debian 40 | versions: 41 | - all 42 | categories: 43 | - cloud 44 | - web 45 | dependencies: [] 46 | -------------------------------------------------------------------------------- /demo/files/code/etc/ansible/roles/carlosbuenosvinos.ansistrano-deploy/tasks/anon-stats.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Sends anonymous stats if the user is ok with it 3 | - name: ANSISTRANO | Send anonymous stats 4 | uri: 5 | url: http://ansistrano.com/deploy 6 | method: POST 7 | timeout: 5 8 | when: ansistrano_allow_anonymous_stats 9 | run_once: true 10 | ignore_errors: yes 11 | delegate_to: 127.0.0.1 12 | sudo: false 13 | -------------------------------------------------------------------------------- /demo/files/code/etc/ansible/roles/carlosbuenosvinos.ansistrano-deploy/tasks/cleanup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Clean up releases 3 | - name: ANSISTRANO | Clean up releases 4 | shell: ls -1dt {{ ansistrano_releases_path.stdout }}/* | tail -n +{{ ansistrano_keep_releases | int + 1 }} | xargs rm -rf 5 | when: ansistrano_keep_releases > 0 6 | -------------------------------------------------------------------------------- /demo/files/code/etc/ansible/roles/carlosbuenosvinos.ansistrano-deploy/tasks/empty.yml: -------------------------------------------------------------------------------- 1 | # This file is intentionally left empty and it is used in those Capistrano flow steps 2 | # where you don't need to execute any custom tasks -------------------------------------------------------------------------------- /demo/files/code/etc/ansible/roles/carlosbuenosvinos.ansistrano-deploy/tasks/setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Setup folders 3 | - name: ANSISTRANO | Ensure deployment base path exists 4 | file: 5 | state: directory 6 | path: "{{ ansistrano_deploy_to }}" 7 | 8 | - name: ANSISTRANO | Set releases path 9 | command: echo "{{ ansistrano_deploy_to }}/{{ ansistrano_version_dir }}" 10 | register: ansistrano_releases_path 11 | 12 | - name: ANSISTRANO | Ensure releases folder exists 13 | file: 14 | state: directory 15 | path: "{{ ansistrano_releases_path.stdout }}" 16 | 17 | - name: ANSISTRANO | Set shared path 18 | command: echo "{{ ansistrano_deploy_to }}/shared" 19 | register: ansistrano_shared_path 20 | 21 | - name: ANSISTRANO | Ensure shared elements folder exists 22 | file: 23 | state: directory 24 | path: "{{ ansistrano_shared_path.stdout }}" 25 | -------------------------------------------------------------------------------- /demo/files/code/etc/ansible/roles/carlosbuenosvinos.ansistrano-deploy/tasks/symlink.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | # Migration check from rsync deployment 4 | - stat: 5 | path: "{{ ansistrano_deploy_to }}/{{ ansistrano_current_dir }}" 6 | register: stat_current_dir 7 | 8 | - name: ANSISTRANO | Remove current folder if it's a directory 9 | file: 10 | state: absent 11 | path: "{{ ansistrano_deploy_to }}/{{ ansistrano_current_dir }}" 12 | when: stat_current_dir.stat.isdir is defined and stat_current_dir.stat.isdir 13 | 14 | # Performs symlink exchange 15 | - name: ANSISTRANO | Change softlink to new release 16 | file: 17 | state: link 18 | path: "{{ ansistrano_deploy_to }}/{{ ansistrano_current_dir }}" 19 | src: "./{{ ansistrano_version_dir }}/{{ ansistrano_release_version }}" 20 | -------------------------------------------------------------------------------- /demo/files/code/etc/ansible/roles/carlosbuenosvinos.ansistrano-deploy/tasks/update-code.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Update code deployment step 3 | - name: ANSISTRANO | Get release version 4 | set_fact: 5 | ansistrano_release_version: "{{ lookup('pipe', 'date -u +%Y%m%d%H%M%SZ') }}" 6 | run_once: true 7 | when: ansistrano_release_version is not defined 8 | delegate_to: 127.0.0.1 9 | 10 | - name: ANSISTRANO | Get release path 11 | command: echo "{{ ansistrano_releases_path.stdout }}/{{ ansistrano_release_version }}" 12 | register: ansistrano_release_path 13 | 14 | - include: "update-code/{{ ansistrano_deploy_via | default('rsync') }}.yml" 15 | 16 | - name: ANSISTRANO | Copy release version into REVISION file 17 | copy: 18 | content: "{{ ansistrano_release_version }}" 19 | dest: "{{ ansistrano_release_path.stdout }}/REVISION" 20 | -------------------------------------------------------------------------------- /demo/files/code/etc/ansible/roles/carlosbuenosvinos.ansistrano-deploy/tasks/update-code/copy.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: ANSISTRANO | SCP | Create release folder 3 | file: 4 | state: directory 5 | path: "{{ ansistrano_release_path.stdout }}" 6 | 7 | - name: ANSISTRANO | SCP | Deploy existing code to remote servers 8 | copy: 9 | src: "{{ ansistrano_deploy_from }}" 10 | dest: "{{ ansistrano_release_path.stdout }}" 11 | -------------------------------------------------------------------------------- /demo/files/code/etc/ansible/roles/carlosbuenosvinos.ansistrano-deploy/tasks/update-code/copy_unarchive.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - include: copy.yml 3 | 4 | - name: ANSISTRANO | copy_unarchive | Set archived file 5 | set_fact: 6 | ansistrano_archived_file: "{{ ansistrano_release_path.stdout }}/{{ ansistrano_deploy_from | basename }}" 7 | 8 | - include: unarchive.yml 9 | -------------------------------------------------------------------------------- /demo/files/code/etc/ansible/roles/carlosbuenosvinos.ansistrano-deploy/tasks/update-code/download.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: ANSISTRANO | download | Create release folder 3 | file: 4 | state: directory 5 | path: "{{ ansistrano_release_path.stdout }}" 6 | 7 | - name: ANSISTRANO | download | Download artifact 8 | get_url: 9 | url: "{{ ansistrano_get_url }}" 10 | dest: "{{ ansistrano_release_path.stdout }}/{{ ansistrano_get_url | basename }}" 11 | -------------------------------------------------------------------------------- /demo/files/code/etc/ansible/roles/carlosbuenosvinos.ansistrano-deploy/tasks/update-code/download_unarchive.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - include: download.yml 3 | 4 | - name: ANSISTRANO | download_unarchive | Set archived file 5 | set_fact: 6 | ansistrano_archived_file: "{{ ansistrano_release_path.stdout }}/{{ ansistrano_get_url | basename }}" 7 | 8 | - include: unarchive.yml 9 | -------------------------------------------------------------------------------- /demo/files/code/etc/ansible/roles/carlosbuenosvinos.ansistrano-deploy/tasks/update-code/rsync.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: ANSISTRANO | RSYNC | Get shared path (in rsync case) 3 | command: echo "{{ ansistrano_shared_path.stdout }}/.shared-copy" 4 | register: ansistrano_shared_rsync_copy_path 5 | 6 | - name: ANSISTRANO | RSYNC | Rsync application files to remote shared copy 7 | synchronize: 8 | src: "{{ ansistrano_deploy_from }}" 9 | dest: "{{ ansistrano_shared_rsync_copy_path.stdout }}" 10 | set_remote_user: "{{ ansistrano_rsync_set_remote_user }}" 11 | recursive: yes 12 | delete: yes 13 | archive: yes 14 | compress: yes 15 | rsync_opts: "{{ ansistrano_rsync_extra_params }}" 16 | 17 | - name: ANSISTRANO | RSYNC | Deploy existing code to servers 18 | command: cp -a {{ ansistrano_shared_rsync_copy_path.stdout }} {{ ansistrano_release_path.stdout }} 19 | -------------------------------------------------------------------------------- /demo/files/code/etc/ansible/roles/carlosbuenosvinos.ansistrano-deploy/tasks/update-code/s3.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: ANSISTRANO | S3 | Create release folder 3 | file: 4 | state: directory 5 | path: "{{ ansistrano_release_path.stdout }}" 6 | 7 | - name: ANSISTRANO | S3 | Get object from S3 8 | s3: 9 | bucket: "{{ ansistrano_s3_bucket }}" 10 | object: "{{ ansistrano_s3_object }}" 11 | dest: "{{ ansistrano_release_path.stdout }}/{{ ansistrano_s3_object | basename }}" 12 | mode: get 13 | region: "{{ ansistrano_s3_region }}" 14 | aws_access_key: "{{ ansistrano_s3_aws_access_key | default(omit) }}" 15 | aws_secret_key: "{{ ansistrano_s3_aws_secret_key | default(omit) }}" 16 | -------------------------------------------------------------------------------- /demo/files/code/etc/ansible/roles/carlosbuenosvinos.ansistrano-deploy/tasks/update-code/s3_unarchive.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - include: s3.yml 3 | 4 | - name: ANSISTRANO | s3_unarchive | Set archived file 5 | set_fact: 6 | ansistrano_archived_file: "{{ ansistrano_release_path.stdout }}/{{ ansistrano_s3_object | basename }}" 7 | 8 | - include: unarchive.yml -------------------------------------------------------------------------------- /demo/files/code/etc/ansible/roles/carlosbuenosvinos.ansistrano-deploy/tasks/update-code/unarchive.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: ANSISTRANO | Unarchive | Unarchive source 3 | unarchive: 4 | copy: no 5 | src: "{{ ansistrano_archived_file }}" 6 | dest: "{{ ansistrano_release_path.stdout }}" 7 | 8 | - name: ANSISTRANO | Unarchive | Delete archived file 9 | file: 10 | path: "{{ ansistrano_archived_file }}" 11 | state: absent -------------------------------------------------------------------------------- /demo/files/code/etc/ansible/roles/carlosbuenosvinos.ansistrano-deploy/test/tasks/create-internal-paths.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # We cannot create the symlinks unless these subfolders exist in the destination release folder 3 | - name: ANSISTRANO | Ensure internal path foo exists 4 | file: 5 | state: directory 6 | path: "{{ ansistrano_release_path.stdout }}/foo" 7 | 8 | - name: ANSISTRANO | Ensure internal path xxx/yyy exists 9 | file: 10 | state: directory 11 | path: "{{ ansistrano_release_path.stdout }}/xxx/yyy" 12 | 13 | - name: ANSISTRANO | Ensure internal path files exists 14 | file: 15 | state: directory 16 | path: "{{ ansistrano_release_path.stdout }}/files" 17 | -------------------------------------------------------------------------------- /demo/files/code/etc/ansible/roles/carlosbuenosvinos.ansistrano-deploy/test/tasks/create-shared-paths.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: ANSISTRANO | Ensure shared path 1 exists 3 | file: 4 | state: directory 5 | path: "{{ ansistrano_deploy_to }}/shared/blah" 6 | 7 | - name: ANSISTRANO | Ensure shared path 2 exists 8 | file: 9 | state: directory 10 | path: "{{ ansistrano_deploy_to }}/shared/foo/bar" 11 | 12 | - name: ANSISTRANO | Ensure shared path 3 exists 13 | file: 14 | state: directory 15 | path: "{{ ansistrano_deploy_to }}/shared/xxx/yyy/zzz" 16 | 17 | - name: ANSISTRANO | Ensure shared file 1 exists 18 | file: 19 | state: touch 20 | path: "{{ ansistrano_deploy_to }}/shared/test.txt" 21 | 22 | - name: ANSISTRANO | Ensure shared files folder exists 23 | file: 24 | state: directory 25 | path: "{{ ansistrano_deploy_to }}/shared/files" 26 | 27 | - name: ANSISTRANO | Ensure shared file 2 exists 28 | file: 29 | state: touch 30 | path: "{{ ansistrano_deploy_to }}/shared/files/test.txt" 31 | -------------------------------------------------------------------------------- /demo/files/code/etc/ssh/ssh_config: -------------------------------------------------------------------------------- 1 | SendEnv LANG LC_* 2 | HashKnownHosts yes 3 | GSSAPIAuthentication yes 4 | GSSAPIDelegateCredentials no 5 | StrictHostKeyChecking no 6 | -------------------------------------------------------------------------------- /demo/files/shared/ssh/authorized_keys: -------------------------------------------------------------------------------- 1 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDDer3R8g1Fz18k7qVCY7wdwkmjATak/MaEjVErVoMTcmmyVgz9LxgviEhZdALm98Ru603VGvxJSR2zl7B4ZP7GA9S66dv6T/OU9v7RWZOcrjcYpGu6NJaY8NWDskJx3MsO50iiLdIy8sVLYbWGL2Ca1qqOpa/nCPRaGlwLGsS5SLrQAVDoEvivvo8FnWf1A8M/uatEtIA8J8nvwirVHSp3eIt9ZDfsu0+153o7mV6VzcqTTgIoCj+C3CK8tw9+H7s0zT96Wt/ph2wy16wAfoQCFi0nKwoEUL71jF6uggHD+0Zn7rC54I/9ovgHJVR0iiCnYUH75ZzDqX52pu4Tdh1b docker-demo 2 | -------------------------------------------------------------------------------- /demo/files/shared/ssh/id_rsa.pub: -------------------------------------------------------------------------------- 1 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDDer3R8g1Fz18k7qVCY7wdwkmjATak/MaEjVErVoMTcmmyVgz9LxgviEhZdALm98Ru603VGvxJSR2zl7B4ZP7GA9S66dv6T/OU9v7RWZOcrjcYpGu6NJaY8NWDskJx3MsO50iiLdIy8sVLYbWGL2Ca1qqOpa/nCPRaGlwLGsS5SLrQAVDoEvivvo8FnWf1A8M/uatEtIA8J8nvwirVHSp3eIt9ZDfsu0+153o7mV6VzcqTTgIoCj+C3CK8tw9+H7s0zT96Wt/ph2wy16wAfoQCFi0nKwoEUL71jF6uggHD+0Zn7rC54I/9ovgHJVR0iiCnYUH75ZzDqX52pu4Tdh1b docker-demo 2 | -------------------------------------------------------------------------------- /demo/files/tomcat/etc/ssh/ssh_host_rsa_key.pub: -------------------------------------------------------------------------------- 1 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDDer3R8g1Fz18k7qVCY7wdwkmjATak/MaEjVErVoMTcmmyVgz9LxgviEhZdALm98Ru603VGvxJSR2zl7B4ZP7GA9S66dv6T/OU9v7RWZOcrjcYpGu6NJaY8NWDskJx3MsO50iiLdIy8sVLYbWGL2Ca1qqOpa/nCPRaGlwLGsS5SLrQAVDoEvivvo8FnWf1A8M/uatEtIA8J8nvwirVHSp3eIt9ZDfsu0+153o7mV6VzcqTTgIoCj+C3CK8tw9+H7s0zT96Wt/ph2wy16wAfoQCFi0nKwoEUL71jF6uggHD+0Zn7rC54I/9ovgHJVR0iiCnYUH75ZzDqX52pu4Tdh1b docker-demo 2 | -------------------------------------------------------------------------------- /demo/files/tomcat/etc/supervisord.d/ssh.ini: -------------------------------------------------------------------------------- 1 | [program:sshd] 2 | directory=/usr/local/ 3 | command=/usr/sbin/sshd -D 4 | autostart=true 5 | autorestart=true 6 | redirect_stderr=true 7 | -------------------------------------------------------------------------------- /demo/files/tomcat/etc/supervisord.d/tomcat.ini: -------------------------------------------------------------------------------- 1 | [program:tomcat] 2 | command=/usr/libexec/tomcat/server start ; 程序启动命令 3 | autostart=true ; 在supervisord启动的时候也自动启动 4 | startsecs=10 ; 启动10秒后没有异常退出,就表示进程正常启动了,默认为1秒 5 | autorestart=true ; 程序退出后自动重启,可选值:[unexpected,true,false],默认为unexpected,表示进程意外杀死后才重启 6 | startretries=3 ; 启动失败自动重试次数,默认是3 7 | ; user=tomcat ; 用哪个用户启动进程,默认是root 8 | priority=999 ; 进程启动优先级,默认999,值小的优先启动 9 | redirect_stderr=true ; 把stderr重定向到stdout,默认false 10 | ; stdout_logfile_maxbytes=20MB ; stdout 日志文件大小,默认50MB 11 | ; stdout_logfile_backups = 20 ; stdout 日志文件备份数,默认是10 12 | ; stdout 日志文件,需要注意当指定目录不存在时无法正常启动,所以需要手动创建目录(supervisord 会自动创建日志文件) 13 | ; stdout_logfile=/opt/apache-tomcat-8.0.35/logs/catalina.out 14 | stopasgroup=false ;默认为false,进程被杀死时,是否向这个进程组发送stop信号,包括子进程 15 | killasgroup=false ;默认为false,向进程组发送kill信号,包括子进程 16 | -------------------------------------------------------------------------------- /demo/files/tomcat/etc/yum.repos.d/CentOS-Epel.repo: -------------------------------------------------------------------------------- 1 | [epel] 2 | name=Extra Packages for Enterprise Linux 7 - $basearch 3 | baseurl=http://mirrors.aliyun.com/epel/7/$basearch 4 | http://mirrors.aliyuncs.com/epel/7/$basearch 5 | failovermethod=priority 6 | enabled=1 7 | gpgcheck=0 8 | gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7 9 | 10 | [epel-debuginfo] 11 | name=Extra Packages for Enterprise Linux 7 - $basearch - Debug 12 | baseurl=http://mirrors.aliyun.com/epel/7/$basearch/debug 13 | http://mirrors.aliyuncs.com/epel/7/$basearch/debug 14 | failovermethod=priority 15 | enabled=0 16 | gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7 17 | gpgcheck=0 18 | 19 | [epel-source] 20 | name=Extra Packages for Enterprise Linux 7 - $basearch - Source 21 | baseurl=http://mirrors.aliyun.com/epel/7/SRPMS 22 | http://mirrors.aliyuncs.com/epel/7/SRPMS 23 | failovermethod=priority 24 | enabled=0 25 | gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7 26 | gpgcheck=0 27 | -------------------------------------------------------------------------------- /demo/init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | cd $(dirname $0) 6 | 7 | if [ -f ../tars/settings/local.py ]; then 8 | echo "local.py exists, no need to copy sample file" 9 | else 10 | echo "local.py not exists, copying sample file" 11 | cp ../tars/settings/local.py.example ../tars/settings/local.py && echo 'file copied' 12 | fi 13 | -------------------------------------------------------------------------------- /doc/images/API-Application-C.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/doc/images/API-Application-C.png -------------------------------------------------------------------------------- /doc/images/API-Application-List.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/doc/images/API-Application-List.png -------------------------------------------------------------------------------- /doc/images/API-Group-C.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/doc/images/API-Group-C.png -------------------------------------------------------------------------------- /doc/images/API-Group-List.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/doc/images/API-Group-List.png -------------------------------------------------------------------------------- /doc/images/API-Group-RD.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/doc/images/API-Group-RD.png -------------------------------------------------------------------------------- /doc/images/API-Group-U.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/doc/images/API-Group-U.png -------------------------------------------------------------------------------- /doc/images/API-Package-C.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/doc/images/API-Package-C.png -------------------------------------------------------------------------------- /doc/images/API-Package-List.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/doc/images/API-Package-List.png -------------------------------------------------------------------------------- /doc/images/API-Server-C.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/doc/images/API-Server-C.png -------------------------------------------------------------------------------- /doc/images/API-Server-List.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/doc/images/API-Server-List.png -------------------------------------------------------------------------------- /doc/images/Admin-Application-New.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/doc/images/Admin-Application-New.png -------------------------------------------------------------------------------- /doc/images/Admin-Application-RDL.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/doc/images/Admin-Application-RDL.png -------------------------------------------------------------------------------- /doc/images/Admin-Group-CU.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/doc/images/Admin-Group-CU.png -------------------------------------------------------------------------------- /doc/images/Admin-Group-RDL.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/doc/images/Admin-Group-RDL.png -------------------------------------------------------------------------------- /doc/images/Admin-Overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/doc/images/Admin-Overview.png -------------------------------------------------------------------------------- /doc/images/Admin-Package-New1-CU.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/doc/images/Admin-Package-New1-CU.png -------------------------------------------------------------------------------- /doc/images/Admin-Package-New2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/doc/images/Admin-Package-New2-1.png -------------------------------------------------------------------------------- /doc/images/Admin-Package-New2-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/doc/images/Admin-Package-New2-2.png -------------------------------------------------------------------------------- /doc/images/Admin-Package-RDL.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/doc/images/Admin-Package-RDL.png -------------------------------------------------------------------------------- /doc/images/Admin-Server-CU.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/doc/images/Admin-Server-CU.png -------------------------------------------------------------------------------- /doc/images/Admin-Server-RDL.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/doc/images/Admin-Server-RDL.png -------------------------------------------------------------------------------- /doc/images/Demo-Screenshots-Deployment-Configure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/doc/images/Demo-Screenshots-Deployment-Configure.png -------------------------------------------------------------------------------- /doc/images/Demo-Screenshots-Deployment-Init.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/doc/images/Demo-Screenshots-Deployment-Init.png -------------------------------------------------------------------------------- /doc/images/Demo-Screenshots-Deployment-Packages.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/doc/images/Demo-Screenshots-Deployment-Packages.png -------------------------------------------------------------------------------- /doc/images/Demo-Screenshots-Deployment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/doc/images/Demo-Screenshots-Deployment.png -------------------------------------------------------------------------------- /doc/images/Demo-Screenshots-Web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/doc/images/Demo-Screenshots-Web.png -------------------------------------------------------------------------------- /doc/images/Demo-Services.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/doc/images/Demo-Services.png -------------------------------------------------------------------------------- /doc/images/Development-Docker-Configure-DB.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/doc/images/Development-Docker-Configure-DB.png -------------------------------------------------------------------------------- /doc/images/Development-Docker-Finish.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/doc/images/Development-Docker-Finish.png -------------------------------------------------------------------------------- /doc/images/Development-Docker-Services.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/doc/images/Development-Docker-Services.png -------------------------------------------------------------------------------- /doc/images/Development-Screenshots-Web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/doc/images/Development-Screenshots-Web.png -------------------------------------------------------------------------------- /docker-compose-frontend.yml: -------------------------------------------------------------------------------- 1 | frontend_build: 2 | image: node:6 3 | volumes: 4 | - .:/code 5 | working_dir: /code 6 | command: make frontend 7 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | db: 2 | image: mysql:5.7 3 | ports: 4 | - "3306:3306" 5 | environment: 6 | - MYSQL_ROOT_PASSWORD=my-secret-pw 7 | - MYSQL_DATABASE=tars 8 | - MYSQL_USER=tars 9 | - MYSQL_PASSWORD=test1234 10 | - MYSQL_CHARSET=utf8 11 | 12 | backend: 13 | image: redis 14 | ports: 15 | - "6379:6379" 16 | 17 | es: 18 | image: elasticsearch:5 19 | ports: 20 | - '9200:9200' 21 | 22 | worker: 23 | build: . 24 | # command: python manage.py celery -A roll_engine worker --autoreload -l info --settings=tars.settings.docker 25 | command: celery worker -A roll_engine -l info 26 | volumes: 27 | - .:/code 28 | environment: 29 | - C_FORCE_ROOT=1 30 | - DJANGO_SETTINGS_MODULE=tars.settings.docker 31 | links: 32 | - backend 33 | - db 34 | - es 35 | 36 | web: 37 | build: . 38 | command: python manage.py runserver 0.0.0.0:8000 --settings=tars.settings.docker 39 | volumes: 40 | - .:/code 41 | ports: 42 | - "8000:8000" 43 | links: 44 | - db 45 | - backend 46 | - es 47 | 48 | -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == "__main__": 6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tars.settings") 7 | 8 | from django.core.management import execute_from_command_line 9 | 10 | execute_from_command_line(sys.argv) 11 | -------------------------------------------------------------------------------- /requirements/base.txt: -------------------------------------------------------------------------------- 1 | # roll_engine requirements 2 | celery>=3.0,<4.0 3 | django-fsm 4 | 5 | # rest_client requirements 6 | pyyaml 7 | urllib3>=1.21.1,<1.23 8 | requests>=2.6.0 9 | elasticsearch 10 | 11 | # tars requirements 12 | decisionTable 13 | Django>=1.8,<1.9 14 | django-constance>=1.2 15 | django-picklefield 16 | django-filter<=0.11.0 17 | djangorestframework>=3.0.4,<3.1.0 18 | djangorestframework-camel-case 19 | djangorestframework-jsonp 20 | MySQL-python 21 | sqlparse 22 | redis 23 | raven 24 | kafka-python 25 | -------------------------------------------------------------------------------- /requirements/local.txt: -------------------------------------------------------------------------------- 1 | -i http://pypi.douban.com/simple 2 | -r base.txt 3 | 4 | ansible<2.0 5 | django-extensions<1.7 6 | django-debug-toolbar 7 | django-celery>=3.1.16 8 | graphviz 9 | Werkzeug 10 | httpretty 11 | vcrpy 12 | -------------------------------------------------------------------------------- /requirements/production.txt: -------------------------------------------------------------------------------- 1 | -r base.txt 2 | 3 | uwsgi 4 | -------------------------------------------------------------------------------- /rest_client/__init__.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | import re 4 | from rest_client.clients import ( 5 | get_es_client, 6 | get_salt_client, 7 | ) 8 | 9 | pattern = re.compile("^get_[a-z_]+_client$") 10 | 11 | __all__ = tuple(i for i in globals().keys() if pattern.search(i) is not None) 12 | -------------------------------------------------------------------------------- /rest_client/clients/__init__.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | from rest_client.utils import camel2underscore 4 | from .es import get_es_client 5 | from .salt import get_salt_client 6 | 7 | __all__ = ('get_es_client', 'get_salt_client',) 8 | 9 | _globals = globals() 10 | 11 | 12 | # Add client to __all__ as get_xxx_client 13 | def __factory(klass): 14 | def func(): 15 | return klass 16 | func.__name__ = 'get_{}_client'.format(camel2underscore(klass.__name__)) 17 | return func 18 | -------------------------------------------------------------------------------- /rest_client/clients/es.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | import urlparse 4 | from elasticsearch import Elasticsearch 5 | 6 | from rest_client.decorators import osg 7 | from rest_client.exceptions import ESClientError, ServerResponseException 8 | from .core import JsonClient 9 | 10 | 11 | class ES(JsonClient): 12 | _es = None 13 | _url_base = None 14 | _env = 'default' 15 | 16 | @classmethod 17 | def config(cls, key=None): 18 | return super(ES, cls).config('ES', key) 19 | 20 | 21 | def get_es_client(env='default'): 22 | es_kls = ES 23 | 24 | if es_kls._es is None: 25 | es_kls._env = 'default' 26 | es_kls.build_url_base() 27 | es_kls._es = Elasticsearch(es_kls._url_base) 28 | 29 | return es_kls._es 30 | -------------------------------------------------------------------------------- /roll_engine/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/roll_engine/__init__.py -------------------------------------------------------------------------------- /roll_engine/celery.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | import os 3 | 4 | from django.conf import settings 5 | from celery import Celery 6 | 7 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'tars.settings') 8 | 9 | app = Celery('tars') 10 | app.config_from_object('django.conf:settings') 11 | app.autodiscover_tasks(lambda: settings.INSTALLED_APPS) 12 | 13 | 14 | @app.task(bind=True) 15 | def debug_task(self): 16 | print('Request: {!r}'.format(self.request)) 17 | -------------------------------------------------------------------------------- /roll_engine/constants.py: -------------------------------------------------------------------------------- 1 | # Deployment Statuses 2 | PENDING = 'PENDING' 3 | SMOKING = 'SMOKING' 4 | SMOKE_SUCCESS = 'SMOKE_SUCCESS' 5 | SMOKE_SUCCESS_BRAKED = 'SMOKE_SUCCESS_BRAKED' 6 | SMOKE_FAILURE_BRAKED = 'SMOKE_FAILURE_BRAKED' 7 | SMOKE_FAILURE = 'SMOKE_FAILURE' 8 | SMOKE_BRAKED = 'SMOKE_BRAKED' 9 | BAKING = 'BAKING' 10 | BAKE_SUCCESS = 'BAKE_SUCCESS' 11 | BAKE_SUCCESS_BRAKED = 'BAKE_SUCCESS_BRAKED' 12 | BAKE_FAILURE_BRAKED = 'BAKE_FAILURE_BRAKED' 13 | BAKE_FAILURE = 'BAKE_FAILURE' 14 | BAKE_BRAKED = 'BAKE_BRAKED' 15 | ROLLING_OUT = 'ROLLING_OUT' 16 | ROLLOUT_SUCCESS = 'ROLLOUT_SUCCESS' 17 | ROLLOUT_SUCCESS_BRAKED = 'ROLLOUT_SUCCESS_BRAKED' 18 | ROLLOUT_FAILURE_BRAKED = 'ROLLOUT_FAILURE_BRAKED' 19 | ROLLOUT_FAILURE = 'ROLLOUT_FAILURE' 20 | ROLLOUT_BRAKED = 'ROLLOUT_BRAKED' 21 | SUCCESS = 'SUCCESS' 22 | FAILURE = 'FAILURE' 23 | REVOKED = 'REVOKED' 24 | 25 | 26 | # DeploymentBatch Statuses 27 | PENDING = PENDING 28 | DEPLOYING = 'DEPLOYING' 29 | SUCCESS = SUCCESS 30 | FAILURE = FAILURE 31 | REVOKED = REVOKED 32 | 33 | 34 | # DeploymentTarget Statuses 35 | PENDING = PENDING 36 | DISABLING = 'DISABLING' 37 | DISABLE_SUCCESS = 'DISABLE_SUCCESS' 38 | DISABLE_FAILURE = 'DISABLE_FAILURE' 39 | ENABLING = 'ENABLING' 40 | ENABLE_SUCCESS = 'ENABLE_SUCCESS' 41 | ENABLE_FAILURE = 'ENABLE_FAILURE' 42 | SUCCESS = SUCCESS 43 | FAILURE = FAILURE 44 | REVOKED = REVOKED 45 | -------------------------------------------------------------------------------- /roll_engine/exceptions.py: -------------------------------------------------------------------------------- 1 | class DeploymentError(Exception): 2 | pass 3 | 4 | 5 | class BatchPatternError(DeploymentError): 6 | pass 7 | 8 | 9 | class MetaMissing(DeploymentError): 10 | pass 11 | 12 | 13 | class JobMissing(DeploymentError): 14 | pass 15 | 16 | 17 | class StatusError(DeploymentError): 18 | pass 19 | 20 | 21 | class ActionNotExist(DeploymentError): 22 | pass 23 | 24 | 25 | class ActionNotAllowed(DeploymentError): 26 | pass 27 | 28 | 29 | class ActionFailed(DeploymentError): 30 | pass 31 | -------------------------------------------------------------------------------- /roll_engine/fsm/__init__.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | import inspect 4 | from functools import wraps 5 | 6 | from django_fsm import transition as fsm_transition 7 | 8 | from roll_engine.models.base import FSMedModel 9 | 10 | 11 | def transition(**kwds): 12 | def decorator(func): 13 | kwds['field'] = FSMedModel._meta.get_field('status') 14 | fsm_trans_func = fsm_transition(**kwds)(func) 15 | 16 | @wraps(func) 17 | def func_wrapper(*args, **kwargs): 18 | return fsm_trans_func(*args, **kwargs) 19 | return func_wrapper 20 | return decorator 21 | 22 | from .deployment import * 23 | from .batch import * 24 | from .target import * 25 | 26 | __all__ = [v for k, v in globals().items() 27 | if not k.startswith('_') and inspect.isclass(v)] 28 | -------------------------------------------------------------------------------- /roll_engine/models/__init__.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | import inspect 4 | 5 | from .deployments import * 6 | from .batches import * 7 | from .targets import * 8 | from .actions import * 9 | from .configs import * 10 | from .base import FSMedModel 11 | 12 | 13 | __all__ = [v for k, v in globals().items() 14 | if not k.startswith('_') and inspect.isclass(v)] 15 | -------------------------------------------------------------------------------- /roll_engine/models/actions.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | from django.db import models 4 | 5 | from roll_engine.db import TimestampedModel 6 | 7 | 8 | class DeploymentAction(TimestampedModel): 9 | action = models.CharField(max_length=255, null=True, blank=True) 10 | message = models.CharField(max_length=255, null=True, blank=True) 11 | operator = models.CharField(max_length=55, null=True, blank=True) 12 | start_time = models.DateTimeField(auto_now_add=True, null=True, blank=True) 13 | 14 | class Meta: 15 | abstract = True 16 | 17 | def __unicode__(self): 18 | return self.action 19 | -------------------------------------------------------------------------------- /roll_engine/models/batches.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | from django.db import models 4 | 5 | from roll_engine.fsm import BatchFSMixin 6 | from roll_engine.mixins import BatchMixin 7 | from roll_engine.exceptions import DeploymentError 8 | from .base import FSMedModel, InheritanceMetaclass 9 | 10 | 11 | class DeploymentBatch(BatchMixin, BatchFSMixin, FSMedModel): 12 | __metaclass__ = InheritanceMetaclass 13 | 14 | index = models.IntegerField(null=True) 15 | pause_time = models.IntegerField(default=0) 16 | FORT_INDEX = 1 17 | 18 | class Meta: 19 | abstract = True 20 | 21 | @classmethod 22 | def validate_meta(cls): 23 | pass 24 | 25 | def get_object(self): 26 | return self 27 | 28 | def is_fort_batch(self): 29 | raise DeploymentError('return boolean to indicate whether a fort batch') 30 | 31 | def save(self, *args, **kwargs): 32 | if self.pk is None: 33 | if self.deployment is not None: 34 | self.pause_time = self.deployment.config.pause_time 35 | super(DeploymentBatch, self).save(*args, **kwargs) 36 | 37 | def is_reach_up_server_threshold(self): 38 | return False 39 | -------------------------------------------------------------------------------- /roll_engine/models/configs.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | from roll_engine.db import TimestampedModel 4 | 5 | 6 | class DeploymentConfig(TimestampedModel): 7 | MANUAL = 'm' 8 | AUTO = 'a' 9 | MODE_CHOICES = ( 10 | (MANUAL, 'manual'), 11 | (AUTO, 'auto') 12 | ) 13 | batch_pattern = models.CharField(max_length=300, null=True) 14 | pause_time = models.IntegerField(default=0) 15 | mode = models.CharField(max_length=1, choices=MODE_CHOICES, default=AUTO) 16 | 17 | class Meta: 18 | abstract = True 19 | 20 | def __unicode__(self): 21 | return self.batch_pattern 22 | -------------------------------------------------------------------------------- /roll_engine/utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/roll_engine/utils/__init__.py -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | name = tars 3 | version = 0.1 4 | summary = TARS 5 | description-file = 6 | README.rst 7 | author = TARS 8 | author-email = tars@ctrip.com 9 | 10 | [files] 11 | packages = 12 | tars 13 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import setuptools 3 | 4 | setuptools.setup( 5 | setup_requires=['pbr'], 6 | pbr=True) 7 | -------------------------------------------------------------------------------- /tars/__init__.py: -------------------------------------------------------------------------------- 1 | from tars.engine.celery_app import app 2 | -------------------------------------------------------------------------------- /tars/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/api/__init__.py -------------------------------------------------------------------------------- /tars/api/filters.py: -------------------------------------------------------------------------------- 1 | from rest_framework.filters import DjangoFilterBackend 2 | 3 | from tars.api.decorators import status, running, ids 4 | 5 | 6 | class StatusFilterBackend(DjangoFilterBackend): 7 | @status() 8 | def filter_queryset(self, request, queryset, view): 9 | queryset = super(StatusFilterBackend, self).filter_queryset( 10 | request, queryset, view) 11 | return queryset 12 | 13 | 14 | class DeploymentFilterBackend(StatusFilterBackend): 15 | @running() 16 | @ids(param='app_id', field='application__id') 17 | def filter_queryset(self, request, queryset, view): 18 | queryset = super(DeploymentFilterBackend, self).filter_queryset( 19 | request, queryset, view) 20 | return queryset 21 | 22 | 23 | class BatchFilterBackend(StatusFilterBackend): 24 | def filter_queryset(self, request, queryset, view): 25 | queryset = super(BatchFilterBackend, self).filter_queryset( 26 | request, queryset, view) 27 | return queryset 28 | -------------------------------------------------------------------------------- /tars/api/permissions.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | from django.conf import settings 4 | from constance import config 5 | 6 | from rest_framework import permissions 7 | 8 | from tars.deployment.models import TarsDeploymentAction 9 | from tars.application.models import Application 10 | 11 | logger = logging.getLogger(__name__) 12 | 13 | 14 | class IsDebugMode(permissions.BasePermission): 15 | def has_permission(self, request, view): 16 | if getattr(settings, 'DEBUG', False): 17 | return True 18 | return False 19 | 20 | class PostOnlyAuth(permissions.IsAuthenticated): 21 | 22 | def has_permission(self, request, view): 23 | if request.method == 'POST' and view.action is not None: 24 | 25 | if super(PostOnlyAuth, self).has_permission(request, view): 26 | return True 27 | else: 28 | app_id = request.data.get('application') or view.get_object().application_id 29 | TarsDeploymentAction.objects.create( 30 | action='auth', 31 | operator=request.user.username, 32 | message='permission deny on {} of application {}'.format(view.action, app_id)) 33 | return False 34 | else: 35 | return True 36 | -------------------------------------------------------------------------------- /tars/api/serializers/__init__.py: -------------------------------------------------------------------------------- 1 | from .application import * 2 | from .server import * 3 | from .deployment import * 4 | from .base import LogSerializer 5 | 6 | __all__ = globals() 7 | -------------------------------------------------------------------------------- /tars/api/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/api/tests/__init__.py -------------------------------------------------------------------------------- /tars/api/tests/test_group.py: -------------------------------------------------------------------------------- 1 | from rest_framework.test import APITestCase 2 | 3 | from tars.application.models import Application 4 | from tars.server.models import Group 5 | 6 | 7 | class TestGroupAPI(APITestCase): 8 | url = '/api/v1/groups' 9 | data = [ 10 | { 11 | 'name': 'group1', 12 | 'group_id': 1, 13 | 'site_name': 'Ctrip', 14 | 'fort': 'FORT1' 15 | }, 16 | { 17 | 'name': 'group2', 18 | 'group_id': 2, 19 | 'site_name': 'Ctrip', 20 | 'fort': 'FORT2' 21 | } 22 | ] 23 | 24 | def setUp(self): 25 | app_data = {'name': 'app1', 'id': 1, 26 | 'environment': 'uat', 'ignore_fort': False} 27 | app = Application.objects.create(**app_data) 28 | 29 | for item in self.data: 30 | Group.objects.create(application=app, **item) 31 | 32 | def test_sync(self): 33 | pass 34 | -------------------------------------------------------------------------------- /tars/api/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import url, include 2 | 3 | from rest_framework import routers 4 | 5 | from tars.api.views import application as application_views 6 | from tars.api.views import server as server_views 7 | from tars.api.views import deployment as deployment_views 8 | from tars.api.views import log as log_views 9 | 10 | 11 | router = routers.DefaultRouter(trailing_slash=False) 12 | 13 | router.register(r'applications', application_views.ApplicationViewSet) 14 | router.register(r'packages', application_views.PackageViewSet) 15 | router.register(r'groups', server_views.GroupViewSet) 16 | router.register(r'join_groups', server_views.JoinedGroupViewSet) 17 | router.register(r'servers', server_views.ServerViewSet) 18 | router.register(r'deployments', deployment_views.DeploymentViewSet, 19 | base_name='deployment') 20 | router.register(r'configs', deployment_views.DeploymentConfigViewSet) 21 | router.register(r'batches', deployment_views.DeploymentBatchViewSet) 22 | router.register(r'targets', deployment_views.DeploymentTargetViewSet) 23 | router.register(r'actions', deployment_views.DeploymentActionViewSet) 24 | 25 | urlpatterns = [ 26 | url(r'^logs', log_views.LogViewSet.as_view({'get': 'list'})), 27 | url(r'^', include(router.urls)), 28 | ] 29 | -------------------------------------------------------------------------------- /tars/api/views/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/api/views/__init__.py -------------------------------------------------------------------------------- /tars/application/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/application/__init__.py -------------------------------------------------------------------------------- /tars/application/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | from tars.application import models 4 | 5 | 6 | class ApplicationAdmin(admin.ModelAdmin): 7 | list_display = ('name',) 8 | admin.site.register(models.Application, ApplicationAdmin) 9 | 10 | 11 | class PackageAdmin(admin.ModelAdmin): 12 | list_display = ('name', 'version', 'application') 13 | admin.site.register(models.Package, PackageAdmin) 14 | -------------------------------------------------------------------------------- /tars/deployment/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/deployment/__init__.py -------------------------------------------------------------------------------- /tars/deployment/admin.py: -------------------------------------------------------------------------------- 1 | from decisionTable import DecisionTable 2 | 3 | from constance.admin import ConstanceAdmin, ConstanceForm, Config 4 | from constance import LazyConfig 5 | 6 | from django.contrib import admin 7 | 8 | from tars.deployment import models 9 | 10 | 11 | config = LazyConfig() 12 | 13 | class CustomConstanceForm(ConstanceForm): 14 | def clean(self): 15 | cleaned_data = super(CustomConstanceForm, self).clean() 16 | 17 | dt_keys = [k for k in cleaned_data.keys() if 'DECISION_TABLE' in k] 18 | # validate decision table string format 19 | try: 20 | for key in dt_keys: 21 | dt = DecisionTable(cleaned_data[key]) 22 | if not dt.decisions: 23 | self.add_error(key, 'The decisions in your input value is empty') 24 | except ValueError as e: 25 | self.add_error(key, e) 26 | 27 | 28 | class ConfigAdmin(ConstanceAdmin): 29 | change_list_template = 'constance_change_list.html' 30 | change_list_form = CustomConstanceForm 31 | 32 | 33 | admin.site.unregister([Config]) 34 | admin.site.register([Config], ConfigAdmin) 35 | -------------------------------------------------------------------------------- /tars/deployment/models/__init__.py: -------------------------------------------------------------------------------- 1 | from .configs import TarsDeploymentConfig 2 | from .deployments import TarsDeployment, TarsFortDeployment 3 | from .actions import TarsDeploymentAction 4 | from .batches import TarsDeploymentBatch 5 | from .targets import TarsDeploymentTarget 6 | 7 | __all__ = (TarsDeploymentConfig, TarsDeployment, TarsFortDeployment, 8 | TarsDeploymentAction, TarsDeploymentBatch, TarsDeploymentTarget) 9 | -------------------------------------------------------------------------------- /tars/deployment/models/actions.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | from deployments import TarsDeployment 4 | from roll_engine.models import DeploymentAction 5 | 6 | 7 | class TarsDeploymentAction(DeploymentAction): 8 | deployment = models.ForeignKey( 9 | TarsDeployment, related_name='actions', db_constraint=False, null=True) 10 | finish_time = models.DateTimeField(auto_now_add=True, null=True, blank=True) 11 | 12 | class Meta: 13 | db_table = 'deployment_actions' 14 | 15 | def __unicode__(self): 16 | return self.action 17 | -------------------------------------------------------------------------------- /tars/deployment/models/configs.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from roll_engine.models import DeploymentConfig 3 | 4 | 5 | class TarsDeploymentConfig(DeploymentConfig): 6 | verify_timeout = models.IntegerField(null=True) 7 | startup_timeout = models.IntegerField(null=True) 8 | ignore_verify_result = models.BooleanField(default=False) 9 | restart_app_pool = models.BooleanField(default=False) 10 | 11 | class Meta: 12 | db_table = 'deployment_configs' 13 | 14 | def __unicode__(self): 15 | return self.batch_pattern 16 | -------------------------------------------------------------------------------- /tars/deployment/templatetags/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/deployment/templatetags/__init__.py -------------------------------------------------------------------------------- /tars/deployment/templatetags/app_filters.py: -------------------------------------------------------------------------------- 1 | from decisionTable import DecisionTable 2 | from django import template 3 | from django.template.defaultfilters import stringfilter 4 | 5 | 6 | register = template.Library() 7 | 8 | DECISION_TABLE_TEMPLATE = ''' 9 | 10 | 11 | 12 | {header} 13 | 14 | 15 | {decisions} 16 |
17 | ''' 18 | 19 | DT_INSTANCE = DecisionTable('=') 20 | 21 | 22 | @register.filter 23 | @stringfilter 24 | def decision_table(value): 25 | header, decisions = DT_INSTANCE._DecisionTable__tableStringParser(value) 26 | header_str = '
{name}
' 27 | 28 | header = [header_str.format(name=h) for h in header] 29 | decisions = [''+''.join(['{}'.format(v) for v in d])+'' 30 | for d in decisions] 31 | 32 | return DECISION_TABLE_TEMPLATE.format( 33 | header=''.join(header), decisions=''.join(decisions)) 34 | -------------------------------------------------------------------------------- /tars/engine/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /tars/engine/celery_app.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | 3 | from roll_engine.celery import app 4 | 5 | 6 | if "raven.contrib.django.raven_compat" in settings.INSTALLED_APPS: 7 | import raven 8 | from raven.contrib.celery import register_logger_signal, register_signal 9 | 10 | client = raven.Client(settings.RAVEN_CONFIG['dsn']) 11 | 12 | # register a custom filter to filter out duplicate logs 13 | register_logger_signal(client) 14 | 15 | # hook into the Celery error handler 16 | register_signal(client) 17 | -------------------------------------------------------------------------------- /tars/exceptions.py: -------------------------------------------------------------------------------- 1 | class TarsError(Exception): 2 | pass 3 | 4 | 5 | class SyncError(TarsError): 6 | pass 7 | 8 | 9 | class PackageError(TarsError): 10 | pass 11 | -------------------------------------------------------------------------------- /tars/middleware/__init__.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | import threading 4 | import logging 5 | 6 | from django.conf import settings 7 | 8 | from raven.contrib.django.raven_compat.middleware import is_ignorable_404 9 | 10 | 11 | class Sentry4XXCatchMiddleware(object): 12 | 13 | def process_response(self, request, response): 14 | from raven.contrib.django.models import client 15 | 16 | if response.status_code < 400 or response.status_code > 450 or is_ignorable_404(request.get_full_path()) or not client.is_enabled(): 17 | return response 18 | 19 | data = client.get_data_from_request(request) 20 | 21 | data.update({ 22 | 'level': logging.INFO, 23 | 'logger': 'http{0}'.format(str(response.status_code)), 24 | }) 25 | result = client.captureMessage( 26 | message='{0}: {1}'.format(getattr(response, 'status_text', 'Page Not Found'), request.build_absolute_uri()), data=data) 27 | if not result: 28 | return 29 | 30 | request.sentry = { 31 | 'project_id': data.get('project', client.remote.project), 32 | 'id': client.get_ident(result), 33 | } 34 | return response 35 | -------------------------------------------------------------------------------- /tars/server/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/server/__init__.py -------------------------------------------------------------------------------- /tars/settings/__init__.py: -------------------------------------------------------------------------------- 1 | from .local import * 2 | -------------------------------------------------------------------------------- /tars/settings/docker.py: -------------------------------------------------------------------------------- 1 | from .local import * 2 | # from .base import INSTALLED_APPS 3 | 4 | # SECURITY WARNING: don't run with debug turned on in production! 5 | # SECRET_KEY = '' 6 | DEBUG = True 7 | TEMPLATE_DEBUG = True 8 | 9 | # Database 10 | # https://docs.djangoproject.com/en/1.7/ref/settings/#databases 11 | DATABASES = { 12 | 'default': { 13 | 'ENGINE': 'django.db.backends.mysql', 14 | 'NAME': 'tars', 15 | 'USER': 'tars', 16 | 'PASSWORD': 'test1234', 17 | 'HOST': 'db', 18 | 'PORT': '3306', 19 | 'OPTIONS': { 20 | 'charset': 'utf8', 21 | }, 22 | 'TEST_CHARSET': 'utf8', 23 | 'TEST_COLLATION': 'utf8_general_ci', 24 | } 25 | } 26 | 27 | REST_CLIENT_SETTINGS = dict( 28 | ES={ 29 | 'default': { 30 | 'HOSTNAME': 'es', 31 | 'PORT': '9200', 32 | } 33 | }, 34 | ) 35 | 36 | # Celery 37 | BROKER_URL = 'redis://backend:6379/1' 38 | CELERY_RESULT_BACKEND = 'redis://backend:6379/1' 39 | 40 | CONSTANCE_REDIS_CONNECTION = 'redis://backend:6379/2' 41 | 42 | # ENABLE/DISABLE CMS synchronize 43 | CMS_SYNC = True 44 | 45 | ENV = 'dev' 46 | -------------------------------------------------------------------------------- /tars/surface/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/__init__.py -------------------------------------------------------------------------------- /tars/surface/decorators.py: -------------------------------------------------------------------------------- 1 | from functools import wraps 2 | 3 | from django.contrib.auth.decorators import login_required as dj_login_required 4 | from constance import config 5 | 6 | 7 | def login_required(func): 8 | @wraps(func) 9 | def func_wrapper(*args, **kwargs): 10 | if config.ENABLE_PERMISSION: 11 | return dj_login_required(func)(*args, **kwargs) 12 | else: 13 | return func(*args, **kwargs) 14 | return func_wrapper 15 | -------------------------------------------------------------------------------- /tars/surface/static/.jsbeautifyrc: -------------------------------------------------------------------------------- 1 | { 2 | "braceStyle": "collapse", 3 | "breakChainedMethods": false, 4 | "e4x": false, 5 | "evalCode": false, 6 | "indentChar": " ", 7 | "indentLevel": 0, 8 | "indentSize": 2, 9 | "indentWithTabs": false, 10 | "jslintHappy": false, 11 | "keepArrayIndentation": false, 12 | "keepFunctionIndentation": false, 13 | "maxPreserveNewlines": 4, 14 | "preserveNewlines": true, 15 | "spaceBeforeConditional": true, 16 | "spaceInParen": false, 17 | "space_after_anon_function": false, 18 | "unescapeStrings": false, 19 | "wrapLineLength": 0, 20 | "eol": "\n", 21 | "wrap_attributes": "auto", 22 | "wrap_attributes_indent_size": 4, 23 | "end_with_newline": true 24 | } -------------------------------------------------------------------------------- /tars/surface/static/admin/img/changelist-bg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/admin/img/changelist-bg.gif -------------------------------------------------------------------------------- /tars/surface/static/admin/img/changelist-bg_rtl.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/admin/img/changelist-bg_rtl.gif -------------------------------------------------------------------------------- /tars/surface/static/admin/img/default-bg-reverse.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/admin/img/default-bg-reverse.gif -------------------------------------------------------------------------------- /tars/surface/static/admin/img/default-bg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/admin/img/default-bg.gif -------------------------------------------------------------------------------- /tars/surface/static/admin/img/deleted-overlay.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/admin/img/deleted-overlay.gif -------------------------------------------------------------------------------- /tars/surface/static/admin/img/gis/move_vertex_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/admin/img/gis/move_vertex_off.png -------------------------------------------------------------------------------- /tars/surface/static/admin/img/gis/move_vertex_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/admin/img/gis/move_vertex_on.png -------------------------------------------------------------------------------- /tars/surface/static/admin/img/icon-no.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/admin/img/icon-no.gif -------------------------------------------------------------------------------- /tars/surface/static/admin/img/icon-unknown.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/admin/img/icon-unknown.gif -------------------------------------------------------------------------------- /tars/surface/static/admin/img/icon-yes.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/admin/img/icon-yes.gif -------------------------------------------------------------------------------- /tars/surface/static/admin/img/icon_addlink.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/admin/img/icon_addlink.gif -------------------------------------------------------------------------------- /tars/surface/static/admin/img/icon_alert.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/admin/img/icon_alert.gif -------------------------------------------------------------------------------- /tars/surface/static/admin/img/icon_calendar.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/admin/img/icon_calendar.gif -------------------------------------------------------------------------------- /tars/surface/static/admin/img/icon_changelink.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/admin/img/icon_changelink.gif -------------------------------------------------------------------------------- /tars/surface/static/admin/img/icon_clock.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/admin/img/icon_clock.gif -------------------------------------------------------------------------------- /tars/surface/static/admin/img/icon_deletelink.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/admin/img/icon_deletelink.gif -------------------------------------------------------------------------------- /tars/surface/static/admin/img/icon_error.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/admin/img/icon_error.gif -------------------------------------------------------------------------------- /tars/surface/static/admin/img/icon_searchbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/admin/img/icon_searchbox.png -------------------------------------------------------------------------------- /tars/surface/static/admin/img/icon_success.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/admin/img/icon_success.gif -------------------------------------------------------------------------------- /tars/surface/static/admin/img/inline-delete-8bit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/admin/img/inline-delete-8bit.png -------------------------------------------------------------------------------- /tars/surface/static/admin/img/inline-delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/admin/img/inline-delete.png -------------------------------------------------------------------------------- /tars/surface/static/admin/img/inline-restore-8bit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/admin/img/inline-restore-8bit.png -------------------------------------------------------------------------------- /tars/surface/static/admin/img/inline-restore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/admin/img/inline-restore.png -------------------------------------------------------------------------------- /tars/surface/static/admin/img/inline-splitter-bg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/admin/img/inline-splitter-bg.gif -------------------------------------------------------------------------------- /tars/surface/static/admin/img/nav-bg-grabber.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/admin/img/nav-bg-grabber.gif -------------------------------------------------------------------------------- /tars/surface/static/admin/img/nav-bg-reverse.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/admin/img/nav-bg-reverse.gif -------------------------------------------------------------------------------- /tars/surface/static/admin/img/nav-bg-selected.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/admin/img/nav-bg-selected.gif -------------------------------------------------------------------------------- /tars/surface/static/admin/img/nav-bg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/admin/img/nav-bg.gif -------------------------------------------------------------------------------- /tars/surface/static/admin/img/selector-icons.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/admin/img/selector-icons.gif -------------------------------------------------------------------------------- /tars/surface/static/admin/img/selector-search.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/admin/img/selector-search.gif -------------------------------------------------------------------------------- /tars/surface/static/admin/img/sorting-icons.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/admin/img/sorting-icons.gif -------------------------------------------------------------------------------- /tars/surface/static/admin/img/tooltag-add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/admin/img/tooltag-add.png -------------------------------------------------------------------------------- /tars/surface/static/admin/img/tooltag-arrowright.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/admin/img/tooltag-arrowright.png -------------------------------------------------------------------------------- /tars/surface/static/admin/js/LICENSE-JQUERY.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010 John Resig, http://jquery.com/ 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /tars/surface/static/admin/js/collapse.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | $(document).ready(function() { 3 | // Add anchor tag for Show/Hide link 4 | $("fieldset.collapse").each(function(i, elem) { 5 | // Don't hide if fields in this fieldset have errors 6 | if ($(elem).find("div.errors").length == 0) { 7 | $(elem).addClass("collapsed").find("h2").first().append(' (' + gettext("Show") + 9 | ')'); 10 | } 11 | }); 12 | // Add toggle to anchor tag 13 | $("fieldset.collapse a.collapse-toggle").click(function(ev) { 14 | if ($(this).closest("fieldset").hasClass("collapsed")) { 15 | // Show 16 | $(this).text(gettext("Hide")).closest("fieldset").removeClass("collapsed").trigger("show.fieldset", [$(this).attr("id")]); 17 | } else { 18 | // Hide 19 | $(this).text(gettext("Show")).closest("fieldset").addClass("collapsed").trigger("hide.fieldset", [$(this).attr("id")]); 20 | } 21 | return false; 22 | }); 23 | }); 24 | })(django.jQuery); 25 | -------------------------------------------------------------------------------- /tars/surface/static/admin/js/collapse.min.js: -------------------------------------------------------------------------------- 1 | (function(a){a(document).ready(function(){a("fieldset.collapse").each(function(c,b){a(b).find("div.errors").length==0&&a(b).addClass("collapsed").find("h2").first().append(' ('+gettext("Show")+")")});a("fieldset.collapse a.collapse-toggle").click(function(){a(this).closest("fieldset").hasClass("collapsed")?a(this).text(gettext("Hide")).closest("fieldset").removeClass("collapsed").trigger("show.fieldset",[a(this).attr("id")]):a(this).text(gettext("Show")).closest("fieldset").addClass("collapsed").trigger("hide.fieldset", 2 | [a(this).attr("id")]);return false})})})(django.jQuery); 3 | -------------------------------------------------------------------------------- /tars/surface/static/admin/js/jquery.init.js: -------------------------------------------------------------------------------- 1 | /* Puts the included jQuery into our own namespace using noConflict and passing 2 | * it 'true'. This ensures that the included jQuery doesn't pollute the global 3 | * namespace (i.e. this preserves pre-existing values for both window.$ and 4 | * window.jQuery). 5 | */ 6 | var django = django || {}; 7 | django.jQuery = jQuery.noConflict(true); 8 | -------------------------------------------------------------------------------- /tars/surface/static/admin/js/prepopulate.min.js: -------------------------------------------------------------------------------- 1 | (function(b){b.fn.prepopulate=function(e,g){return this.each(function(){var a=b(this),d=function(){if(!a.data("_changed")){var f=[];b.each(e,function(h,c){c=b(c);c.val().length>0&&f.push(c.val())});a.val(URLify(f.join(" "),g))}};a.data("_changed",false);a.change(function(){a.data("_changed",true)});a.val()||b(e.join(",")).keyup(d).change(d).focus(d)})}})(django.jQuery); 2 | -------------------------------------------------------------------------------- /tars/surface/static/django_extensions/img/indicator.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/django_extensions/img/indicator.gif -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/awt/Audo.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2014 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2014年7月7日 9 | */ 10 | 11 | $import("js.awt.Component"); 12 | 13 | Class.forName({ 14 | name: "class js.awt.Audo extends js.awt.Component", 15 | "public Audo": function() { 16 | 17 | } 18 | }); 19 | 20 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/awt/Button.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2014 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2014年7月7日 9 | */ 10 | 11 | $import("js.awt.Component"); 12 | 13 | Class.forName({ 14 | name: "class js.awt.Button extends js.awt.Component", 15 | "public Button": function() { 16 | 17 | } 18 | }); 19 | 20 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/awt/Canvas.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2014 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2014年7月7日 9 | */ 10 | 11 | $import("js.awt.Component"); 12 | 13 | Class.forName({ 14 | name: "class js.awt.Canvas extends js.awt.Component", 15 | "public Canvas": function() { 16 | 17 | } 18 | }); 19 | 20 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/awt/Choice.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2014 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2014年7月7日 9 | */ 10 | 11 | $import("js.awt.Component"); 12 | 13 | Class.forName({ 14 | name: "class js.awt.Choice extends js.awt.Component", 15 | "public Choice": function() { 16 | 17 | } 18 | }); 19 | 20 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/awt/Color.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2014 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2014年7月7日 9 | */ 10 | 11 | $import("js.awt.Component"); 12 | 13 | Class.forName({ 14 | name: "class js.awt.Audo extends js.awt.Component", 15 | "public Audo": function() { 16 | 17 | } 18 | }); 19 | 20 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/awt/Container.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2014 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2014年7月7日 9 | */ 10 | 11 | $import("js.awt.Component"); 12 | 13 | Class.forName({ 14 | name: "class js.awt.Container extends js.awt.Component", 15 | "public Container": function() { 16 | 17 | } 18 | }); 19 | 20 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/awt/Date.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2014 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2014年7月7日 9 | */ 10 | 11 | $import("js.awt.Component"); 12 | 13 | Class.forName({ 14 | name: "class js.awt.Date extends js.awt.Component", 15 | "public Date": function() { 16 | 17 | } 18 | }); 19 | 20 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/awt/Dialog.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2014 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2014年7月7日 9 | */ 10 | 11 | $import("js.awt.Container"); 12 | 13 | Class.forName({ 14 | name: "class js.awt.Window extends js.awt.Container", 15 | "public Window": function() { 16 | 17 | } 18 | }); 19 | 20 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/awt/Field.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2014 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2014年7月7日 9 | */ 10 | 11 | $import("js.awt.Component"); 12 | 13 | Class.forName({ 14 | name: "abstract class js.awt.Field extends js.awt.Component", 15 | "public Field": function() { 16 | 17 | } 18 | }); 19 | 20 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/awt/Frame.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2014 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2014年7月7日 9 | */ 10 | 11 | $import("js.awt.Component"); 12 | 13 | Class.forName({ 14 | name: "class js.awt.Menu extends js.awt.Component", 15 | "public Menu": function() { 16 | 17 | } 18 | }); 19 | 20 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/awt/GridPanel.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2014 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2014年7月7日 9 | */ 10 | 11 | $import("js.awt.Panel"); 12 | 13 | Class.forName({ 14 | name: "class js.awt.TabPanel extends js.awt.Panel", 15 | "public TabPanel": function() { 16 | 17 | } 18 | }); 19 | 20 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/awt/Hidden.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2014 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2014年7月7日 9 | */ 10 | 11 | $import("js.awt.Component"); 12 | 13 | Class.forName({ 14 | name: "class js.awt.Hidden extends js.awt.Component", 15 | "public Hidden": function() { 16 | 17 | } 18 | }); 19 | 20 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/awt/Image.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2014 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2014年7月7日 9 | */ 10 | 11 | $import("js.awt.Component"); 12 | 13 | Class.forName({ 14 | name: "class js.awt.Image extends js.awt.Component", 15 | "public Image": function() { 16 | 17 | } 18 | }); 19 | 20 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/awt/Label.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2014 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2014年7月7日 9 | */ 10 | 11 | $import("js.awt.Component"); 12 | 13 | Class.forName({ 14 | name: "class js.awt.Label extends js.awt.Component", 15 | "public Label": function() { 16 | 17 | } 18 | }); 19 | 20 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/awt/List.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2014 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2014年7月7日 9 | */ 10 | 11 | $import("js.awt.Component"); 12 | 13 | Class.forName({ 14 | name: "class js.awt.List extends js.awt.Component", 15 | "public List": function() { 16 | 17 | } 18 | }); 19 | 20 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/awt/Menu.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2014 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2014年7月7日 9 | */ 10 | 11 | $import("js.awt.Component"); 12 | 13 | Class.forName({ 14 | name: "class js.awt.Frame extends js.awt.Component", 15 | "public Frame": function() { 16 | 17 | } 18 | }); 19 | 20 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/awt/Panel.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2014 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2014年7月7日 9 | */ 10 | 11 | $import("js.awt.Container"); 12 | 13 | Class.forName({ 14 | name: "class js.awt.Panel extends js.awt.Container", 15 | "public Panel": function() { 16 | 17 | } 18 | }); 19 | 20 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/awt/ProgressBar.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2014 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2014年7月7日 9 | */ 10 | 11 | $import("js.awt.Component"); 12 | 13 | Class.forName({ 14 | name: "class js.awt.ProgressBar extends js.awt.Component", 15 | "public ProgressBar": function() { 16 | 17 | } 18 | }); 19 | 20 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/awt/Radio.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2014 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2014年7月7日 9 | */ 10 | 11 | $import("js.awt.Component"); 12 | 13 | Class.forName({ 14 | name: "class js.awt.Radio extends js.awt.Component", 15 | "public Radio": function() { 16 | 17 | } 18 | }); 19 | 20 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/awt/Spinner.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2014 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2014年7月7日 9 | */ 10 | 11 | $import("js.awt.Component"); 12 | 13 | Class.forName({ 14 | name: "class js.awt.Spinner extends js.awt.Component", 15 | "public Spinner": function() { 16 | 17 | } 18 | }); 19 | 20 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/awt/TabPanel.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2014 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2014年7月7日 9 | */ 10 | 11 | $import("js.awt.Panel"); 12 | 13 | Class.forName({ 14 | name: "class js.awt.GridPanel extends js.awt.Panel", 15 | "public GridPanel": function() { 16 | 17 | } 18 | }); 19 | 20 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/awt/Text.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2014 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2014年7月7日 9 | */ 10 | 11 | $import("js.awt.Component"); 12 | 13 | Class.forName({ 14 | name: "class js.awt.Text extends js.awt.Component", 15 | "public Text": function() { 16 | 17 | } 18 | }); 19 | 20 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/awt/TextArea.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2014 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2014年7月7日 9 | */ 10 | 11 | $import("js.awt.Text"); 12 | 13 | Class.forName({ 14 | name: "class js.awt.TextArea extends js.awt.Text", 15 | "public TextArea": function() { 16 | 17 | } 18 | }); 19 | 20 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/awt/TextField.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2014 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2014年7月7日 9 | */ 10 | 11 | $import("js.awt.Text"); 12 | 13 | Class.forName({ 14 | name: "class js.awt.TextField extends js.awt.Text", 15 | "public TextField": function() { 16 | 17 | } 18 | }); 19 | 20 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/awt/Time.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2014 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2014年7月7日 9 | */ 10 | 11 | $import("js.awt.Component"); 12 | 13 | Class.forName({ 14 | name: "class js.awt.Time extends js.awt.Component", 15 | "public Time": function() { 16 | 17 | } 18 | }); 19 | 20 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/awt/Tree.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2014 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2014年7月7日 9 | */ 10 | 11 | $import("js.awt.Component"); 12 | 13 | Class.forName({ 14 | name: "class js.awt.Tree extends js.awt.Component", 15 | "public Tree": function() { 16 | 17 | } 18 | }); 19 | 20 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/awt/TreePanel.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2014 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2014年7月7日 9 | */ 10 | 11 | $import("js.awt.Panel"); 12 | 13 | Class.forName({ 14 | name: "class js.awt.TreePanel extends js.awt.Panel", 15 | "public TreePanel": function() { 16 | 17 | } 18 | }); 19 | 20 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/awt/Video.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2014 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2014年7月7日 9 | */ 10 | 11 | $import("js.awt.Component"); 12 | 13 | Class.forName({ 14 | name: "class js.awt.Video extends js.awt.Component", 15 | "public Video": function() { 16 | 17 | } 18 | }); 19 | 20 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/awt/Window.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2014 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2014年7月7日 9 | */ 10 | 11 | $import("js.awt.Window"); 12 | 13 | Class.forName({ 14 | name: "class js.awt.Dialog extends js.awt.Window", 15 | "public Dialog": function() { 16 | 17 | } 18 | }); 19 | 20 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/io/PrintWriter.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ! JSRT JavaScript Library 0.1.1 lico.atom@gmail.com 3 | * 4 | * Copyright 2008, 2014 Atom Union, Inc. Released under the MIT license 5 | * 6 | * Date: Feb 14, 2014 7 | */ 8 | $import("js.io.Writer", "BootstrapClassLoader"); 9 | Class.forName({ 10 | name: "class js.io.PrintWriter extends js.io.Writer", 11 | PrintWriter: function() {}, 12 | print: function(cbuf, off, len, ln) {}, 13 | println: function(cbuf, off, len) { 14 | this.print(cbuf, off, len, true); 15 | } 16 | }); 17 | 18 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/io/Writer.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ! JSRT JavaScript Library 0.1.1 lico.atom@gmail.com 3 | * 4 | * Copyright 2008, 2014 Atom Union, Inc. Released under the MIT license 5 | * 6 | * Date: Feb 14, 2014 7 | */ 8 | 9 | Class.forName({ 10 | name: "abstract class js.io.Writer extends Object", 11 | "protected _writer": null, 12 | Writer: function(writer) { 13 | this._writer = writer; 14 | }, 15 | 16 | /** 将指定字符追加到此 writer。 */ 17 | append: function(c) { 18 | return this; 19 | }, 20 | /** 写入字符数组,字符,字符串或某一部分 */ 21 | write: function(cbuf, off, len) {} 22 | }); 23 | 24 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/lang/Boolean.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2014 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2014年6月25日 9 | */ 10 | Class.forName({ 11 | name: "class Boolean", 12 | alias: "js.lang.Boolean", 13 | Boolean: function() {}, 14 | "public equals": function(s) { 15 | return Object.isBoolean(s) && this == s; 16 | } 17 | }); 18 | 19 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/lang/ClassLoader.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ! JSRT JavaScript Library 0.1.1 lico.atom@gmail.com 3 | * 4 | * Copyright 2008, 2014 Atom Union, Inc. Released under the MIT license 5 | * 6 | * Date: Feb 17, 2014 7 | */ 8 | 9 | Class.forName({ 10 | name: "abstract class js.lang.ClassLoader extends Object", 11 | 12 | '@Setter @Getter private parent': null, 13 | 14 | '@Setter @Getter private classes': [], 15 | 16 | "abstract loadClass": function(scriptUrl, callback, scope, showBusy) {}, 17 | 'static getSystemClassLoader': function(scriptUrl) { 18 | return atom.misc.Launcher.getLauncher().getClassLoader(); 19 | } 20 | }); 21 | 22 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/lang/ClassNotFoundException.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ! JSRT JavaScript Library 0.1.1 lico.atom@gmail.com 3 | * 4 | * Copyright 2008, 2014 Atom Union, Inc. Released under the MIT license 5 | * 6 | * Date: Feb 19, 2014 7 | */ 8 | Class.forName({ 9 | name: "class js.lang.ClassNotFoundException extends js.lang.Exception", 10 | "private name": "js.lang.ClassNotFoundException", // 错误名 11 | "private number": 100 12 | // 错误号 13 | }); 14 | 15 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/lang/CloneNotSupportedException.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2014 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2014年10月13日 9 | */ 10 | 11 | /** 12 | * Thrown to indicate that the clone method in class 13 | * Object has been called to clone an object, but that 14 | * the object's class does not implement the Cloneable 15 | * interface. 16 | *

17 | * Applications that override the clone method can also 18 | * throw this exception to indicate that an object could not or 19 | * should not be cloned. 20 | * 21 | * @author unascribed 22 | * @see java.lang.Cloneable 23 | * @see java.lang.Object#clone() 24 | * @since JDK1.0 25 | */ 26 | $import("js.lang.Exception", "BootstrapClassLoader"); 27 | Class.forName({ 28 | name: "class js.lang.CloneNotSupportedException extends js.lang.Exception", 29 | "private name": "js.lang.CloneNotSupportedException", // 错误名 30 | "private number": 109 31 | // 错误号 32 | 33 | }); 34 | 35 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/lang/Error.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2014 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2014年6月25日 9 | */ 10 | Class.forName({ 11 | name: "class Error", 12 | alias: "js.lang.Error", 13 | 14 | "private name": "js.lang.Error", // 错误名 15 | "private number": 1, 16 | 17 | Error: function(message, fileName, lineNumber, stack) { 18 | this.message = message; 19 | this.fileName = fileName; 20 | this.stack = stack; 21 | this.lineNumber = lineNumber; 22 | }, 23 | 'static init': function() { 24 | var methods = {}, 25 | __methods = js.lang.Throwable.$class.getMethods(), 26 | __length = __methods.length, 27 | __index = 0; 28 | for (; __index < __length; __index++) { 29 | methods[__methods[__index]._name] = __methods[__index]._value; 30 | } 31 | Object.extend(Error.prototype, methods); 32 | } 33 | }); 34 | 35 | js.lang.Error.init(); 36 | 37 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/lang/EvalError.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2014 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2014年6月25日 9 | */ 10 | 11 | $import("js.lang.Throwable", "BootstrapClassLoader"); 12 | Class.forName({ 13 | name: "class EvalError", 14 | alias: "js.lang.EvalError", 15 | 16 | "private name": "js.lang.EvalError", // 错误名 17 | "private number": 2, 18 | 19 | EvalError: function() {} 20 | }); 21 | 22 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/lang/Exception.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ! JSRT JavaScript Library 0.1.1 lico.atom@gmail.com 3 | * 4 | * Copyright 2008, 2014 Atom Union, Inc. Released under the MIT license 5 | * 6 | * Date: Feb 12, 2014 7 | */ 8 | Class.forName({ 9 | name: "class js.lang.Exception extends js.lang.Throwable", 10 | 11 | "private name": "js.lang.Exception", // 错误名 12 | "private number": 0, // 错误号 13 | 14 | Exception: function(message, fileName, lineNumber, stack) { 15 | this.message = message; 16 | this.fileName = fileName; 17 | this.stack = stack; 18 | this.lineNumber = lineNumber; 19 | } 20 | 21 | }); 22 | 23 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/lang/Function.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2014 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2014年6月25日 9 | */ 10 | 11 | Class.forName({ 12 | name: "class Function", 13 | alias: "js.lang.Function", 14 | Function: function() {} 15 | }); 16 | 17 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/lang/IllegalAccessException.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ! JSRT JavaScript Library 0.1.1 lico.atom@gmail.com 3 | * 4 | * Copyright 2008, 2014 Atom Union, Inc. Released under the MIT license 5 | * 6 | * Date: Feb 12, 2014 7 | */ 8 | $import("js.lang.Exception", "BootstrapClassLoader"); 9 | Class.forName({ 10 | name: "class js.lang.IllegalAccessException extends js.lang.Exception", 11 | "private name": "js.lang.IllegalAccessException", // 错误名 12 | "private number": 101 13 | // 错误号 14 | }); 15 | 16 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/lang/IllegalArgumentException.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ! JSRT JavaScript Library 0.1.1 lico.atom@gmail.com 3 | * 4 | * Copyright 2008, 2014 Atom Union, Inc. Released under the MIT license 5 | * 6 | * Date: Feb 12, 2014 7 | */ 8 | $import("js.lang.Exception", "BootstrapClassLoader"); 9 | Class.forName({ 10 | name: "class js.lang.IllegalArgumentException extends js.lang.Exception", 11 | "private name": "js.lang.IllegalArgumentException", // 错误名 12 | "private number": 102 13 | // 错误号 14 | }); 15 | 16 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/lang/IllegalStateException.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ! JSRT JavaScript Library 0.1.1 lico.atom@gmail.com 3 | * 4 | * Copyright 2008, 2014 Atom Union, Inc. Released under the MIT license 5 | * 6 | * Date: Feb 12, 2014 7 | */ 8 | $import("js.lang.Exception", "BootstrapClassLoader"); 9 | Class.forName({ 10 | name: "class js.lang.IllegalStateException extends js.lang.Exception", 11 | "private name": "js.lang.IllegalStateException", // 错误名 12 | "private number": 103 13 | // 错误号 14 | }); 15 | 16 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/lang/IndexOutOfBoundsException.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ! JSRT JavaScript Library 0.1.1 lico.atom@gmail.com 3 | * 4 | * Copyright 2008, 2014 Atom Union, Inc. Released under the MIT license 5 | * 6 | * Date: Feb 12, 2014 7 | */ 8 | $import("js.lang.Exception", "BootstrapClassLoader"); 9 | Class.forName({ 10 | name: "class js.lang.IndexOutOfBoundsException extends js.lang.Exception", 11 | "private name": "js.lang.IndexOutOfBoundsException", // 错误名 12 | "private number": 104 13 | // 错误号 14 | }); 15 | 16 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/lang/InternalError.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2015 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2015年2月10日 9 | */ 10 | Class.forName({ 11 | name: "class js.lang.InternalError extends js.lang.Error", 12 | 13 | "private name": "js.lang.InternalError", // 错误名 14 | "private number": 99, 15 | 16 | 17 | }); 18 | 19 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/lang/NoSuchFieldException.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ! JSRT JavaScript Library 0.1.1 lico.atom@gmail.com 3 | * 4 | * Copyright 2008, 2014 Atom Union, Inc. Released under the MIT license 5 | * 6 | * Date: Feb 12, 2014 7 | */ 8 | Class.forName({ 9 | name: "class js.lang.NoSuchFieldException extends js.lang.Exception", 10 | "private name": "js.lang.NoSuchFieldException", 11 | "private number": 105 12 | }); 13 | 14 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/lang/NoSuchMethodException.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ! JSRT JavaScript Library 0.1.1 lico.atom@gmail.com 3 | * 4 | * Copyright 2008, 2014 Atom Union, Inc. Released under the MIT license 5 | * 6 | * Date: Feb 12, 2014 7 | */ 8 | Class.forName({ 9 | name: "class js.lang.NoSuchMethodException extends js.lang.Exception", 10 | "private name": "js.lang.NoSuchMethodException", 11 | "private number": 106 12 | }); 13 | 14 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/lang/NullPointerException.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ! JSRT JavaScript Library 0.1.1 lico.atom@gmail.com 3 | * 4 | * Copyright 2008, 2014 Atom Union, Inc. Released under the MIT license 5 | * 6 | * Date: Feb 12, 2014 7 | */ 8 | $import("js.lang.Exception", "BootstrapClassLoader"); 9 | Class.forName({ 10 | name: "class js.lang.NullPointerException extends js.lang.Exception", 11 | "private name": "js.lang.NullPointerException", 12 | "private number": 107 13 | }); 14 | 15 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/lang/Number.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2014 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2014年6月25日 9 | */ 10 | 11 | Class.forName({ 12 | name: "class Number", 13 | 14 | alias: "js.lang.Number", 15 | Number: function() {}, 16 | "public equals": function(s) { 17 | return Object.isNumber(s) && this == s; 18 | } 19 | 20 | }); 21 | 22 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/lang/RangeError.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2014 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2014年6月25日 9 | */ 10 | 11 | $import("js.lang.Throwable", "BootstrapClassLoader"); 12 | Class.forName({ 13 | name: "class RangeError", 14 | alias: "js.lang.RangeError", 15 | 16 | "private name": "js.lang.RangeError", // 错误名 17 | "private number": 3, 18 | 19 | RangeError: function() {} 20 | }); 21 | 22 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/lang/ReferenceError.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2014 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2014年6月25日 9 | */ 10 | $import("js.lang.Throwable", "BootstrapClassLoader"); 11 | Class.forName({ 12 | name: "class ReferenceError", 13 | alias: "js.lang.ReferenceError", 14 | 15 | "private name": "js.lang.ReferenceError", // 错误名 16 | "private number": 4, 17 | 18 | ReferenceError: function() {} 19 | }); 20 | 21 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/lang/RegExp.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2014 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2014年6月25日 9 | */ 10 | 11 | Class.forName({ 12 | name: "class RegExp", 13 | alias: "js.lang.RegExp", 14 | RegExp: function() {} 15 | }); 16 | 17 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/lang/String.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ! JSRT JavaScript Library 0.1.1 lico.atom@gmail.com 3 | * 4 | * Copyright 2008, 2014 Atom Union, Inc. Released under the MIT license 5 | * 6 | * Date: Feb 10, 2014 7 | */ 8 | 9 | Class.forName({ 10 | name: "class String", 11 | alias: "js.lang.String", 12 | String: function() {}, 13 | "public trim": function() { 14 | var re = /^\s+|\s+$/g; 15 | return function() { 16 | return this.replace(re, ""); 17 | }; 18 | }(), 19 | "public equals": function(s) { 20 | return Object.isString(s) && this == s; 21 | }, 22 | getLength: function() { 23 | return this.length; 24 | } 25 | 26 | }); 27 | 28 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/lang/SyntaxError.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2014 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2014年6月25日 9 | */ 10 | $import("js.lang.Throwable", "BootstrapClassLoader"); 11 | Class.forName({ 12 | name: "class SyntaxError", 13 | alias: "js.lang.SyntaxError", 14 | 15 | "private name": "js.lang.SyntaxError", // 错误名 16 | "private number": 5, 17 | 18 | SyntaxError: function() {} 19 | }); 20 | 21 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/lang/TypeError.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2014 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2014年6月25日 9 | */ 10 | $import("js.lang.Throwable", "BootstrapClassLoader"); 11 | Class.forName({ 12 | name: "class TypeError", 13 | alias: "js.lang.TypeError", 14 | 15 | "private name": "js.lang.TypeError", // 错误名 16 | "private number": 6, 17 | 18 | TypeError: function() {} 19 | }); 20 | 21 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/lang/URIError.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2014 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2014年6月25日 9 | */ 10 | $import("js.lang.Throwable", "BootstrapClassLoader"); 11 | 12 | Class.forName({ 13 | name: "class URIError", 14 | alias: "js.lang.URIError", 15 | 16 | "private name": "js.lang.URIError", // 错误名 17 | "private number": 7, 18 | 19 | URIError: function() {} 20 | }); 21 | 22 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/lang/UnsupportedOperationException.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ! JSRT JavaScript Library 0.1.1 lico.atom@gmail.com 3 | * 4 | * Copyright 2008, 2014 Atom Union, Inc. Released under the MIT license 5 | * 6 | * Date: Feb 12, 2014 7 | */ 8 | $import("js.lang.Exception", "BootstrapClassLoader"); 9 | Class 10 | .forName({ 11 | name: "class js.lang.UnsupportedOperationException extends js.lang.Exception", 12 | "private name": "js.lang.UnsupportedOperationException", // 错误名 13 | "private number": 108 14 | // 错误号 15 | }); 16 | 17 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/lang/reflect/Constructor.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ! JSRT JavaScript Library 0.1.1 lico.atom@gmail.com 3 | * 4 | * Copyright 2008, 2014 Atom Union, Inc. Released under the MIT license 5 | * 6 | * Date: Feb 14, 2014 7 | */ 8 | 9 | Class.forName({ 10 | name: "abstract class js.lang.reflect.Constructor extends Object" 11 | }); 12 | 13 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/lang/reflect/Field.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ! JSRT JavaScript Library 0.1.1 lico.atom@gmail.com 3 | * 4 | * Copyright 2008, 2014 Atom Union, Inc. Released under the MIT license 5 | * 6 | * Date: Feb 14, 2014 7 | */ 8 | 9 | Class.forName({ 10 | name: "public final class js.lang.reflect.Field extends Object", 11 | "@Setter @Getter private _declaringClass": null, 12 | "@Setter @Getter private _name": null, 13 | "@Setter @Getter private _modifiers": null, 14 | "@Setter @Getter private _annotations": null, 15 | "@Setter @Getter private _value": null, 16 | 17 | Field: function(name, value, declaringClass, modifiers, annotations) { 18 | this._name = name; 19 | this._declaringClass = declaringClass; 20 | this._modifiers = modifiers; 21 | this._annotations = annotations; 22 | this._value = value; 23 | 24 | }, 25 | clone: function() { 26 | return this; 27 | }, 28 | "set": function(obj, value) { 29 | obj[this._name] = value; 30 | }, 31 | "get": function(obj) { 32 | return obj[this._name]; 33 | } 34 | }); 35 | js.lang.reflect.Field.loaded = true; 36 | 37 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/lang/reflect/InvocationTargetException.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ! JSRT JavaScript Library 0.1.1 lico.atom@gmail.com 3 | * 4 | * Copyright 2008, 2014 Atom Union, Inc. Released under the MIT license 5 | * 6 | * Date: Feb 14, 2014 7 | */ 8 | $import("js.lang.Exception", "BootstrapClassLoader"); 9 | Class 10 | .forName({ 11 | name: "class js.lang.reflect.InvocationTargetException extends js.lang.Exception", 12 | "private name": "InvocationTargetException", // 错误名 13 | "private number": 100 14 | // 错误号 15 | }); 16 | 17 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/net/Http.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ! JSRT JavaScript Library 0.1.1 lico.atom@gmail.com 3 | * 4 | * Copyright 2008, 2014 Atom Union, Inc. Released under the MIT license 5 | * 6 | * Date: Feb 14, 2014 7 | */ 8 | 9 | Class.forName({ 10 | name: "class js.net.http.Http extends Object", 11 | "public static REQUEST": { 12 | TYPE: ["GET", "HEAD", "PUT", "DELETE", "POST", "OPTIONS"] 13 | }, 14 | Http: function() {} 15 | }); 16 | 17 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/net/HttpURLConnection.js: -------------------------------------------------------------------------------- 1 | $import("js.net.URLConnection"); 2 | 3 | Class.forName({ 4 | name: "class js.net.HttpURLConnection extends js.net.URLConnection", 5 | 6 | "public static getConnection": function() { 7 | var xhr = null; 8 | 9 | if (typeof XMLHttpRequest != 'undefined') { 10 | xhr = new XMLHttpRequest(); 11 | } else { 12 | xhr = new ActiveXObject('Microsoft.XMLHTTP'); 13 | } 14 | return xhr; 15 | } 16 | }); 17 | 18 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/net/Rest.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ! JSRT JavaScript Library 0.1.1 lico.atom@gmail.com 3 | * 4 | * Copyright 2008, 2014 Atom Union, Inc. Released under the MIT license 5 | * 6 | * Date: Feb 14, 2014 7 | */ 8 | 9 | Class.forName({ 10 | name: "class js.net.http.Rest extends Object", 11 | Rest: function() {}, 12 | build: (function() { 13 | var regx1 = /\/{2,}/g, 14 | regx2 = /\/$/g; 15 | return function() { 16 | if (arguments.length > 0) { 17 | if (!Object.isEmpty(arguments[0]) && Object.isString(arguments[0])) { 18 | var _method = arguments[0].toUpperCase(); 19 | if (com.js.net.http.HTTP.REQUEST.TYPE.contains(_method)) { 20 | var temp = new StringBuffer(); 21 | var url = temp.append("").applys( 22 | Array.prototype.slice.call(arguments, 1)) 23 | .toString("/"); 24 | temp.clear(); 25 | temp.append( 26 | url.trim().replace(regx1, "/").replace(regx2, 27 | "")).append("?_method=") 28 | .append(_method); 29 | return temp.toString(); 30 | } 31 | } 32 | } 33 | return null; 34 | }; 35 | })() 36 | }); 37 | 38 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/net/URLConnection.js: -------------------------------------------------------------------------------- 1 | Class.forName({ 2 | name: "class js.net.URLConnection extends Object", 3 | 4 | }); 5 | 6 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/test/AssertionError.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * JSRT JavaScript Library 0.2.1 3 | * lico.atom@gmail.com 4 | * 5 | * Copyright 2008, 2014 Atom Union, Inc. 6 | * Released under the MIT license 7 | * 8 | * Date: 2014年6月25日 9 | */ 10 | 11 | 12 | $import("js.lang.Error", "BootstrapClassLoader"); 13 | Class.forName({ 14 | name: "class js.test.AssertionError extends js.lang.Error", 15 | "private name": "js.test.AssertionError", // 错误名 16 | "private number": -1 17 | 18 | 19 | }); 20 | 21 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/text/Format.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ! JSRT JavaScript Library 0.1.1 lico.atom@gmail.com 3 | * 4 | * Copyright 2008, 2014 Atom Union, Inc. Released under the MIT license 5 | * 6 | * Date: Feb 16, 2014 7 | */ 8 | 9 | Class.forName({ 10 | name: "abstract class js.text.Format extends Object", 11 | Format: function() {}, 12 | 13 | /** 格式化一个对象以生成一个字符串。 */ 14 | 'abstract format': function(obj) {}, 15 | 16 | /** 从给定字符串的开始处分析文本以生成一个对象。 */ 17 | 'abstract parse': function(source) {} 18 | }); 19 | 20 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/util/Entry.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ! JSRT JavaScript Library 0.1.1 lico.atom@gmail.com 3 | * 4 | * Copyright 2008, 2014 Atom Union, Inc. Released under the MIT license 5 | * 6 | * Date: Feb 11, 2014 7 | */ 8 | 9 | Class.forName({ 10 | name: "class js.util.Entry extends Object", 11 | "private _key": null, 12 | "private _value": null, 13 | Entry: function(key, value) { 14 | this._key = key; 15 | this._value = value; 16 | }, 17 | "clone": function() { 18 | var key = this._key ? this._key.clone() : this._key; 19 | var value = this._value ? this._value.clone() : this._value; 20 | return new js.util.Entry(key, value); 21 | }, 22 | getKey: function() { 23 | return this._key; 24 | }, 25 | getValue: function() { 26 | return this._value; 27 | }, 28 | setValue: function(val) { 29 | this._value = _val; 30 | } 31 | }); 32 | 33 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/util/EntrySet.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ! JSRT JavaScript Library 0.1.1 lico.atom@gmail.com 3 | * 4 | * Copyright 2008, 2014 Atom Union, Inc. Released under the MIT license 5 | * 6 | * Date: Feb 11, 2014 7 | */ 8 | 9 | $import("js.util.Set", "BootstrapClassLoader"); 10 | 11 | Class.forName({ 12 | name: "class js.util.EntrySet extends js.util.Set", 13 | "private _element": null, 14 | EntrySet: function(element) { 15 | this._element = element; 16 | }, 17 | iterator: function() { 18 | return new js.util.HashIterator(this._element); 19 | }, 20 | size: function() { 21 | return this._element.size(); 22 | } 23 | }); 24 | 25 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/util/HashSet.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ! JSRT JavaScript Library 0.1.1 lico.atom@gmail.com 3 | * 4 | * Copyright 2008, 2014 Atom Union, Inc. Released under the MIT license 5 | * 6 | * Date: Feb 11, 2014 7 | */ 8 | 9 | $import("js.util.Set", "BootstrapClassLoader"); 10 | $import("js.util.HashMap", "BootstrapClassLoader"); 11 | 12 | Class.forName({ 13 | name: "class js.util.HashSet extends js.util.Set", 14 | 15 | "private _table": null, 16 | HashSet: function() { 17 | this._table = new js.util.HashMap(); 18 | }, 19 | 20 | iterator: function() { 21 | return this._table.keySet().iterator(); 22 | }, 23 | 24 | size: function() { 25 | return this._table.size(); 26 | }, 27 | 28 | isEmpty: function() { 29 | return this._table.isEmpty(); 30 | }, 31 | 32 | contains: function(o) { 33 | return this._table.containsKey(o); 34 | }, 35 | 36 | add: function(e) { 37 | return this._table.put(e, null); 38 | }, 39 | 40 | remove: function(o) { 41 | this._table.remove(o); 42 | return o; 43 | }, 44 | 45 | clear: function() { 46 | this._table.clear(); 47 | } 48 | }); 49 | 50 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/util/Iterator.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ! JSRT JavaScript Library 0.1.1 lico.atom@gmail.com 3 | * 4 | * Copyright 2008, 2014 Atom Union, Inc. Released under the MIT license 5 | * 6 | * Date: Feb 11, 2014 7 | */ 8 | 9 | Class.forName({ 10 | name: "class js.util.Iterator extends Object", 11 | "private _element": null, 12 | "private _cursor": 0, 13 | "private _lastRet": -1, 14 | Iterator: function(element) { 15 | this._element = element || []; 16 | }, 17 | 18 | hasNext: function() { 19 | return this._cursor < this._element.size(); 20 | }, 21 | 22 | next: function() { 23 | try { 24 | var next = this._element.get(this._cursor); 25 | this._lastRet = this._cursor++; 26 | return next; 27 | } catch (e) { 28 | throw new js.lang.IndexOutOfBoundsException("Index: " + this._cursor + ", Size: " + this._element.size() + ",Message:" + e.getMessage()); 29 | } 30 | }, 31 | remove: function() { 32 | if (this._lastRet === -1) 33 | throw new js.lang.IllegalStateException(); 34 | try { 35 | this._element.removeAt(this._lastRet); 36 | if (this._lastRet < this._cursor) 37 | this._cursor--; 38 | this._lastRet = -1; 39 | } catch (e) { 40 | throw new js.lang.IndexOutOfBoundsException(); 41 | } 42 | } 43 | }); 44 | 45 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/util/KeyIterator.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ! JSRT JavaScript Library 0.1.1 lico.atom@gmail.com 3 | * 4 | * Copyright 2008, 2014 Atom Union, Inc. Released under the MIT license 5 | * 6 | * Date: Feb 11, 2014 7 | */ 8 | 9 | $import("js.util.HashIterator", "BootstrapClassLoader"); 10 | 11 | Class 12 | .forName({ 13 | name: "class js.util.KeyIterator extends js.util.HashIterator", 14 | next: function() { 15 | try { 16 | var next = this._element._table[this._element._hashArray[this._cursor]]; 17 | this._lastRet = this._cursor++; 18 | return next.getKey(); 19 | } catch (e) { 20 | throw new js.lang.IndexOutOfBoundsException("Index: " + this._cursor + ", Size: " + this._element.size() + ",Message:" + e.getMessage()); 21 | } 22 | } 23 | }); 24 | 25 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/util/KeySet.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ! JSRT JavaScript Library 0.1.1 lico.atom@gmail.com 3 | * 4 | * Copyright 2008, 2014 Atom Union, Inc. Released under the MIT license 5 | * 6 | * Date: Feb 11, 2014 7 | */ 8 | 9 | $import("js.util.Set", "BootstrapClassLoader"); 10 | $import("js.util.KeyIterator", "BootstrapClassLoader"); 11 | 12 | Class.forName({ 13 | name: "class js.util.KeySet extends js.util.Set", 14 | "private _element": null, 15 | KeySet: function(element) { 16 | this._element = element; 17 | }, 18 | iterator: function() { 19 | return new js.util.KeyIterator(this._element); 20 | }, 21 | size: function() { 22 | return this._element.size(); 23 | } 24 | }); 25 | 26 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/util/LinkIterator.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ! JSRT JavaScript Library 0.1.1 lico.atom@gmail.com 3 | * 4 | * Copyright 2008, 2014 Atom Union, Inc. Released under the MIT license 5 | * 6 | * Date: Feb 11, 2014 7 | */ 8 | 9 | $import("js.util.Iterator", "BootstrapClassLoader"); 10 | 11 | Class.forName({ 12 | name: "class js.util.LinkIterator extends js.util.Iterator", 13 | 14 | LinkIterator: function(element, index) { 15 | this._element = element; 16 | this._cursor = index || 0; 17 | }, 18 | 19 | "hasPrevious": function() { 20 | return this._cursor > 0; 21 | }, 22 | 23 | "previous": function() { 24 | try { 25 | var i = this._cursor - 1, 26 | previous = this._element.get(i); 27 | this._lastRet = this._cursor = i; 28 | return previous; 29 | } catch (e) { 30 | throw new js.lang.IndexOutOfBoundsException(); 31 | } 32 | }, 33 | 34 | "nextIndex": function() { 35 | return this._cursor; 36 | }, 37 | 38 | "previousIndex": function() { 39 | return this._cursor - 1; 40 | } 41 | }); 42 | 43 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/util/NoSuchElementException.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ! JSRT JavaScript Library 0.1.1 lico.atom@gmail.com 3 | * 4 | * Copyright 2008, 2014 Atom Union, Inc. Released under the MIT license 5 | * 6 | * Date: Feb 12, 2014 7 | */ 8 | $import("js.lang.Exception", "BootstrapClassLoader"); 9 | Class.forName({ 10 | name: "class js.util.NoSuchElementException extends js.lang.Exception", 11 | "private name": "js.util.NoSuchElementException", // 错误名 12 | "private number": 801 13 | // 错误号 14 | }); 15 | 16 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/util/Set.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ! JSRT JavaScript Library 0.1.1 lico.atom@gmail.com 3 | * 4 | * Copyright 2008, 2014 Atom Union, Inc. Released under the MIT license 5 | * 6 | * Date: Feb 11, 2014 7 | */ 8 | 9 | $import("js.util.Collection", "BootstrapClassLoader"); 10 | 11 | Class.forName({ 12 | name: "class js.util.Set extends js.util.Collection" 13 | 14 | }); 15 | 16 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/util/TreeMap.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ! JSRT JavaScript Library 0.1.1 lico.atom@gmail.com 3 | * 4 | * Copyright 2008, 2014 Atom Union, Inc. Released under the MIT license 5 | * 6 | * Date: Feb 11, 2014 7 | */ 8 | 9 | $import("js.util.Map", "BootstrapClassLoader"); 10 | 11 | Class.forName({ 12 | name: "class js.util.TreeMap extends js.util.Map" 13 | }); 14 | 15 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/util/TreeSet.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ! JSRT JavaScript Library 0.1.1 lico.atom@gmail.com 3 | * 4 | * Copyright 2008, 2014 Atom Union, Inc. Released under the MIT license 5 | * 6 | * Date: Feb 11, 2014 7 | */ 8 | 9 | $import("js.util.Set", "BootstrapClassLoader"); 10 | 11 | Class.forName({ 12 | name: "class js.util.TreeSet extends js.util.Set" 13 | 14 | }); 15 | 16 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/util/ValueIterator.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ! JSRT JavaScript Library 0.1.1 lico.atom@gmail.com 3 | * 4 | * Copyright 2008, 2014 Atom Union, Inc. Released under the MIT license 5 | * 6 | * Date: Feb 11, 2014 7 | */ 8 | 9 | $import("js.util.HashIterator", "BootstrapClassLoader"); 10 | 11 | Class 12 | .forName({ 13 | name: "class js.util.ValueIterator extends js.util.HashIterator", 14 | next: function() { 15 | try { 16 | var next = this._element._table[this._element._hashArray[this._cursor]]; 17 | this._lastRet = this._cursor++; 18 | return next.getValue(); 19 | } catch (e) { 20 | throw new js.lang.IndexOutOfBoundsException("Index: " + this._cursor + ", Size: " + this._element.size() + ",Message:" + e.getMessage()); 21 | } 22 | } 23 | }); 24 | 25 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/main/js/js/util/ValueList.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ! JSRT JavaScript Library 0.1.1 lico.atom@gmail.com 3 | * 4 | * Copyright 2008, 2014 Atom Union, Inc. Released under the MIT license 5 | * 6 | * Date: Feb 11, 2014 7 | */ 8 | 9 | $import("js.util.List", "BootstrapClassLoader"); 10 | $import("js.util.ValueIterator", "BootstrapClassLoader"); 11 | 12 | Class.forName({ 13 | name: "class js.util.ValueList extends js.util.List", 14 | 15 | "private _element": null, 16 | ValueList: function(element) { 17 | this._element = element; 18 | }, 19 | iterator: function() { 20 | return new js.util.ValueIterator(this._element); 21 | }, 22 | size: function() { 23 | return this._element.size(); 24 | }, 25 | 26 | "removeAt": function(index) { 27 | this.rangeCheck(); 28 | return this._element._table.splice(index, 1); 29 | }, 30 | 31 | "get": function(index) { 32 | this.rangeCheck(); 33 | return this._element._table[index]; 34 | }, 35 | 36 | "subList": function(fromIndex, toIndex) { 37 | return this._element._table.slice(fromIndex, toIndex); 38 | }, 39 | 40 | "set": function(index, element) { 41 | this.rangeCheck(index); 42 | var oldValue = this._element._table[index]; 43 | this._element._table[index] = element; 44 | return oldValue; 45 | } 46 | 47 | }); 48 | 49 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/test/html/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | JSRT JAVASCRIPT LIBRARY 0.1.1-SNAPSHORT 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/test/js/js/model/Animal.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * 4 | */ 5 | 6 | var animalClass = Class.forName({ 7 | name: "class js.model.Animal extends Object", 8 | "@Getter @Setter private age": 0, 9 | "private name": 0, 10 | Animal: function(name) { 11 | this.name = name; 12 | }, 13 | setName: function(name) { 14 | this.name = name; 15 | }, 16 | getName: function() { 17 | return this.name; 18 | }, 19 | say: function() { 20 | return "i am a animal"; 21 | } 22 | }); 23 | 24 | -------------------------------------------------------------------------------- /tars/surface/static/jre/src/test/js/js/model/Dog.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * 4 | */ 5 | 6 | $import("js.model.Animal"); 7 | var dogClass = Class.forName({ 8 | name: "public class js.model.Dog extends js.model.Animal", 9 | "@Getter @Setter private color": "black", 10 | "@Getter @Setter private word": "", 11 | "public Dog": function(name, word) { 12 | this.word = word; 13 | }, 14 | say: function() { 15 | return this.word; 16 | } 17 | }); 18 | 19 | -------------------------------------------------------------------------------- /tars/surface/static/logo.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/logo.ico -------------------------------------------------------------------------------- /tars/surface/static/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tars", 3 | "description": "tars surface", 4 | "private": true, 5 | "dependencies": {}, 6 | "devDependencies": { 7 | "bower": "^1.4.1", 8 | "gulp": "^3.8.11", 9 | "less": "^2.5.1", 10 | "del": "^1.1.1", 11 | "gulp-bower": "0.0.10", 12 | "gulp-bower-normalize": "^1.0.6", 13 | "gulp-concat": "^2.5.2", 14 | "gulp-jsbeautifier": "0.0.8", 15 | "gulp-jshint": "^1.10.0", 16 | "gulp-json-editor": "^2.2.1", 17 | "gulp-less": "^3.0.3", 18 | "gulp-livereload": "^3.8.0", 19 | "gulp-minify-css": "^1.1.1", 20 | "gulp-minify-html": "^1.0.2", 21 | "gulp-rename": "^1.2.2", 22 | "gulp-uglify": "^1.2.0", 23 | "gulp-util": "^3.0.6", 24 | "config-file": "^0.3.1", 25 | "main-bower-files": "^2.7.0" 26 | }, 27 | "engines": { 28 | "node": "^0.12.2", 29 | "npm": "^2.7.4" 30 | }, 31 | "group": "com.ctrip", 32 | "artifact": "tars", 33 | "authors": [ 34 | "lico" 35 | ], 36 | "license": "MIT", 37 | "debug": true, 38 | "skin": "default", 39 | "version": "1.2.32", 40 | "target": "local" 41 | } -------------------------------------------------------------------------------- /tars/surface/static/pom.json: -------------------------------------------------------------------------------- 1 | { 2 | "group": "com.ctrip", 3 | "artifact": "tars", 4 | "name": "tars", 5 | "description": "tars surface", 6 | "authors": [ 7 | "lico" 8 | ], 9 | "license": "MIT", 10 | "private": true, 11 | "debug": true, 12 | "skin": "default", 13 | "version": "1.2.32", 14 | "target": "local" 15 | } -------------------------------------------------------------------------------- /tars/surface/static/rest_framework/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/rest_framework/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /tars/surface/static/rest_framework/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/rest_framework/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /tars/surface/static/rest_framework/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/rest_framework/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /tars/surface/static/rest_framework/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/rest_framework/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /tars/surface/static/rest_framework/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/rest_framework/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /tars/surface/static/rest_framework/img/grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/rest_framework/img/grid.png -------------------------------------------------------------------------------- /tars/surface/static/rest_framework_swagger/images/logo_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/rest_framework_swagger/images/logo_small.png -------------------------------------------------------------------------------- /tars/surface/static/rest_framework_swagger/images/pet_store_api.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/rest_framework_swagger/images/pet_store_api.png -------------------------------------------------------------------------------- /tars/surface/static/rest_framework_swagger/images/throbber.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/rest_framework_swagger/images/throbber.gif -------------------------------------------------------------------------------- /tars/surface/static/rest_framework_swagger/images/wordnik_api.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/rest_framework_swagger/images/wordnik_api.png -------------------------------------------------------------------------------- /tars/surface/static/src/main/css/animate.css: -------------------------------------------------------------------------------- 1 | @charset 'utf-8'; 2 | .animate.ng-hide-add { 3 | -webkit-transition: all linear 0s; 4 | transition: all linear 0s; 5 | opacity: 1; 6 | } 7 | .animate.ng-hide-remove { 8 | -webkit-transition: all linear 0s; 9 | transition: all linear 0s; 10 | } 11 | .animate.ng-hide-remove.ng-hide-add { 12 | opacity: 0; 13 | } 14 | .animate.ng-hide-add-active { 15 | -webkit-transition: 0.5s linear 0s; 16 | transition: 0.5s linear 0s; 17 | opacity: 0; 18 | } 19 | .animate.ng-hide-remove-active { 20 | -webkit-transition: 0.5s linear 0s; 21 | transition: 0.5s linear 0s; 22 | } 23 | .animate.ng-hide-remove-active.ng-hide-add-active { 24 | opacity: 1; 25 | } 26 | .animate.fast.ng-hide-add-active, 27 | .animate.fast.ng-hide-remove-active { 28 | -webkit-transition: 1s linear 0s; 29 | transition: 1s linear 0s; 30 | } 31 | .animate.height { 32 | overflow: hidden; 33 | } 34 | .animate.height.ng-hide-add { 35 | height: auto; 36 | } 37 | .animate.height.ng-hide-add.ng-hide-add-active { 38 | height: 0; 39 | } 40 | .animate.height.ng-hide-remove { 41 | height: 0; 42 | } 43 | .animate.height.ng-hide-remove.ng-hide-remove-active { 44 | height: auto; 45 | } 46 | -------------------------------------------------------------------------------- /tars/surface/static/src/main/css/animate.less: -------------------------------------------------------------------------------- 1 | @charset 'utf-8'; 2 | 3 | .animate{ 4 | @opacity_show:1; 5 | @opacity_hide:0; 6 | .transition(@property:all,@timing:linear,@duration:0s){ 7 | -webkit-transition: @arguments; 8 | transition: @arguments; 9 | } 10 | &.ng-hide-add{ 11 | .transition(); 12 | opacity: @opacity_show; 13 | } 14 | &.ng-hide-remove{ 15 | .transition(); 16 | &.ng-hide-add{ 17 | opacity: @opacity_hide; 18 | } 19 | } 20 | &.ng-hide-add-active{ 21 | .transition(0.5s); 22 | opacity: @opacity_hide; 23 | } 24 | &.ng-hide-remove-active{ 25 | .transition(0.5s); 26 | &.ng-hide-add-active{ 27 | opacity: @opacity_show; 28 | } 29 | } 30 | &.fast{ 31 | &.ng-hide-add-active,&.ng-hide-remove-active { 32 | .transition(1s); 33 | } 34 | } 35 | 36 | &.height{ 37 | overflow: hidden; 38 | &.ng-hide-add { 39 | height: auto; 40 | &.ng-hide-add-active{ 41 | height:0; 42 | } 43 | } 44 | &.ng-hide-remove{ 45 | height:0; 46 | &.ng-hide-remove-active{ 47 | height:auto; 48 | } 49 | } 50 | 51 | } 52 | 53 | } -------------------------------------------------------------------------------- /tars/surface/static/src/main/css/easypie.css: -------------------------------------------------------------------------------- 1 | @charset 'utf-8'; 2 | .easypie { 3 | position: relative; 4 | display: inline-block; 5 | text-align: center; 6 | font-weight: 100; 7 | width: 100%; 8 | /*96px*/ 9 | height: 100%; 10 | /*96px*/ 11 | } 12 | .easypie canvas { 13 | position: absolute; 14 | top: 0; 15 | left: 0; 16 | } 17 | .easypie .percent { 18 | display: inline-block; 19 | z-index: 2; 20 | line-height: 96px; 21 | font-size: 2em; 22 | } 23 | .easypie .percent:after { 24 | content: '%'; 25 | margin-left: 0.1em; 26 | font-size: .5em; 27 | } 28 | .easypie .second { 29 | display: inline-block; 30 | z-index: 2; 31 | line-height: 96px; 32 | font-size: 2em; 33 | } 34 | .easypie .second:after { 35 | content: 's'; 36 | margin-left: 0.1em; 37 | font-size: .5em; 38 | } 39 | .easypie.lg { 40 | width: 196px; 41 | height: 196px; 42 | } 43 | .easypie.lg .percent, 44 | .easypie.lg .second { 45 | line-height: 196px; 46 | font-size: 6em; 47 | } 48 | .easypie.lg .percent:after, 49 | .easypie.lg .second:after { 50 | margin-left: 0.4em; 51 | font-size: 0.6em; 52 | } 53 | -------------------------------------------------------------------------------- /tars/surface/static/src/main/css/easypie.less: -------------------------------------------------------------------------------- 1 | @charset 'utf-8'; 2 | .easypie { 3 | .count-it(){ 4 | display: inline-block; 5 | z-index: 2; 6 | line-height: 96px; 7 | font-size: 2em; 8 | } 9 | .count-it-after(@content){ 10 | content:@content; 11 | margin-left: 0.1em; 12 | font-size: .5em; 13 | } 14 | position: relative; 15 | display: inline-block; 16 | text-align: center; 17 | font-weight: 100; 18 | width: 100%; 19 | /*96px*/ 20 | height: 100%; 21 | /*96px*/ 22 | canvas { 23 | position: absolute; 24 | top: 0; 25 | left: 0; 26 | } 27 | .percent{ 28 | .count-it; 29 | &:after{ 30 | .count-it-after('%'); 31 | } 32 | } 33 | .second{ 34 | .count-it; 35 | &:after{ 36 | .count-it-after('s'); 37 | } 38 | } 39 | 40 | &.lg{ 41 | width: 196px; 42 | height: 196px; 43 | .percent,.second { 44 | line-height: 196px; 45 | font-size: 6em; 46 | &:after{ 47 | margin-left: 0.4em; 48 | font-size: 0.6em; 49 | } 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /tars/surface/static/src/main/images/1x1_0.5_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/src/main/images/1x1_0.5_black.png -------------------------------------------------------------------------------- /tars/surface/static/src/main/images/404-lg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/src/main/images/404-lg.png -------------------------------------------------------------------------------- /tars/surface/static/src/main/images/404-md.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/src/main/images/404-md.png -------------------------------------------------------------------------------- /tars/surface/static/src/main/images/404-sm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/src/main/images/404-sm.png -------------------------------------------------------------------------------- /tars/surface/static/src/main/images/404-xs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/src/main/images/404-xs.png -------------------------------------------------------------------------------- /tars/surface/static/src/main/images/arrow-bottom-left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/src/main/images/arrow-bottom-left.png -------------------------------------------------------------------------------- /tars/surface/static/src/main/images/arrow-bottom-left2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/src/main/images/arrow-bottom-left2.png -------------------------------------------------------------------------------- /tars/surface/static/src/main/images/arrow-bottom-right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/src/main/images/arrow-bottom-right.png -------------------------------------------------------------------------------- /tars/surface/static/src/main/images/arrow-bottom-right2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/src/main/images/arrow-bottom-right2.png -------------------------------------------------------------------------------- /tars/surface/static/src/main/images/arrow-top-left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/src/main/images/arrow-top-left.png -------------------------------------------------------------------------------- /tars/surface/static/src/main/images/arrow-top-left2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/src/main/images/arrow-top-left2.png -------------------------------------------------------------------------------- /tars/surface/static/src/main/images/arrow-top-right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/src/main/images/arrow-top-right.png -------------------------------------------------------------------------------- /tars/surface/static/src/main/images/arrow-top-right2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/src/main/images/arrow-top-right2.png -------------------------------------------------------------------------------- /tars/surface/static/src/main/images/bg_noise.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/src/main/images/bg_noise.png -------------------------------------------------------------------------------- /tars/surface/static/src/main/images/bg_stitch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/src/main/images/bg_stitch.png -------------------------------------------------------------------------------- /tars/surface/static/src/main/images/blank.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/src/main/images/blank.gif -------------------------------------------------------------------------------- /tars/surface/static/src/main/images/body_bg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/src/main/images/body_bg.gif -------------------------------------------------------------------------------- /tars/surface/static/src/main/images/bxslider/bx_loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/src/main/images/bxslider/bx_loader.gif -------------------------------------------------------------------------------- /tars/surface/static/src/main/images/bxslider/clog-36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/src/main/images/bxslider/clog-36.png -------------------------------------------------------------------------------- /tars/surface/static/src/main/images/bxslider/controls.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/src/main/images/bxslider/controls.png -------------------------------------------------------------------------------- /tars/surface/static/src/main/images/chart/circlepin-30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/src/main/images/chart/circlepin-30.png -------------------------------------------------------------------------------- /tars/surface/static/src/main/images/ctrl-up-down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/src/main/images/ctrl-up-down.png -------------------------------------------------------------------------------- /tars/surface/static/src/main/images/goback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/src/main/images/goback.png -------------------------------------------------------------------------------- /tars/surface/static/src/main/images/loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/src/main/images/loader.gif -------------------------------------------------------------------------------- /tars/surface/static/src/main/images/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/src/main/images/loading.gif -------------------------------------------------------------------------------- /tars/surface/static/src/main/images/lockscreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/src/main/images/lockscreen.png -------------------------------------------------------------------------------- /tars/surface/static/src/main/images/logo.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/src/main/images/logo.ico -------------------------------------------------------------------------------- /tars/surface/static/src/main/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/src/main/images/logo.png -------------------------------------------------------------------------------- /tars/surface/static/src/main/images/postmark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/src/main/images/postmark.png -------------------------------------------------------------------------------- /tars/surface/static/src/main/images/resource/lockscreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/src/main/images/resource/lockscreen.png -------------------------------------------------------------------------------- /tars/surface/static/src/main/images/resource/uc_user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/src/main/images/resource/uc_user.png -------------------------------------------------------------------------------- /tars/surface/static/src/main/images/rm-36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/src/main/images/rm-36.png -------------------------------------------------------------------------------- /tars/surface/static/src/main/images/scrollbar_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/src/main/images/scrollbar_white.png -------------------------------------------------------------------------------- /tars/surface/static/src/main/images/sleep-lg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/src/main/images/sleep-lg.png -------------------------------------------------------------------------------- /tars/surface/static/src/main/images/slider_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/src/main/images/slider_white.png -------------------------------------------------------------------------------- /tars/surface/static/src/main/images/tars.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/src/main/images/tars.png -------------------------------------------------------------------------------- /tars/surface/static/src/main/images/uc_user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/src/main/images/uc_user.png -------------------------------------------------------------------------------- /tars/surface/static/src/main/images/upload/user/photo-user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/src/main/images/upload/user/photo-user.png -------------------------------------------------------------------------------- /tars/surface/static/src/main/images/upload/user/zhuoluo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/src/main/images/upload/user/zhuoluo.jpg -------------------------------------------------------------------------------- /tars/surface/static/src/main/images/xmon-36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctripcorp/tars/d7954fccaf1a17901f22d844d84c5663a3d79c11/tars/surface/static/src/main/images/xmon-36.png -------------------------------------------------------------------------------- /tars/surface/static/src/main/js/com/ctrip/tars/apps/multi/filter/MonitorStatus.js: -------------------------------------------------------------------------------- 1 | Class.forName({ 2 | name: "class com.ctrip.tars.apps.multi.filter.MonitorStatus extends Object", 3 | "@Getter @Setter name": "", 4 | "@Getter @Setter icon": "", 5 | "@Getter @Setter title": "", 6 | "@Getter @Setter size": "", 7 | "@Getter @Setter left": "", 8 | "@Getter @Setter marginLeft": "", 9 | "@Getter @Setter disabled": false, 10 | "@Getter @Setter active": false, 11 | "@Getter @Setter effect": false, 12 | "@Getter @Setter value": 0, 13 | "@Getter @Setter badge": "", 14 | 15 | MonitorStatus: function(name, icon, title, size, left, marginLeft, active, disabled, effect, badge) { 16 | this.name = name; 17 | this.icon = icon; 18 | this.title = title; 19 | this.size = size; 20 | this.left = left; 21 | this.marginLeft = marginLeft; 22 | this.active = !!active; 23 | this.disabled = !!disabled; 24 | this.effect = !!effect; 25 | this.badge = badge; 26 | }, 27 | 28 | "abstract click": function($scope, $event) { 29 | $scope.toggleStatusWanted(this.name); 30 | }, 31 | 32 | "plus": function(value) { 33 | this.value += value; 34 | }, 35 | 36 | "minus": function(value) { 37 | this.value -= value; 38 | } 39 | }); 40 | 41 | -------------------------------------------------------------------------------- /tars/surface/static/src/main/js/com/ctrip/tars/base/DefaultService.js: -------------------------------------------------------------------------------- 1 | $import("com.ctrip.tars.base.Service"); 2 | 3 | Class.forName({ 4 | name: "class com.ctrip.tars.base.DefaultService extends com.ctrip.tars.base.Service", 5 | 6 | "public static final REPLACE": 0, 7 | "public static final ISOLATE": 1, 8 | 9 | DefaultService: function() {}, 10 | 11 | "protected absolute parse": function(data, params, mode) { 12 | if (mode !== com.ctrip.tars.base.DefaultService.ISOLATE) { 13 | this.data = data || result; 14 | } 15 | }, 16 | 17 | "public load": function(path, filters, callback, exception) { 18 | this.loadData(this.getUrl(path), filters, null, null, function() { 19 | this.update(callback); 20 | }, com.ctrip.tars.base.DefaultService.REPLACE, exception); 21 | }, 22 | 23 | "public get": function(path, filters, callback, exception) { 24 | this.loadData(this.getUrl(path), filters, null, null, callback, com.ctrip.tars.base.DefaultService.ISOLATE, exception); 25 | } 26 | }); 27 | 28 | -------------------------------------------------------------------------------- /tars/surface/static/src/main/js/com/ctrip/tars/component/ICheckbox.js: -------------------------------------------------------------------------------- 1 | Class.forName({ 2 | name: "class com.ctrip.tars.component.ICheckbox extends Object", 3 | 4 | "@Setter checked": true, 5 | "@Setter disabled": false, 6 | 7 | "ICheckbox": function(checked, disabled) { 8 | this.checked = checked; 9 | this.disabled = disabled; 10 | }, 11 | 12 | getChecked: function() { 13 | return this.isChecked() ? "checked" : ""; 14 | }, 15 | getDisabled: function() { 16 | return this.isDisabled() ? "disabled" : ""; 17 | }, 18 | 19 | isChecked: function() { 20 | return this.checked; 21 | }, 22 | isDisabled: function() { 23 | return this.disabled; 24 | } 25 | }); 26 | 27 | -------------------------------------------------------------------------------- /tars/surface/static/src/main/js/com/ctrip/tars/component/IForm.js: -------------------------------------------------------------------------------- 1 | Class.forName({ 2 | name: "class com.ctrip.tars.component.IForm extends Object", 3 | 4 | "@Getter @Setter element": "", 5 | 6 | IForm: function(element) { 7 | this.element = element; 8 | }, 9 | "public reset": function() { 10 | //TODO 11 | }, 12 | "public getValues": function() { 13 | var values = {}, 14 | dom = this.element; 15 | if (dom) { 16 | $.each(dom.find('input,select,textarea'), function(i, n) { 17 | if (n.type != 'button' && !n.disabled) { 18 | if (n.id || n.name) { 19 | var value = null; 20 | try { 21 | switch (n.type) { 22 | case "radio": 23 | case "number": 24 | value = $(n).val() * 1; 25 | break; 26 | default: 27 | value = $(n).val(); 28 | break; 29 | } 30 | } catch (e) {} 31 | if (value == 'undefined') value = null; 32 | values[n.id || n.name] = value || null; 33 | } 34 | } 35 | }); 36 | } 37 | return values; 38 | } 39 | }); 40 | 41 | -------------------------------------------------------------------------------- /tars/surface/static/src/main/js/com/ctrip/tars/component/ISlider.js: -------------------------------------------------------------------------------- 1 | Class.forName({ 2 | name: "class com.ctrip.tars.component.ISlider extends Object", 3 | 4 | "@Getter @Setter element": null, 5 | 6 | ISlider: function(element, options) { 7 | this.options = options; 8 | this.element = $(element).bxSlider(this.options); 9 | }, 10 | 11 | reflow: function(options) { 12 | if (Object.isNull(this.element)) { 13 | return; 14 | } 15 | 16 | var index = this.element.getCurrentSlide(), 17 | count = this.element.getSlideCount(); 18 | 19 | if (index >= count || index < 0) { 20 | index = 0; 21 | } 22 | 23 | this.options = $.extend(true, this.options, options, { 24 | startSlide: index 25 | }); 26 | 27 | this.element.reloadSlider(this.options); 28 | 29 | //this.element.goToSlide(index); 30 | } 31 | 32 | }); 33 | 34 | -------------------------------------------------------------------------------- /tars/surface/static/src/main/js/com/ctrip/tars/component/angular/percent/Pie.js: -------------------------------------------------------------------------------- 1 | $import("com.ctrip.tars.util.Common"); 2 | $import("com.ctrip.tars.component.chart.Pie"); 3 | var easypie = angular 4 | .module("com.ctrip.tars.component.angular.percent.pie", []).directive('pie', function() { 5 | return { 6 | restrict: 'EA', 7 | replace: true, 8 | transclude: true, 9 | template: '

', 10 | scope: false, 11 | link: function(scope, element, attrs, controller) { 12 | var id = com.ctrip.tars.util.Common.stripscript(scope.hashCode()); 13 | element.attr("id", "high-chart-" + id).css("height", element.width()); 14 | new com.ctrip.tars.component.chart.Pie(id).render(); 15 | }, 16 | controller: ["$scope", function($scope) { 17 | 18 | }] 19 | }; 20 | }); 21 | 22 | -------------------------------------------------------------------------------- /tars/surface/static/src/main/js/com/ctrip/tars/component/angular/postmark/Postmark.js: -------------------------------------------------------------------------------- 1 | $import("com.ctrip.tars.component.Dragmove"); 2 | 3 | var postmark = angular.module("com.ctrip.tars.component.angular.postmark", []).service('com.ctrip.tars.component.angular.postmark.Service', ['$rootScope', '$http', function($rootScope, $http) { 4 | return {}; 5 | }]) 6 | .controller("com.ctrip.tars.component.angular.postmark.Controller", ['$scope', 'com.ctrip.tars.component.angular.postmark.Service', 7 | function($scope, service) {} 8 | ]) 9 | .directive("postmark", function() { 10 | return { 11 | restrict: 'E', 12 | replace: true, 13 | transclude: true, 14 | scope: false, 15 | template: ['
{{ date }}
{{ time }}
'].join(""), 16 | link: function(scope, element, attributes, postmarkController) { 17 | element.dragmove(); 18 | }, 19 | /* 20 | compile: function(element, attributes) { 21 | return { 22 | pre: function preLink(scope, element, attributes) { 23 | 24 | }, 25 | post: function postLink(scope, element, attributes) { 26 | 27 | } 28 | }; 29 | }, 30 | */ 31 | controller: ["$scope", function($scope) {}] 32 | }; 33 | }); 34 | 35 | -------------------------------------------------------------------------------- /tars/surface/static/src/main/js/com/ctrip/tars/config/Service.js: -------------------------------------------------------------------------------- 1 | $import("com.ctrip.tars.base.DefaultService"); 2 | 3 | Class.forName({ 4 | name: "class com.ctrip.tars.config.Service extends com.ctrip.tars.base.DefaultService", 5 | Service: function() {}, 6 | 7 | getUrl: function(path) { 8 | return ["/surface/config/"].join(""); 9 | } 10 | }); 11 | 12 | var header = angular.module("com.ctrip.tars.config", []) 13 | .service('com.ctrip.tars.config.Service', com.ctrip.tars.config.Service); 14 | 15 | -------------------------------------------------------------------------------- /tars/surface/static/src/main/js/com/ctrip/tars/deployments/Parallel.js: -------------------------------------------------------------------------------- 1 | tarsPortal.controller("com.ctrip.tars.deployments.parallel.Controller", ['$scope', '$rootScope', function($scope, $rootScope) { 2 | 3 | }]); 4 | 5 | -------------------------------------------------------------------------------- /tars/surface/static/src/main/js/com/ctrip/tars/deployments/Serial.js: -------------------------------------------------------------------------------- 1 | tarsPortal.controller("com.ctrip.tars.deployments.serial.Controller", ['$scope', '$rootScope', function($scope, $rootScope) { 2 | 3 | 4 | 5 | }]); 6 | 7 | -------------------------------------------------------------------------------- /tars/surface/static/src/main/js/com/ctrip/tars/deployments/Tabs.js: -------------------------------------------------------------------------------- 1 | tarsPortal.controller("com.ctrip.tars.deployments.tabs.Controller", ['$scope', '$rootScope', function($scope, $rootScope) { 2 | $scope.tabs = new js.util.HashMap(); 3 | 4 | $scope.tabs.put("app", { 5 | active: true, 6 | id: "app", 7 | name: "应用发布" 8 | }); 9 | /* 10 | $scope.tabs.put("pools", { 11 | active: false, 12 | id: "pools", 13 | name: "Pools" 14 | }); 15 | $scope.tabs.put("cis", { 16 | active: false, 17 | id: "cis", 18 | name: "CIs" 19 | }); 20 | */ 21 | $scope.switchTab = function(name) { 22 | var tabs = $scope.tabs, 23 | tab = tabs.get(name); 24 | if (tab && !tab.active) { 25 | tab.active = true; 26 | var it = tabs.keySet().iterator(); 27 | while (it.hasNext()) { 28 | var key = it.next(), 29 | value = tabs.get(key); 30 | if (!key.equals(name)) { 31 | value.active = false; 32 | } 33 | } 34 | } 35 | }; 36 | 37 | $scope.isActiveTab = function(name) { 38 | var tab = $scope.tabs.get(name); 39 | return tab && tab.active; 40 | }; 41 | 42 | $scope.getTabValues = function() { 43 | return $scope.tabs.values().toArray(); 44 | }; 45 | 46 | }]); 47 | 48 | -------------------------------------------------------------------------------- /tars/surface/static/src/main/js/com/ctrip/tars/group/rollback/Cancel.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by liujc on 2015/2/28. 3 | */ 4 | $import("com.ctrip.tars.group.Command"); 5 | 6 | Class.forName({ 7 | name: "class com.ctrip.tars.group.rollback.Cancel extends com.ctrip.tars.group.Command", 8 | 9 | "icon": "times", 10 | "text": "取消", 11 | "title": "取消", 12 | "@Getter @Setter position": "pull-right", 13 | "@Getter @Setter theme": "default", 14 | "@Getter @Setter status": 0, 15 | 16 | Cancel: function(status) { 17 | this.status = status; 18 | }, 19 | 20 | "click": function($scope, $event) { 21 | var scope = this; 22 | 23 | scope.$super.click.call(scope); 24 | scope.disabled = true; 25 | 26 | window.setTimeout(function() { 27 | $("#window--3").find(".au-dialog-close").click(); 28 | scope.disabled = false; 29 | }, 300); 30 | } 31 | }); 32 | 33 | -------------------------------------------------------------------------------- /tars/surface/static/src/main/js/com/ctrip/tars/group/rollback/CommandGroup.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by liujc on 2015/2/28. 3 | */ 4 | 5 | $import("com.ctrip.tars.group.rollback.Cancel"); 6 | $import("com.ctrip.tars.group.rollback.Confirm"); 7 | 8 | $import("js.util.HashMap", "BootstrapClassLoader"); 9 | Class.forName({ 10 | name: "class com.ctrip.tars.group.rollback.CommandGroup extends Object", 11 | 12 | "private groups": new js.util.HashMap(), 13 | 14 | "CommandGroup": function() { 15 | this.groups.put("step-0", [new com.ctrip.tars.group.rollback.Confirm(0), 16 | new com.ctrip.tars.group.rollback.Cancel(0) 17 | ]); 18 | }, 19 | "static getInstance": function() { 20 | if (Object.isNull(com.ctrip.tars.group.rollback.CommandGroup.instance)) { 21 | com.ctrip.tars.group.rollback.CommandGroup.instance = new com.ctrip.tars.group.rollback.CommandGroup(); 22 | } 23 | return com.ctrip.tars.group.rollback.CommandGroup.instance; 24 | }, 25 | 26 | "getCommands": function(key) { 27 | return this.groups.get(key); 28 | } 29 | }); 30 | 31 | -------------------------------------------------------------------------------- /tars/surface/static/src/main/js/com/ctrip/tars/group/rollback/Service.js: -------------------------------------------------------------------------------- 1 | $import("com.ctrip.tars.base.DefaultService"); 2 | 3 | Class.forName({ 4 | name: "class com.ctrip.tars.group.rollback.Service extends com.ctrip.tars.base.DefaultService", 5 | Service: function() {}, 6 | 7 | getUrl: function(path) { 8 | if (!com.ctrip.tars.util.Id.isValid(path.group)) { 9 | return null; 10 | } 11 | return [BASE_URL, "groups/", path.group, "/rollback_deployment"].join(""); 12 | }, 13 | 14 | getData: function() { 15 | if (!this.data.config) { 16 | this.data.config = { 17 | batchPattern: '50%', 18 | pauseTime: 0, 19 | startupTimeout: 0, 20 | verifyTimeout: 0, 21 | ignoreVerifyResult: false, 22 | restartAppPool: false 23 | }; 24 | } 25 | return this.data; 26 | } 27 | }); 28 | 29 | angular.module("com.ctrip.tars.group.rollback", []) 30 | .service('com.ctrip.tars.group.rollback.Service', com.ctrip.tars.group.rollback.Service); 31 | 32 | -------------------------------------------------------------------------------- /tars/surface/static/src/main/js/com/ctrip/tars/group/rollout/Cancel.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by liujc on 2015/2/28. 3 | */ 4 | $import("com.ctrip.tars.group.Command"); 5 | Class.forName({ 6 | name: "class com.ctrip.tars.group.rollout.Cancel extends com.ctrip.tars.group.Command", 7 | 8 | "icon": "times", 9 | "text": "取消", 10 | "title": "取消", 11 | "@Getter @Setter position": "pull-right", 12 | "@Getter @Setter theme": "default", 13 | "@Getter @Setter status": 0, 14 | 15 | Cancel: function(status) { 16 | this.status = status; 17 | }, 18 | 19 | "click": function($scope, $event) { 20 | var scope = this; 21 | 22 | scope.$super.click.call(scope); 23 | scope.disabled = true; 24 | 25 | window.setTimeout(function() { 26 | $("#window--2").find(".au-dialog-close").click(); 27 | scope.disabled = false; 28 | }, 300); 29 | } 30 | }); 31 | 32 | -------------------------------------------------------------------------------- /tars/surface/static/src/main/js/com/ctrip/tars/group/rollout/Next.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by liujc on 2015/2/28. 3 | */ 4 | $import("com.ctrip.tars.group.Command"); 5 | Class.forName({ 6 | name: "class com.ctrip.tars.group.rollout.Next extends com.ctrip.tars.group.Command", 7 | 8 | "icon": "arrow-right", 9 | "text": "下一步", 10 | "title": "下一步", 11 | "@Getter @Setter position": "pull-right", 12 | "@Getter @Setter theme": "primary", 13 | "@Getter @Setter status": 0, 14 | 15 | Next: function(status) { 16 | this.status = status; 17 | this.active = false; 18 | }, 19 | 20 | "click": function($scope, $event) { 21 | var scope = this; 22 | 23 | scope.$super.click.call(scope); 24 | scope.disabled = true; 25 | 26 | window.setTimeout(function() { 27 | //var ele = $event.target; 28 | var status = $scope.command.status; 29 | var steps = $scope.steps; 30 | if (status >= 0 && status < steps.length - 1) { 31 | steps[status].progress = "done"; 32 | steps[status + 1].progress = "doing"; 33 | } 34 | 35 | if (!$scope.$$phase) { 36 | $scope.$apply(); 37 | } 38 | 39 | scope.disabled = false; 40 | }, 300); 41 | 42 | } 43 | }); 44 | 45 | -------------------------------------------------------------------------------- /tars/surface/static/src/main/js/com/ctrip/tars/group/rollout/Previous.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by liujc on 2015/2/28. 3 | */ 4 | $import("com.ctrip.tars.group.Command"); 5 | Class.forName({ 6 | name: "class com.ctrip.tars.group.rollout.Previous extends com.ctrip.tars.group.Command", 7 | 8 | "icon": "arrow-left", 9 | "text": "上一步", 10 | "title": "上一步", 11 | "@Getter @Setter position": "pull-left", 12 | "@Getter @Setter theme": "default", 13 | "@Getter @Setter status": 0, 14 | 15 | Previous: function(status) { 16 | this.status = status; 17 | }, 18 | 19 | "click": function($scope, $event) { 20 | var scope = this; 21 | 22 | scope.$super.click.call(scope); 23 | scope.disabled = true; 24 | 25 | window.setTimeout(function() { 26 | //var ele = $event.target; 27 | var status = $scope.command.status; 28 | var steps = $scope.steps; 29 | if (status > 0 && status < steps.length) { 30 | steps[status].progress = "todo"; 31 | steps[status - 1].progress = "doing"; 32 | } 33 | if (!$scope.$$phase) { 34 | $scope.$apply(); 35 | } 36 | scope.disabled = false; 37 | }, 300); 38 | } 39 | }); 40 | 41 | -------------------------------------------------------------------------------- /tars/surface/static/src/main/js/com/ctrip/tars/groups/Service.js: -------------------------------------------------------------------------------- 1 | $import("com.ctrip.tars.base.PaginationService"); 2 | 3 | Class.forName({ 4 | name: "class com.ctrip.tars.groups.Service extends com.ctrip.tars.base.PaginationService", 5 | Service: function() {}, 6 | 7 | getUrl: function(path) { 8 | if (!com.ctrip.tars.util.Id.isValid(path.app)) { 9 | return null; 10 | } 11 | return [BASE_URL, "applications/", path.app, "/groups"].join(""); 12 | } 13 | }); 14 | 15 | 16 | angular 17 | .module("com.ctrip.tars.groups", []) 18 | .service('com.ctrip.tars.groups.Service', com.ctrip.tars.groups.Service); 19 | 20 | -------------------------------------------------------------------------------- /tars/surface/static/src/main/js/com/ctrip/tars/header/Header.js: -------------------------------------------------------------------------------- 1 | angular.module("com.ctrip.tars.header", ['com.ctrip.tars.component.angular.tooltip']) 2 | .controller("com.ctrip.tars.header.Controller", ['$scope', '$rootScope', '$location', 3 | function($scope, $rootScope, $location, service) { 4 | 5 | $scope.init = function() { 6 | /* 7 | $('a[data-toggle="tooltip"]').tooltip({ 8 | container: 'body' 9 | }); 10 | */ 11 | }; 12 | } 13 | ]); 14 | 15 | -------------------------------------------------------------------------------- /tars/surface/static/src/main/js/com/ctrip/tars/model/Application.js: -------------------------------------------------------------------------------- 1 | $import("com.ctrip.tars.model.Group"); 2 | Class.forName({ 3 | 4 | name: "class com.ctrip.tars.model.Application extend Object", 5 | 6 | "@Getter @Setter private id": null, 7 | "@Getter @Setter private appId": null, 8 | "@Getter @Setter private name": null, 9 | 10 | "@Getter @Setter private createdAt": null, 11 | "@Getter @Setter private updatedAt": null, 12 | 13 | "@Getter @Setter private statuses": null, 14 | 15 | "@Getter @Setter private groups": [], 16 | 17 | Application: function() { 18 | 19 | }, 20 | 21 | unserialize: function(json) { 22 | if (!Object.isNull(json)) { 23 | this.id = json.id; 24 | this.appId = json.appId; 25 | this.name = json.name; 26 | this.createdAt = json.createdAt; 27 | this.updatedAt = json.updatedAt; 28 | this.statuses = json.statuses; 29 | if (!Object.isNull(json.groups) && Object.isArray(json.groups)) { 30 | for (var i = 0, len = json.groups.length; i < len; i++) { 31 | this.groups.push(new com.ctrip.tars.model.Group().unserialize(json.groups[i])); 32 | } 33 | } 34 | } 35 | return this; 36 | }, 37 | serialize: function() { 38 | return this.toJson(); 39 | } 40 | }); 41 | 42 | -------------------------------------------------------------------------------- /tars/surface/static/src/main/js/com/ctrip/tars/model/Flowstep.js: -------------------------------------------------------------------------------- 1 | Class.forName({ 2 | 3 | name: "class com.ctrip.tars.model.Flowstep extend Object", 4 | 5 | "@Getter @Setter private name": 0, 6 | "@Getter @Setter private time": "", 7 | "@Getter @Setter private progress": "todo", // doing done todo error 8 | "@Getter @Setter private data": {}, 9 | 10 | 11 | Flowstep: function(name, progress, time, data, handler) { 12 | 13 | this.name = name; 14 | this.progress = progress || "todo"; 15 | this.time = time; 16 | this.data = data; 17 | if (handler && Object.isFunction(handler)) { 18 | this.handler = handler; 19 | } 20 | }, 21 | 22 | "handler": function() { 23 | var events = angular.element($("#com-ctrip-tars-console-Controller")).scope(); 24 | events.filter({ 25 | deploy_target_status: this.data.status, 26 | deploy_target: this.data.id 27 | }); 28 | 29 | $("li[name='console']").click(); 30 | } 31 | }); 32 | 33 | -------------------------------------------------------------------------------- /tars/surface/static/src/main/js/com/ctrip/tars/model/Group.js: -------------------------------------------------------------------------------- 1 | Class.forName({ 2 | name: "class com.ctrip.tars.model.Group extend Object", 3 | 4 | "@Getter @Setter private id": "", 5 | "@Getter @Setter private groupId": "", 6 | "@Getter @Setter private name": "", 7 | 8 | "@Getter @Setter private siteName": "", 9 | "@Getter @Setter private healthCheckUrl": "", 10 | "@Getter @Setter private fort": "", 11 | 12 | Group: function() { 13 | 14 | }, 15 | 16 | unserialize: function(json) { 17 | if (!Object.isNull(json)) { 18 | this.id = json.id; 19 | this.groupId = json.groupId; 20 | this.name = json.name; 21 | this.siteName = json.siteName; 22 | this.healthCheckUrl = json.healthCheckUrl; 23 | this.fort = json.fort; 24 | } 25 | return this; 26 | }, 27 | serialize: function() { 28 | return this.toJson(); 29 | } 30 | }); 31 | 32 | -------------------------------------------------------------------------------- /tars/surface/static/src/main/js/com/ctrip/tars/model/Notification.js: -------------------------------------------------------------------------------- 1 | Class.forName({ 2 | 3 | name: "class com.ctrip.tars.model.Notification extend Object", 4 | 5 | "public static final ERROR": 2, 6 | "public static final MESSAGE": 1, 7 | "public static final Notice": 0, 8 | 9 | "@Getter @Setter private level": 0, 10 | "@Getter @Setter private title": "", 11 | "@Getter @Setter private content": "", 12 | "handler": function() {}, 13 | 14 | Notification: function(level, title, content, handler) { 15 | this.level = level || 1; 16 | this.title = title; 17 | this.content = content; 18 | if (handler && Object.isFunction(handler)) { 19 | this.handler = handler; 20 | } 21 | } 22 | 23 | }); 24 | 25 | -------------------------------------------------------------------------------- /tars/surface/static/src/main/js/com/ctrip/tars/navigator/Navigator.js: -------------------------------------------------------------------------------- 1 | tarsPortal.controller("com.ctrip.tars.navigator.Controller", ['$scope', '$rootScope', '$location', 2 | function($scope, $rootScope, $location) { 3 | $scope.init = function() { 4 | /* Sidebar tree view */ 5 | $(".sidebar-menu .treeview").tree(); 6 | }; 7 | 8 | $scope.init(); 9 | } 10 | ]); 11 | 12 | -------------------------------------------------------------------------------- /tars/surface/static/src/main/js/com/ctrip/tars/util/Angular.js: -------------------------------------------------------------------------------- 1 | Class.forName({ 2 | name: "class com.ctrip.tars.util.Angular extends Object", 3 | 4 | Angular: function() {}, 5 | 6 | "static getParent": function(scope, selector) { 7 | if (!scope) { 8 | throw new js.lang.IllegalArgumentException("Parameter named scope can not be null."); 9 | } 10 | 11 | var $parent = scope.$parent; 12 | if (!selector) { 13 | return $parent; 14 | } 15 | 16 | var parent = com.ctrip.tars.util.Angular.getScope(selector); 17 | while ($parent && $parent != parent) { 18 | $parent = $parent.$parent; 19 | } 20 | return $parent; 21 | }, 22 | 23 | "static getScope": function(target) { 24 | var ele = $(target); 25 | if (ele.length < 0) { 26 | throw new js.lang.IllegalArgumentException("The element doesn't exist with selector of '" + target + "'"); 27 | } else if (ele.length > 1) { 28 | throw new js.lang.IllegalArgumentException("Exist more than one element with selector of '" + target + "'"); 29 | } 30 | return angular.element(ele).scope(); 31 | }, 32 | 33 | "static getRootScope": function() { 34 | return angular.element(document).scope(); 35 | } 36 | }); 37 | 38 | -------------------------------------------------------------------------------- /tars/surface/static/src/main/js/com/ctrip/tars/util/Csrf.js: -------------------------------------------------------------------------------- 1 | Class.forName({ 2 | name: "class com.ctrip.tars.util.Csrf extends Object", 3 | 4 | Csrf: function() {}, 5 | 6 | // using jQuery 7 | "public static getCookie": function(name) { 8 | var cookieValue = null; 9 | if (document.cookie && document.cookie !== '') { 10 | var cookies = document.cookie.split(';'); 11 | for (var i = 0; i < cookies.length; i++) { 12 | 13 | var cookie = (cookies[i] || "").trim(); 14 | // Does this cookie string begin with the name we want? 15 | if (cookie.substring(0, name.length + 1) === (name + '=')) { 16 | cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); 17 | break; 18 | } 19 | } 20 | } 21 | return cookieValue; 22 | } 23 | }); 24 | 25 | -------------------------------------------------------------------------------- /tars/surface/static/src/main/js/com/ctrip/tars/util/Id.js: -------------------------------------------------------------------------------- 1 | Class.forName({ 2 | name: "class com.ctrip.tars.util.Id extends Object", 3 | 4 | Id: function() {}, 5 | 6 | "public static isValid": function(id) { 7 | return !Object.isNull(id) && ((Object.isNumber(id) && id > 0) || (Object.isNumber(id * 1) && id * 1 > 0)); 8 | }, 9 | 10 | "public static isValidIds": function(ids) { 11 | if (!Object.isNull(ids)) { 12 | 13 | if (Object.isNumber(ids) && ids > 0) { 14 | return true; 15 | } else if (Object.isNumber(ids * 1) && ids * 1 > 0) { 16 | return true; 17 | } else { 18 | var idA = ("" + ids).split(","); 19 | for (var i = 0, len = idA.length; i < len; i++) { 20 | if (!Object.isNumber(idA[i] * 1) || idA[i] * 1 <= 0) { 21 | return false; 22 | } 23 | } 24 | return true; 25 | } 26 | } 27 | return false; 28 | } 29 | }); 30 | 31 | -------------------------------------------------------------------------------- /tars/surface/static/src/main/js/com/ctrip/tars/util/Jquery.js: -------------------------------------------------------------------------------- 1 | Class.forName({ 2 | name: "class com.ctrip.tars.util.Jquery extends Object", 3 | 4 | Jquery: function() {}, 5 | 6 | "static getOffset": function(target, origin) { 7 | var to = $(target).offset(), 8 | oo = $(origin).offset(); 9 | return { 10 | left: to.left - oo.left, 11 | top: to.top - oo.top 12 | }; 13 | } 14 | }); 15 | 16 | -------------------------------------------------------------------------------- /tars/surface/static/src/main/js/com/ctrip/tars/util/LocalStorage.js: -------------------------------------------------------------------------------- 1 | Class.forName({ 2 | name: "class com.ctrip.tars.util.LocalStorage extend Object", 3 | 4 | "public static instance": null, 5 | 6 | "private LocalStorage": function() {}, 7 | 8 | "public static getInstance": function() { 9 | if (!com.ctrip.tars.util.LocalStorage.instance) { 10 | com.ctrip.tars.util.LocalStorage.instance = new com.ctrip.tars.util.LocalStorage(); 11 | } 12 | return com.ctrip.tars.util.LocalStorage.instance; 13 | }, 14 | 15 | put: function(key, value) { 16 | localStorage[key] = JSON.stringify(value); 17 | }, 18 | 19 | get: function(key) { 20 | var value = localStorage[key]; 21 | return value ? JSON.parse(value) : null; 22 | }, 23 | 24 | remove: function(key) { 25 | delete localStorage[key]; 26 | }, 27 | 28 | clear: function() { 29 | for (var key in localStorage) { 30 | delete localStorage[key]; 31 | } 32 | }, 33 | 34 | length: function() { 35 | return localStorage.length; 36 | }, 37 | 38 | size: function() { 39 | return this.length(); 40 | } 41 | }); 42 | 43 | -------------------------------------------------------------------------------- /tars/surface/static/src/main/js/com/ctrip/tars/util/Slot.js: -------------------------------------------------------------------------------- 1 | $import("js.util.Stack", "BootstrapClassLoader"); 2 | 3 | Class.forName({ 4 | name: "class com.ctrip.tars.util.Slot extends js.util.Stack", 5 | 6 | Slot: function() {}, 7 | push: function(ele) { 8 | var index = this.search(ele); 9 | if (index !== -1) { 10 | if (index === this.length() - 1) { 11 | return; 12 | } 13 | //移动到最顶端 14 | this._table.splice(index, 1); 15 | } 16 | this.$super.push.call(this, ele); 17 | }, 18 | 19 | "set": function(index, element) { 20 | //不允许重复 21 | throw new js.lang.UnsupportedOperationException(); 22 | }, 23 | 24 | add: function(o) { 25 | //不允许重复 26 | throw new js.lang.UnsupportedOperationException(); 27 | }, 28 | addAll: function(c) { 29 | //不允许重复 30 | throw new js.lang.UnsupportedOperationException(); 31 | }, 32 | erase: function(ele) { 33 | var index = this.search(ele); 34 | if (index === -1) { 35 | return null; 36 | } 37 | return this._table.splice(index, 1); 38 | } 39 | 40 | }); 41 | 42 | -------------------------------------------------------------------------------- /tars/surface/static/src/main/skin/default/css/skin.less: -------------------------------------------------------------------------------- 1 | /* 2 | Skin default 3 | -------- 4 | */ 5 | @tars-type:; 6 | @bg-color-1:#11cfd2; // main-bg-color df5252 7 | @bg-color-3:darken(@bg-color-1,10%); //gray for checkbox:checked and list:active 8 | @fa-btn-bgcolor:#ffeb3b; //rollback btn bgcolor 9 | @sorter-btn-bgcolor:@bg-color-3;//for tab-bottom-border 10 | @scroll-top-btn-bgcolor:@bg-color-3;//scroll to top btn bg 11 | @tab-border-color:#ff6d00;//for tab-bottom-border 12 | @monitor-active-bgcolor:@bg-color-3; //for sort btn bgcolor 13 | 14 | @bg-color-2:#9e9e9e; //gray for checkbox:disabled 15 | @font-color-1:#f9f9f9; //white font 16 | @font-color-2:mix(@bg-color-1,#fff,50%);//for tab word 17 | @font-color-3:#616161; 18 | @font-color-4:#999999; 19 | @input-font-color:#666; 20 | @border-color-1:#333; 21 | @border-color-2:#444; 22 | @topology-hover-color:#ffeb3b; 23 | @navbar-mixin-bg:rgba(0,0,0,0.2); 24 | @navbar-hover-bg:rgba(0,0,0,0.1); 25 | 26 | @import "../../skins.less"; -------------------------------------------------------------------------------- /tars/surface/static/src/main/skin/fat/css/skin.less: -------------------------------------------------------------------------------- 1 | /* 2 | Skin fat 3 | -------- 4 | */ 5 | @tars-type:'FAT'; 6 | @bg-color-1:#3897c5; // main-bg-color df5252 7 | @bg-color-3:darken(@bg-color-1,10%); //gray for checkbox:checked and list:active 8 | @fa-btn-bgcolor:#ffeb3b; //rollback btn bgcolor 9 | @sorter-btn-bgcolor:@bg-color-3;//for tab-bottom-border 10 | @scroll-top-btn-bgcolor:@bg-color-3;//scroll to top btn bg 11 | @tab-border-color:#ff6d00;//for tab-bottom-border 12 | @monitor-active-bgcolor:@bg-color-3; //for sort btn bgcolor 13 | 14 | @bg-color-2:#9e9e9e; //gray for checkbox:disabled 15 | @font-color-1:#f9f9f9; //white font 16 | @font-color-2:mix(@bg-color-1,#fff,50%);//for tab word 17 | @font-color-3:#616161; 18 | @font-color-4:#999999; 19 | @input-font-color:#666; 20 | @border-color-1:#333; 21 | @border-color-2:#444; 22 | @topology-hover-color:#ffeb3b; 23 | @navbar-mixin-bg:rgba(0,0,0,0.2); 24 | @navbar-hover-bg:rgba(0,0,0,0.1); 25 | 26 | @import "../../skins.less"; -------------------------------------------------------------------------------- /tars/surface/static/src/main/skin/test/css/skin.less: -------------------------------------------------------------------------------- 1 | /* 2 | Skin test 3 | -------- 4 | */ 5 | @tars-type:'TEST'; 6 | @bg-color-1:#009587; // main-bg-color df5252 7 | @bg-color-3:darken(@bg-color-1,10%); //gray for checkbox:checked and list:active 8 | @fa-btn-bgcolor:#ffeb3b; //rollback btn bgcolor 9 | @sorter-btn-bgcolor:@bg-color-3;//for tab-bottom-border 10 | @scroll-top-btn-bgcolor:@bg-color-3;//scroll to top btn bg 11 | @tab-border-color:#ff6d00;//for tab-bottom-border 12 | @monitor-active-bgcolor:@bg-color-3; //for sort btn bgcolor 13 | 14 | @bg-color-2:#9e9e9e; //gray for checkbox:disabled 15 | @font-color-1:#f9f9f9; //white font 16 | @font-color-2:mix(@bg-color-1,#fff,50%);//for tab word 17 | @font-color-3:#616161; 18 | @font-color-4:#999999; 19 | @input-font-color:#666; 20 | @border-color-1:#333; 21 | @border-color-2:#444; 22 | @topology-hover-color:#ffeb3b; 23 | @navbar-mixin-bg:rgba(0,0,0,0.2); 24 | @navbar-hover-bg:rgba(0,0,0,0.1); 25 | 26 | @import "../../skins.less"; -------------------------------------------------------------------------------- /tars/surface/static/src/main/skin/uat/css/skin.less: -------------------------------------------------------------------------------- 1 | /* 2 | Skin uat 3 | -------- 4 | */ 5 | @tars-type:'UAT'; 6 | @bg-color-1:#6f5499; // main-bg-color df5252 7 | @bg-color-3:darken(@bg-color-1,10%); //gray for checkbox:checked and list:active 8 | @fa-btn-bgcolor:#ffeb3b; //rollback btn bgcolor 9 | @sorter-btn-bgcolor:@bg-color-3;//for tab-bottom-border 10 | @scroll-top-btn-bgcolor:@bg-color-3;//scroll to top btn bg 11 | @tab-border-color:#ff6d00;//for tab-bottom-border 12 | @monitor-active-bgcolor:@bg-color-3; //for sort btn bgcolor 13 | 14 | @bg-color-2:#9e9e9e; //gray for checkbox:disabled 15 | @font-color-1:#f9f9f9; //white font 16 | @font-color-2:mix(@bg-color-1,#fff,50%);//for tab word 17 | @font-color-3:#616161; 18 | @font-color-4:#999999; 19 | @input-font-color:#666; 20 | @border-color-1:#333; 21 | @border-color-2:#444; 22 | @topology-hover-color:#ffeb3b; 23 | @navbar-mixin-bg:rgba(0,0,0,0.2); 24 | @navbar-hover-bg:rgba(0,0,0,0.1); 25 | 26 | @import "../../skins.less"; -------------------------------------------------------------------------------- /tars/surface/static/src/main/template/404.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
-------------------------------------------------------------------------------- /tars/surface/static/src/main/template/cis.html: -------------------------------------------------------------------------------- 1 | I'm cis. -------------------------------------------------------------------------------- /tars/surface/static/src/main/template/dialog/batches.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tars/surface/static/src/main/template/group.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 5 |
6 |

7 | 11 |

12 |
13 | 14 | 15 | 16 | 17 | 18 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 | 32 |
-------------------------------------------------------------------------------- /tars/surface/static/src/main/template/parallel.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 5 | 6 | 7 |
8 | 12 | 13 |
14 |
15 | 16 |
17 |
18 | 19 | 20 |
21 |
22 |
23 |
24 |
-------------------------------------------------------------------------------- /tars/surface/static/src/main/template/pools.html: -------------------------------------------------------------------------------- 1 | I'm pools. -------------------------------------------------------------------------------- /tars/surface/templates/OnService.html: -------------------------------------------------------------------------------- 1 | 4008206666 -------------------------------------------------------------------------------- /tars/surface/templates/admin/404.html: -------------------------------------------------------------------------------- 1 | {% extends "admin/base_site.html" %} 2 | {% load i18n %} 3 | 4 | {% block title %}{% trans 'Page not found' %}{% endblock %} 5 | 6 | {% block content %} 7 | 8 |

{% trans 'Page not found' %}

9 | 10 |

{% trans "We're sorry, but the requested page could not be found." %}

11 | 12 | {% endblock %} 13 | -------------------------------------------------------------------------------- /tars/surface/templates/admin/500.html: -------------------------------------------------------------------------------- 1 | {% extends "admin/base_site.html" %} 2 | {% load i18n %} 3 | 4 | {% block breadcrumbs %} 5 | 9 | {% endblock %} 10 | 11 | {% block title %}{% trans 'Server error (500)' %}{% endblock %} 12 | 13 | {% block content %} 14 |

{% trans 'Server Error (500)' %}

15 |

{% trans "There's been an error. It's been reported to the site administrators via email and should be fixed shortly. Thanks for your patience." %}

16 | 17 | {% endblock %} 18 | -------------------------------------------------------------------------------- /tars/surface/templates/admin/actions.html: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 |
3 | {% for field in action_form %}{% if field.label %}{% endif %}{% endfor %} 4 | 5 | {% if actions_selection_counter %} 6 | 7 | {{ selection_note }} 8 | {% if cl.result_count != cl.result_list|length %} 9 | {{ selection_note_all }} 10 | 11 | {% blocktrans with cl.result_count as total_count %}Select all {{ total_count }} {{ module_name }}{% endblocktrans %} 12 | 13 | {% trans "Clear selection" %} 14 | {% endif %} 15 | {% endif %} 16 |
17 | -------------------------------------------------------------------------------- /tars/surface/templates/admin/app_index.html: -------------------------------------------------------------------------------- 1 | {% extends "admin/index.html" %} 2 | {% load i18n %} 3 | 4 | {% if not is_popup %} 5 | {% block breadcrumbs %} 6 | 13 | {% endblock %} 14 | {% endif %} 15 | 16 | {% block sidebar %}{% endblock %} 17 | -------------------------------------------------------------------------------- /tars/surface/templates/admin/auth/user/add_form.html: -------------------------------------------------------------------------------- 1 | {% extends "admin/change_form.html" %} 2 | {% load i18n %} 3 | 4 | {% block form_top %} 5 | {% if not is_popup %} 6 |

{% trans "First, enter a username and password. Then, you'll be able to edit more user options." %}

7 | {% else %} 8 |

{% trans "Enter a username and password." %}

9 | {% endif %} 10 | {% endblock %} 11 | 12 | {% block after_field_sets %} 13 | 14 | {% endblock %} 15 | -------------------------------------------------------------------------------- /tars/surface/templates/admin/base_site.html: -------------------------------------------------------------------------------- 1 | {% extends "admin/base.html" %} 2 | {% load i18n %} 3 | 4 | {% block title %}{{ title }} | {% 'Tars site admin' %}{% endblock %} 5 | 6 | {% block branding %} 7 |

{% 'Tars Login' %}

8 | {% endblock %} 9 | 10 | {% block nav-global %}{% endblock %} 11 | -------------------------------------------------------------------------------- /tars/surface/templates/admin/date_hierarchy.html: -------------------------------------------------------------------------------- 1 | {% if show %} 2 |
3 |
9 |
10 | {% endif %} 11 | -------------------------------------------------------------------------------- /tars/surface/templates/admin/filter.html: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 |

{% blocktrans with filter_title=title %} By {{ filter_title }} {% endblocktrans %}

3 | 9 | -------------------------------------------------------------------------------- /tars/surface/templates/admin/invalid_setup.html: -------------------------------------------------------------------------------- 1 | {% extends "admin/base_site.html" %} 2 | {% load i18n %} 3 | 4 | {% block breadcrumbs %} 5 | 9 | {% endblock %} 10 | 11 | {% block content %} 12 |

{% trans "Something's wrong with your database installation. Make sure the appropriate database tables have been created, and make sure the database is readable by the appropriate user." %}

13 | {% endblock %} 14 | -------------------------------------------------------------------------------- /tars/surface/templates/admin/pagination.html: -------------------------------------------------------------------------------- 1 | {% load admin_list %} 2 | {% load i18n %} 3 |

4 | {% if pagination_required %} 5 | {% for i in page_range %} 6 | {% paginator_number cl i %} 7 | {% endfor %} 8 | {% endif %} 9 | {{ cl.result_count }} {% ifequal cl.result_count 1 %}{{ cl.opts.verbose_name }}{% else %}{{ cl.opts.verbose_name_plural }}{% endifequal %} 10 | {% if show_all_url %}  {% trans 'Show all' %}{% endif %} 11 | {% if cl.formset and cl.result_count %}{% endif %} 12 |

13 | -------------------------------------------------------------------------------- /tars/surface/templates/admin/popup_response.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /tars/surface/templates/admin/prepopulated_fields_js.html: -------------------------------------------------------------------------------- 1 | {% load l10n %} 2 | 28 | -------------------------------------------------------------------------------- /tars/surface/templates/admin/search_form.html: -------------------------------------------------------------------------------- 1 | {% load i18n admin_static %} 2 | {% if cl.search_fields %} 3 |
16 | 17 | {% endif %} 18 | -------------------------------------------------------------------------------- /tars/surface/templates/admin/submit_line.html: -------------------------------------------------------------------------------- 1 | {% load i18n admin_urls %} 2 |
3 | {% if show_save %}{% endif %} 4 | {% if show_delete_link %} 5 | {% url opts|admin_urlname:'delete' original.pk|admin_urlquote as delete_url %} 6 | 7 | {% endif %} 8 | {% if show_save_as_new %}{%endif%} 9 | {% if show_save_and_add_another %}{% endif %} 10 | {% if show_save_and_continue %}{% endif %} 11 |
12 | -------------------------------------------------------------------------------- /tars/surface/templates/settings.html: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | {% for name, value in settings.items %} 16 | 17 | 18 | 19 | 20 | {% endfor %} 21 | 22 |
{% trans "Setting" %}{% trans "Value" %}
{{ name }}{{ value|pprint }}
23 | -------------------------------------------------------------------------------- /tars/surface/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import patterns, url 2 | 3 | from tars.surface import views 4 | 5 | 6 | urlpatterns = patterns('', 7 | url(r'^$', views.index, name='surface_index'), 8 | url(r'^ping/$', views.ping, name='surface_ping'), 9 | url(r'^settings/$', views.export_settings, 10 | name='settings'), 11 | ) 12 | -------------------------------------------------------------------------------- /tars/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import patterns, include, url 2 | from django.contrib import admin 3 | from django.views.generic import TemplateView, RedirectView 4 | 5 | 6 | urlpatterns = patterns('', 7 | url(r'^admin/', include(admin.site.urls)), 8 | url(r'^api/v1/', include('tars.api.urls')), 9 | url(r'^(surface/)?', include("tars.surface.urls")), 10 | url(r'^domaininfo/', TemplateView.as_view(template_name='OnService.html')), # health check flag 11 | url(r'^favicon\.ico$', RedirectView.as_view(url='/static/logo.ico')), 12 | url(r'^login/$', 'tars.surface.views.login'), 13 | url(r'^logout/$', 'tars.surface.views.logout'), 14 | ) 15 | 16 | # if settings.DEBUG: 17 | # additional_ones = patterns('', 18 | # url(r'^docs/', 19 | # include('rest_framework_swagger.urls')), 20 | # ) 21 | # urlpatterns += additional_ones 22 | # 23 | -------------------------------------------------------------------------------- /tars/wsgi.py: -------------------------------------------------------------------------------- 1 | import os 2 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tars.settings") 3 | 4 | from django.conf import settings 5 | from django.core.wsgi import get_wsgi_application 6 | 7 | if "raven.contrib.django.raven_compat" in settings.INSTALLED_APPS: 8 | from raven.contrib.django.raven_compat.middleware.wsgi import Sentry 9 | application = Sentry(get_wsgi_application()) 10 | else: 11 | from django.core.wsgi import get_wsgi_application 12 | application = get_wsgi_application() 13 | -------------------------------------------------------------------------------- /tools/celeryd.conf: -------------------------------------------------------------------------------- 1 | # Names of nodes to start 2 | # most will only start one node: 3 | CELERYD_NODES="worker1" 4 | 5 | # Absolute or relative path to the 'celery' command: 6 | CELERY_BIN="$(which celery)" 7 | 8 | # App instance to use 9 | # comment out this line if you don't use an app 10 | CELERY_APP="roll_engine" 11 | 12 | # Where to chdir at start. 13 | CELERYD_CHDIR="/opt/apps/tars/current" 14 | 15 | # Extra command-line arguments to the worker 16 | CELERYD_OPTS="--time-limit=300 --concurrency=8" 17 | 18 | # %N will be replaced with the first part of the nodename. 19 | CELERYD_LOG_FILE="/var/log/celery/%N.log" 20 | CELERYD_PID_FILE="/var/run/celery/%N.pid" 21 | 22 | # Workers should run as an unprivileged user. 23 | # You need to create this user manually (or you can choose 24 | # a user/group combination that already exists, e.g. nobody). 25 | CELERYD_USER="op1" 26 | CELERYD_GROUP="op1" 27 | 28 | # If enabled pid and log directories will be created if missing, 29 | # and owned by the userid/group configured. 30 | CELERY_CREATE_DIRS=1 31 | -------------------------------------------------------------------------------- /tools/celeryd.conf.j2: -------------------------------------------------------------------------------- 1 | # Names of nodes to start 2 | # most will only start one node: 3 | CELERYD_NODES="worker1" 4 | 5 | # Absolute or relative path to the 'celery' command: 6 | CELERY_BIN="$(which celery)" 7 | 8 | # App instance to use 9 | # comment out this line if you don't use an app 10 | CELERY_APP="roll_engine" 11 | 12 | # Where to chdir at start. 13 | CELERYD_CHDIR="/opt/apps/tars/current" 14 | 15 | # Extra command-line arguments to the worker 16 | CELERYD_OPTS="--time-limit=300 --concurrency=8" 17 | 18 | # %N will be replaced with the first part of the nodename. 19 | CELERYD_LOG_FILE="/var/log/celery/%N.log" 20 | CELERYD_PID_FILE="/var/run/celery/%N.pid" 21 | 22 | # Workers should run as an unprivileged user. 23 | # You need to create this user manually (or you can choose 24 | # a user/group combination that already exists, e.g. nobody). 25 | CELERYD_USER="{{ app_user }}" 26 | CELERYD_GROUP="{{ app_user }}" 27 | 28 | # If enabled pid and log directories will be created if missing, 29 | # and owned by the userid/group configured. 30 | CELERY_CREATE_DIRS=1 31 | -------------------------------------------------------------------------------- /tools/deploy.sh: -------------------------------------------------------------------------------- 1 | DIR="$( cd "$( dirname "$0" )" && pwd )" 2 | OS=$( lsb_release -si ) 3 | 4 | # UWSGI 5 | pip install uwsgi 6 | 7 | mkdir -p /var/log/uwsgi 8 | chmod 777 /var/log/uwsgi 9 | 10 | mkdir -p /var/www 11 | cp "$DIR/tarsd.ini" /var/www/ 12 | cp "$DIR/tarsd" /etc/init.d/ 13 | chmod 755 /etc/init.d/tarsd 14 | 15 | 16 | # NGINX 17 | case $OS in 18 | 'CentOS') 19 | yum install -y nginx 20 | ;; 21 | 'Ubuntu') 22 | apt-get install -y nginx 23 | ;; 24 | *) 25 | echo "Unsupported Linux distribution: $OS, aborting deployment" 26 | exit 64 27 | ;; 28 | esac 29 | 30 | cp "$DIR/django.conf" /etc/nginx/conf.d/ 31 | 32 | 33 | # CELERY 34 | mkdir -p /var/log/celery 35 | mkdir -p /var/run/celery 36 | chmod 777 /var/log/celery 37 | chmod 777 /var/run/celery 38 | 39 | cp "$DIR/celeryd.conf" /etc/default/celeryd 40 | cp "$DIR/celeryd" /etc/init.d/ 41 | chmod 755 /etc/init.d/celeryd 42 | 43 | 44 | # Finally restart related services 45 | service nginx restart 46 | service tarsd restart 47 | service celeryd restart 48 | -------------------------------------------------------------------------------- /tools/maintain.sh: -------------------------------------------------------------------------------- 1 | cd /opt/tars 2 | 3 | sudo git pull origin develop 4 | 5 | sudo service tarsd stop 6 | 7 | sudo service tarsd start 8 | 9 | sudo service nginx restart 10 | 11 | sudo service celeryd restart -------------------------------------------------------------------------------- /tools/restart.sh: -------------------------------------------------------------------------------- 1 | service tarsd stop && service tarsd start 2 | 3 | sleep 2 4 | 5 | service celeryd restart 6 | -------------------------------------------------------------------------------- /tools/tarsd.ini: -------------------------------------------------------------------------------- 1 | [uwsgi] 2 | chdir=/opt/apps/tars/current 3 | module=tars.wsgi 4 | master=True 5 | pidfile=/var/run/tarsd.pid 6 | vacuum=True 7 | socket=:8000 8 | max-requests=5000 9 | workers=3 10 | daemonize=/var/log/uwsgi/tars.log 11 | --------------------------------------------------------------------------------