Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

A different way to solve the automatic deployment of Linux-& gt; windows

2025-01-15 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >

Share

Shulou(Shulou.com)06/02 Report--

Scene:

There is a project that uses a Windows server (running jar packages and .NET code), and how to integrate into the existing automated deployment platform (based on Linux) faces two problems

How to transfer resources from Linux to Windows how to use the program as a background process on windows and separate it from the terminal (cmd or powershell), so as to achieve the effect similar to that achieved by nohup command under Linux?

For question 1, at first I wanted to find a "windows version of sshd" program, but I didn't seem to find a more official one; later I thought that powershell also had a Linux version, and I wanted to transfer files between Linux and Windows through powershell by installing powershell on Linux, and run remote commands. But the Linux version is only powershell core, only the core functions, and powershell online learning materials are too few (complain: including the windows official website for powershell tutorials are only "introduction" to the degree, not enough to learn to use), so I have no choice but to give it up.

For question 2, I think that on Windows, using powershell should be able to try the target effect, but after some research, we only found a way to run commands in the background in powershell, but can not get away from the powershell terminal. Later, I want to "encapsulate" the target process as a windows service, but after some research, I found that it is not so easy to do. So far, I am deeply saddened by Windows.

In addition to "sudden whim", why not use flask to do a small interface program, run on Windows, and automatically deploy the platform to upload jar packages to the target Windows through the http interface (solve problem 1). As for problem 2, it is also in the form of a http interface to start a child process through python's subprocess library. It should be noted that the subprocess.Popen () method has a parameter creationflags=subprocess.CREATE_NO_WINDOW unique to Windows. Through this parameter, the process can run independently of window (cmd or powershell), which is equivalent to the effect of nohup under Linux.

The desired effect is in the CI/CD tool, which updates the code through http requests, such as curl 172.16.1.77:5000/stop?project=we-gatewaycurl-XPUT 172.16.1.77:5000/update-we-gateway-F "file=@ `ls build/libs/* .jar`" curl 172.16.1.77:5000/start?project=we-gateway.

When you need to manually start and stop applications on windows, you can also easily use command-line tools (including flask itself), as follows

PS C:\ deploy\ win_server_manage > python.\ wechat_manager.pyUsage: wechat_manager.py [OPTIONS] COMMAND [ARGS]... Options:-- help Show this message and exit.Commands: start Start the specified APP in background stop Stop the specified APP

Wechat_manager.py relies on click (dependent) for friendly command-line support.

Concrete plan

The flask project directory structure is as follows

Look at the code in turn (not complicated but with necessary comments)

App.py provides flask interface

Import osimport subprocessimport loggingfrom flask import Flask, request, and Responsefrom werkzeug.utils import secure_filenameimport we_manager# output the flask log to the specified file logger = logging.getLogger () file_handler = logging.FileHandler ('Cpurl _ hand _ deployment _ accounting _ management _ account _ out.log' Encoding='UTF-8') logger.addHandler (file_handler) logger.setLevel (logging.DEBUG) app = Flask (_ _ name__) app.config.from_pyfile ('conf.py') def upload_base (project): file = request.files.get (' file') if not file: return'No file had uploaded', 400 if file.filename =': return'No selected file', 400 # return'"project" key not in the post data' 400 filename = secure_filename (file.filename) file.save (os.path.join (app.config ['PROJECTS'] [project], filename)) return' successfully upload {}\ n'.format (filename) # example 1: update the target jar package by upload # because you cannot upload the file and identify the project at the same time Therefore, each project needs to give a separate interface @ app.route ('/ update-we-gateway', methods= ['put',' post']) def upload_gateway (): return upload_base ('we-gateway') # example 2: update step does not need to send a file Directly in the target directory, the git pull code can @ app.route ('/ update-we-server', methods= ['put',' post']) def upload_server (): os.chdir (app.config ['PROJECTS'] [' we-server']) p = subprocess.Popen (['git',' pull'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) Creationflags=subprocess.CREATE_NO_WINDOW) return "STDOUT: {}\ n STDERR: {}" .format (p.stdout.read (). Decode ('gb2312') if p.stdout else None, p.stderr.read (). Decode (' gb2312') if p.stderr else None) @ app.route ('/ stop') def stop (): project = request.values.get ('project') if not project: return' "project" key is necessary in the args' 400 if project not in app.config ['PROJECTS']: return' wrong project name', 400 return we_manager.stop_ (project) @ app.route ('/ start') def start (): project = request.values.get ('project') if not project: return' "project" key is necessary in the args', 400 if project not in app.config ['PROJECTS']: return' wrong project name', 400 return we_manager.start_ (project)

Conf.py configuration items, mainly the correspondence between the project name and its directory

WIN_IP = '172.16.1.7'PROJECTS = {' we-gateway': 'CWR hand deployable hand deployment,' flask': 'Corel hand deploy hand deployment, windowserverware management'}

The main logic for wechat_manager.py to start and stop a project, referenced by app.py

Import osimport subprocessimport globimport shleximport confdef start_ (name): os.chdir (conf.projects [name]) if name = = 'flask': # flask as a resident process, cannot use (stdout=subprocess.PIPE, stderr=subprocess.STDOUT) and stdout.read () to try to get standard output, it will block # when there is (stdout=subprocess.PIPE, stderr=subprocess.STDOUT), you must use the following sentence to get the output before you can really start flask Stdout = p.stdout.read (). Decode ('gb2312') if p.stdout else None # # if you have this sentence here, you can start and block console. The output of # flask that does not block console but does not actually start is defined internally by flask p = subprocess.Popen (shlex.split ("flask run-- host localhost") Creationflags=subprocess.CREATE_NO_WINDOW) else: try: jarfile = glob.glob ('* {} * .jar '.format (name)) [0] except: print ("Can't find a valid jarfile") return # powershell out-file is equivalent to > # subcommands starting with powershell.exe/cmd.exe in Linux the pid recorded should be powershell/cmd A pid such as direct kill cannot kill the java process # but because there is no processing output within the jar package, if python does not capture the subcommand output, it will not be able to get the output, but if it is captured Blocks the python process (because the output of the resident memory process is "endless") p = subprocess.Popen (shlex.split ("java-jar {}" .format (jarfile)) with open ('{} / pid.txt'.format (conf.PROJECTS [name]),'w') as f: f.write (str (p.pid)) print ('start {}, pid {} stored in pid.txt.'.format (name) P.pid)) return 'start {}, pid {} stored in pid.txt.'.format (name, p.pid) def stop_ (name): os.chdir (conf.PROJECTS [name]) res = [] with open (' {} / pid.txt'.format (conf.PROJECTS [name])) as f: pid = f.read () p = subprocess.Popen (['powershell.exe',' kill', pid], stdout=subprocess.PIPE Stderr=subprocess.STDOUT) res.append (p.stdout.read (). Decode ('gb2312') if p.stdout else None) res.append (p.stderr.read (). Decode (' gb2312') if p.stderr else None) p.wait (10) try: os.remove ('{} / pid.txt'.format (conf.PROJECTS [name]) except FileNotFoundError: pass print ('Stop {}, pid.txt removed.\ n {}' .format (name) Res) return 'Stop {}, pid.txt removed.\ n {}' .format (name, res) if _ _ name__ = ='_ _ main__': import click @ click.group () def cli (): pass @ click.command () @ click.argument ('name' Required=True) def start (name): "Start the specified APP in background" if name not in conf.PROJECTS: click.echo ('Wrong name of app') return # p = Process (target=start_, args= (name,)) # p.start () # unnecessary start_ (name) @ click.command () @ click.argument (' name' Required=True) def stop (name): "Stop the specified APP" if name not in conf.PROJECTS: click.echo ('Wrong name of app') return stop_ (name) cli.add_command (start) cli.add_command (stop) cli ()

Finally, I hope to provide some inspiration and help for the partners who have been devastated by Windows.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Servers

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report