рд╕реНрд╡рдЪрд╛рд▓рди SVN + Apache + LDAP

рдЙрдкрд░реНрдпреБрдХреНрдд рд▓рд┐рдВрдХ рдкрд░ рдмрд╣реБрдд рд╕реА рдмрд╛рддреЗрдВ рд▓рд┐рдЦреА рдЧрдИ рд╣реИрдВ, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдирдИ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдЦреЛрд▓рдиреЗ рдкрд░ рдореБрдЭреЗ рд╣рдореЗрд╢рд╛ рдХреБрдЫ рдЕрд╕реБрд╡рд┐рдзрд╛ рдорд╣рд╕реВрд╕ рд╣реБрдИ: рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдПрдХ рдирдпрд╛ рд╕реНрдерд╛рди рдмрдирд╛рдирд╛, svnadmin рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдмрдирд╛рдирд╛ рдФрд░ рдЕрдкрд╛рдЪреЗ рдХреЛ рдкреБрдирд░рд╛рд░рдВрдн рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рдерд╛ред рдЬрдм рдорд╣реАрдиреЗ рдореЗрдВ рдПрдХ рдмрд╛рд░ рдРрд╕рд╛ рдХрд╛рдо рдХрд░рдирд╛ рдкрдбрд╝рддрд╛ рд╣реИ, рддреЛ рдпрд╣ рд╕рд╣рдиреАрдп рд╣реЛрддрд╛ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЬрдм рдРрд╕рд╛ рдХрд╛рдо рд╕рдкреНрддрд╛рд╣ рдореЗрдВ рдХрдИ рдмрд╛рд░ рдХрд░рдирд╛ рдкрдбрд╝рддрд╛ рд╣реИ, рддреЛ рдпрд╣ рдЗрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рд╕реНрд╡рдЪрд╛рд▓рди рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд╛рдпрдХ рд╣реИред рджрд░рдЕрд╕рд▓, рд╣рдо рдХрдЯ рдХреЗ рддрд╣рдд рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░ рд░рд╣реЗ рд╣реИрдВред


рдЖрдЧреЗ рджреЗрдЦрддреЗ рд╣реБрдП, рдореИрдВ рд╕реНрд╡рдпрдВ рдЕрдкрд╛рдЪреЗ рдХреЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред

рдореБрдЦреНрдп рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдлрд╝рд╛рдЗрд▓ /etc/httpd/conf/httpd.conf
...... # Load config files from the config directory "/etc/httpd/conf.d". # Include conf.d/*.conf ...... 

рджрд░рдЕрд╕рд▓, рдпрд╣рд╛рдВ рд╕рдм рдХреБрдЫ рд╕реНрдкрд╖реНрдЯ рд╣реИ (рдорд╛рдирдХ рд╕реЗрдВрдЯреЛрд╕ 5.6 рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рд╕реЗ рдЕрдкрд╛рдЪреЗ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рддреЗ рд╕рдордп рдпрд╣ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рд╕реНрдерд╛рди рд╣реИ)

рдлрд╝рд╛рдЗрд▓ /etc/httpd/conf.d/subversion.conf
 LoadModule dav_svn_module modules/mod_dav_svn.so LoadModule authz_svn_module modules/mod_authz_svn.so LoadModule authnz_ldap_module modules/mod_authnz_ldap.so <VirtualHost *:5553> ServerName svn.company.ru ServerAdmin svn_admin@company.ru DocumentRoot /opt/svn/repo LimitRequestBody 2147483647 CustomLog /var/log/httpd/subversion.log combined ErrorLog /var/log/httpd/subversion-error.log <IfModule rewrite_module> RewriteLogLevel 0 RewriteEngine On RewriteCond "%{REQUEST_METHOD}" !"^(GET|POST|HEAD)$" RewriteCond "%{REQUEST_FILENAME}" "^/([^/\.]+)$" RewriteCond "/opt/svn/repo/%1" -d RewriteRule "^/([^/\.]+)$" "/$1/" [passthrough] </IfModule> Include conf.d/subversion.d/*.conf </VirtualHost> 

рдпрд╣ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдлрд╝рд╛рдЗрд▓ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддреА рд╣реИред рдпрд╣ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИ рдХрд┐ рд╣рдо рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рд╕рднреА рд╕реНрдерд╛рдиреЛрдВ рдХреЛ conf.d / subversion.d рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдореЗрдВ рдбрд╛рд▓рддреЗ рд╣реИрдВред рдпрд╣ рдХреНрдпреЛрдВ рдЖрд╡рд╢реНрдпрдХ рд╣реИ? рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдпрд╣ рдЯреНрд░реИрдХ рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реИ рдХрд┐ рдХреМрди рд╕реЗ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рд╢рд╛рдорд┐рд▓ рд╣реИрдВ, рдФрд░ рджреВрд╕рд░реА рдмрд╛рдд, рдЬрдм рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╢реБрд░реВ рд╣реЛрддреА рд╣реИ (рддреЛ рдЙрд╕ рдкрд░ рдФрд░ рдЕрдзрд┐рдХ)ред
рдлрд╝рд╛рдЗрд▓ /etc/httpd/conf.d/subversion.d/example_repo.conf
 <Location "/example_repo/"> DAV svn SVNPath /opt/svn/repo/example_repo SVNListParentPath on AuthType Basic AuthName "SVN Server" AuthBasicProvider ldap AuthzLDAPAuthoritative Off AuthLDAPBindDN "cn=ldpcat,cn=users,dc=company,dc=ru" AuthLDAPBindPassword "12345678" AuthLDAPURL ldap://ldap.company.ru:389/ou=user,dc=company,dc=ru?sAMAccountName?sub?(objectClass=*) AuthBasicAuthoritative off <Limit GET PROPFIND> Require valid-user </Limit> <Limit GET PROFIND PROPPATCH DELETE MERGE PUT POST MKCOL MKACTIVITY COPY MOVE LOCK UNLOCK> Require ldap-group cn=example_group,ou=user,dc=company,dc=ru </Limit> </Location> 

рдпрд╣рд╛рдВ рд╣рдо рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХреЗ рдирд╛рдо рдФрд░ рд╕реНрдерд╛рди рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдЗрдВрдЧрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рд╣рдо рдХрд┐рд╕ рдЦрд╛рддреЗ рдХреЛ AD рдбрд╛рдпрд░реЗрдХреНрдЯрд░реА (рд╣рд╛рдВ, AD рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ), рдЗрд╕ рдЦрд╛рддреЗ рдХрд╛ рдкрд╛рд╕рд╡рд░реНрдб, рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдФрд░ рдПрдХ рдЦреЛрдЬ рдлрд╝рд┐рд▓реНрдЯрд░ рджреЗрдЦреЗрдВрдЧреЗред рдЖрдЧреЗ, рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рд╣рдо рдЗрдВрдЧрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХреЛ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдбреЛрдореЗрди рдореЗрдВ рдЕрдзрд┐рдХреГрдд рд╕рднреА рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЛ рдЕрдиреБрдорддрд┐ рджреА рдЬрд╛рддреА рд╣реИ (рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЖрдк рдбреЛрдореЗрди рдореЗрдВ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╕рдореВрд╣ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ)ред рдЕрдЧрд▓рд╛, рдЕрдЧрд▓реА рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛, рд╣рдо рдЗрдВрдЧрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдбреЛрдореЗрди рдореЗрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХрд╛ рдХреМрди рд╕рд╛ рд╕рдореВрд╣ (рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, example_group) рдХреЛ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХреЗ рд╕рд╛рде рдЕрдиреНрдп рд╕рднреА рдХреНрд░рд┐рдпрд╛рдПрдВ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рд╣реИред

рдЕрдкрд╛рдЪреЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЗ рд╕рд╛рде рд╕рдм рдХреБрдЫ рд╕реНрдкрд╖реНрдЯ рд╣реИ, рдЕрдм рд╣рдо рдПрдХ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░реЗрдВрдЧреЗ рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рд╣рдо рдирдП рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдмрдирд╛рдПрдВрдЧреЗред рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЪрд╛рд╣рд┐рдП
  1. рдПрдХ рдЦрд╛рд▓реА рднрдВрдбрд╛рд░ рдмрдирд╛рдПрдБ
  2. рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХреЗ рд▓рд┐рдП рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдПрдБ
  3. рд╕рдореВрд╣ рдХреЗ рд╕рджрд╕реНрдпреЛрдВ рдХреЛ рдПрдХ рд╕реВрдЪрдирд╛ рдкрддреНрд░ рднреЗрдЬреЗрдВ рдЬрд┐рд╕рдореЗрдВ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рдмрджрд▓рд╛рд╡ рдХрд░рдиреЗ рдХрд╛ рдЕрдзрд┐рдХрд╛рд░ рд╣реЛ


рдЪрд▓рд┐рдП рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред


рдореИрдВрдиреЗ рд╡рд┐рдХрд▓реНрдк рд╕реЗ рд╕реНрд░реЛрдд рд╕реЗ рд╕реНрдерд╛рдкрд┐рдд python рд╕рдВрд╕реНрдХрд░рдг 2.7 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ --prefix = / opt / python2.7 --with-threads --enable-unicode = ucs4 --includedir = / usr / - рд╢рд╛рдорд┐рд▓ рдХрд░рдиреЗ рдпреЛрдЧреНрдп- ipv6ред рдпрд╣ рдЕрдЬрдЧрд░-рд▓реЗрдбреИрдк рдореЙрдбреНрдпреВрд▓ (рдореИрдВрдиреЗ рд╕реЗрдЯрдкреНрдЯреВрд▓ рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛) рдХреЛ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рднреА рдЖрд╡рд╢реНрдпрдХ рд╣реЛрдЧрд╛ред рдиреАрдЪреЗ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╣реА рд╣реИред
 #!/usr/bin/env python2.7 # -*- coding: utf-8 -*- import os import ldap import ldap.sasl import sys import smtplib from email.mime.text import MIMEText server_init_file = '/etc/init.d/httpd' apache_config_dir = '/etc/httpd/conf.d/subversion.d/' repo_path = '/opt/svn/repo/' user_owner_repo = 'apache' group_owner_repo = 'apache' mail_server = 'mail.company.ru' mail_smtp_port = 25 mail_from = 'redmine@company.ru' list_mail = [ ] root_svn_url = 'http://svn.company.ru/' if len(sys.argv)<=2: print u"   " print u"           " print u": addsvnrepo example_repo example_group" sys.exit() server = 'ldap://ldap' user_id = 'ldpcat' pw = '12345678' dn_search = 'OU=User,DC=company,DC=ru' repo_name = sys.argv[1] group_commit = sys.argv[2] if repo_name != None: print "  "+repo_name else: sys.exit() def main(): try: con = ldap.initialize(server) con.set_option(ldap.OPT_REFERRALS, 0) con.simple_bind_s(user_id, pw) print ' ' except ldap.INVALID_CREDENTIALS: print "    " sys.exit() except ldap.LDAPError, e: if type(e.message) == dict and e.message.has_key('desc'): print 'Error - ' + e.message['desc'] else: print 'Error - ' + str(e) sys.exit() finally: print '' search(con, group_commit) repo_create() config_write() server_reload() mailer() def search(con, group_commit): try: base_dn = 'dc=company,dc=ru' filter = "(memberOf=CN="+group_commit+","+dn_search+")" attrs = ['mail'] timeout = 3 results = con.search_s(base_dn, ldap.SCOPE_SUBTREE, filter, attrs) for dn,entry in results: if dn != None: list_mail.extend(entry['mail']) con.unbind() print list_mail print u" " except ldap.LDAPError, e: print 'Error - ' + str(e) sys.exit() def mailer(): text = u' ' text2 = repo_name text3 = u' .\n    ' text4 = root_svn_url+repo_name text5 = u'/\n  !\n' text_s = text+text2+text3+text4+text5 subj = u'  '+repo_name msg = MIMEText(text_s, "", "cp1251") msg['Subject'] = subj msg['From'] = mail_from msg['To'] = ', '.join( list_mail ) print u"  " print msg['To'] s = smtplib.SMTP(mail_server, mail_smtp_port) s.sendmail(msg['From'], list_mail, msg.as_string()) s.quit() print u"...." def repo_create(): svnadmin_create_msg = result = os.popen("svnadmin create "+repo_path+repo_name).read() print svnadmin_create_msg chmod_msg = result = os.popen("chown -R "+user_owner_repo+":"+group_owner_repo+" "+repo_path+repo_name).read() print chmod_msg def config_write(): if os.path.exists(apache_config_dir+repo_name+".conf") : print u"   " sys.exit() else: print "  ......" f1 = open(apache_config_dir+repo_name+".conf", 'w') f = open(apache_config_dir+"skeleton.tpl", 'r') body_config = f.read() f.close() f1.write(body_config.format(repo_name, repo_path, group_commit, server, dn_search)) f1.close() def server_reload(): print u' apache.......' reload_msg = result = os.popen(server_init_file+" restart").read() print reload_msg if __name__=="__main__": main() 


рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╕реЗ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдореИрдВрдиреЗ рдкреНрд░рддреНрдпреЗрдХ рдХреНрд░рд┐рдпрд╛ рдХреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ рдзрдХреЗрд▓ рджрд┐рдпрд╛ред рдореИрдВ рдпрд╣ рдиреЛрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХреЗ рд▓рд┐рдП рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдлрд╝рд╛рдЗрд▓ рдХрдВрдХрд╛рд▓ рд╕реЗ рдмрдирд╛рдИ рдЧрдИ рд╣реИред рдЯреЗрдореНрдкрд▓реЗрдЯ, рдЬрд┐рд╕реЗ /etc/httpd/conf.d/subversion.d рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдХреЗ рдЕрдВрджрд░ рдбрд╛рд▓рдирд╛ рд╣реЛрдЧрд╛ред рдЯреЗрдореНрдкрд▓реЗрдЯ рд╕рд╛рдордЧреНрд░реА
 <Location "/{0}/"> DAV svn SVNPath {1}{0} SVNListParentPath on AuthType Basic AuthName "SVN Server" AuthBasicProvider ldap AuthzLDAPAuthoritative Off AuthLDAPBindDN "cn=ldpcat,cn=users,dc=company,dc=ru" AuthLDAPBindPassword "12345678" AuthLDAPURL {3}/{4}?sAMAccountName?sub?(objectClass=*) AuthBasicAuthoritative off <Limit GET PROPFIND> Require valid-user </Limit> <Limit PROPPATCH DELETE MERGE PUT POST MKCOL MKACTIVITY COPY MOVE LOCK UNLOCK> Require ldap-group cn={2},{4} </Limit> </Location> 


рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╕рдм рдХреБрдЫред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЛ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХреА рдПрдХ рд╕реВрдЪреА рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЬрд┐рд╕рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╡реЗ рдХрд┐рд╕реА рднреА рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рдкреНрд░рд╡реЗрд╢ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рд╡рд╣рд╛рдВ рд╕реЗ рд╡рд╛рдВрдЫрд┐рдд рдлрд╝рд╛рдЗрд▓ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ /etc/httpd/conf.d/subversion.conf рдлрд╛рдЗрд▓ рдореЗрдВ SVNListParentPath рдСрди рдбрд╛рдпрд░реЗрдХреНрдЯрд┐рд╡ рдЬреЛрдбрд╝рдХрд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдХрд┐ рдореЗрдиреВ рд╡рд╛рд▓рд╛ рдкреГрд╖реНрда рдХреЙрд░реНрдкреЛрд░реЗрдЯ рд╢реИрд▓реА рдореЗрдВ рджрд┐рдЦрд╛рдИ рджреЗред рдФрд░ рдлрд┐рд░, рдореИрдВрдиреЗ рдорджрдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдЬрдЧрд░ рдХреЛ рдмреБрд▓рд╛рдпрд╛ред рдкреНрд░рд╛рд░рдВрдн рдореЗрдВ () рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдЖрд░рдВрднреАрдХрд░рдг рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЕрдкрд╛рдЪреЗ /etc/init.d/httpd, рд▓рд╛рдЗрди рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛
/opt/svn/repo/svn_gen > /opt/svn/repo/index.html

рдлрд╝рд╛рдЗрд▓ / рдСрдкреНрдЯ / svn / рд░реЗрдкреЛ / svn_gen
 #!/usr/bin/env python2.7 import os sdir='/opt/svn/repo/' r, d, f = os.walk(sdir).next() lb=len(d) y=0 addrrepo='http://svn.company.ru/' print "<ul>" while y<lb: print "<li>" print "<a href='" print addrrepo+d[y] print "/" print "'" print ">" print d[y] print "</a>" print "<br \>" y=y+1 else: print "</ul>" print "<hr /" print '<h2>PopoWeb Server running on BolgenOS Server 1.6(fundamentally new system of Denis Popov)</ h2>' 

рдпрд╣рд╛рдВ рдореИрдВрдиреЗ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рд╕реАрдПрд╕рдПрд╕ рдХреЗ рд▓рд┐рдВрдХ рд╣рдЯрд╛ рджрд┐рдП рд╣реИрдВ, рддрд╛рдХрд┐ рдореИрдВ рдЙрд╕ рд╕рдВрдЧрдарди рдХреЛ рди рдЫреЛрдбрд╝реВрдВ рдЬрд┐рд╕рдореЗрдВ рдореИрдВ рдХрд╛рдо рдХрд░рддрд╛ рд╣реВрдВ (рд░рдВрдЧ рдмрд╣реБрдд рдкрд╣рдЪрд╛рдирдиреЗ рдпреЛрдЧреНрдп рд╣реИрдВ), рд▓реЗрдХрд┐рди рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рд╕рдордЭрддреЗ рд╣реИрдВ, рдЖрдк рдЕрдкрдиреА рдкрд╕рдВрдж рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдкреГрд╖реНрда рдХреЛ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЖрдк рдЯреЗрдореНрдкрд▓реЗрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рднреА рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд╣рд╛рд▓рд╛рдБрдХрд┐, svn_gen рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдкреЗрди рд╕реЗ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдЬреЛрдбрд╝рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рд╣реА рдердХ рдЧрдИ рдереАред

рдореИрдВ рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдХреНрдпрд╛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛

рдкреБрдирд╢реНрдЪ рд▓рд┐рдкрд┐рдпреЛрдВ рдХреЛ рдЖрд░реНрдХрд╛рдЗрд╡ рдХреЗ рд╕рд╛рде рд▓рд┐рдкрд┐рдпреЛрдВ рдФрд░ рд▓рд┐рдВрдХрдкреНрд▓реЗрдЯ рдХреЗ рд╕рд╛рде рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ
PSS рдХреЛрдб рд╕рд╣реА рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореИрдВ рдХрд┐рд╕реА рднреА рдЯрд┐рдкреНрдкрдгреА рдХреЛ рд╕рд╣рд░реНрд╖ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░реВрдВрдЧрд╛ред

Source: https://habr.com/ru/post/In126338/


All Articles