fix agent update, new agent 0.11.1
This commit is contained in:
@@ -145,6 +145,62 @@ def install_updates():
|
||||
return __salt__["cmd.run_bg"]([TAC_RMM, "-m", "winupdater"])
|
||||
|
||||
|
||||
def agent_update_v2(inno, url):
|
||||
# make sure another instance of the update is not running
|
||||
# this function spawns 2 instances of itself (because we call it twice with salt run_bg)
|
||||
# so if more than 2 running, don't continue as an update is already running
|
||||
count = 0
|
||||
for p in psutil.process_iter():
|
||||
try:
|
||||
with p.oneshot():
|
||||
if "win_agent.agent_update_v2" in p.cmdline():
|
||||
count += 1
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
if count > 2:
|
||||
return "already running"
|
||||
|
||||
sleep(random.randint(1, 20)) # don't flood the rmm
|
||||
|
||||
exe = os.path.join(TEMP_DIR, inno)
|
||||
|
||||
if os.path.exists(exe):
|
||||
try:
|
||||
os.remove(exe)
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
r = requests.get(url, stream=True, timeout=600)
|
||||
except Exception:
|
||||
return "failed"
|
||||
|
||||
if r.status_code != 200:
|
||||
return "failed"
|
||||
|
||||
with open(exe, "wb") as f:
|
||||
for chunk in r.iter_content(chunk_size=1024):
|
||||
if chunk:
|
||||
f.write(chunk)
|
||||
del r
|
||||
|
||||
ret = subprocess.run([exe, "/VERYSILENT", "/SUPPRESSMSGBOXES"], timeout=90)
|
||||
return "ok"
|
||||
|
||||
|
||||
def do_agent_update_v2(inno, url):
|
||||
return __salt__["cmd.run_bg"](
|
||||
[
|
||||
SALT_CALL,
|
||||
"win_agent.agent_update_v2",
|
||||
f"inno={inno}",
|
||||
f"url={url}",
|
||||
"--local",
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
def agent_update(version, url):
|
||||
# make sure another instance of the update is not running
|
||||
# this function spawns 2 instances of itself so if more than 2 running,
|
||||
|
||||
@@ -19,48 +19,38 @@ logger.configure(**settings.LOG_CONFIG)
|
||||
@app.task
|
||||
def send_agent_update_task(pks, version):
|
||||
assert isinstance(pks, list)
|
||||
ver = version.split("winagent-v")[1]
|
||||
q = Agent.objects.only("pk").filter(pk__in=pks)
|
||||
|
||||
agents = [
|
||||
i
|
||||
for i in q
|
||||
if pyver.parse(i.version) < pyver.parse(ver) and i.status == "online"
|
||||
]
|
||||
q = Agent.objects.filter(pk__in=pks)
|
||||
agents = [i.pk for i in q if pyver.parse(i.version) < pyver.parse(version)]
|
||||
|
||||
if agents:
|
||||
for agent in agents:
|
||||
agent.update_pending = True
|
||||
agent.save(update_fields=["update_pending"])
|
||||
chunks = (agents[i : i + 30] for i in range(0, len(agents), 30))
|
||||
|
||||
minions = [i.salt_id for i in agents]
|
||||
for chunk in chunks:
|
||||
for pk in chunk:
|
||||
agent = Agent.objects.get(pk=pk)
|
||||
if agent.operating_system is not None:
|
||||
if "64bit" in agent.operating_system:
|
||||
arch = "64"
|
||||
elif "32bit" in agent.operating_system:
|
||||
arch = "32"
|
||||
else:
|
||||
arch = "64"
|
||||
|
||||
r = Agent.get_github_versions()
|
||||
git_versions = r["versions"]
|
||||
data = r["data"] # full response from github
|
||||
versions = {}
|
||||
url = settings.DL_64 if arch == "64" else settings.DL_32
|
||||
inno = (
|
||||
f"winagent-v{version}.exe"
|
||||
if arch == "64"
|
||||
else f"winagent-v{version}-x86.exe"
|
||||
)
|
||||
|
||||
for i, release in enumerate(data):
|
||||
versions[i] = release["name"]
|
||||
|
||||
key = [k for k, v in versions.items() if v == version][0]
|
||||
|
||||
# download_url = data[key]["assets"][1]["browser_download_url"]
|
||||
|
||||
# emergency patch for now until fix tomorrow, otherwise all 64 bit agents
|
||||
# will get 32 bit agents and crash
|
||||
download_url = "https://github.com/wh1te909/winagent/releases/download/v0.11.0/winagent-v0.11.0.exe"
|
||||
|
||||
# split into chunks to not overload salt
|
||||
chunks = (minions[i : i + 30] for i in range(0, len(minions), 30))
|
||||
|
||||
for chunk in chunks:
|
||||
r = Agent.salt_batch_async(
|
||||
minions=chunk,
|
||||
func="win_agent.do_agent_update",
|
||||
kwargs={"version": ver, "url": download_url},
|
||||
)
|
||||
sleep(5)
|
||||
r = agent.salt_api_async(
|
||||
func="win_agent.do_agent_update_v2",
|
||||
kwargs={
|
||||
"inno": inno,
|
||||
"url": url,
|
||||
},
|
||||
)
|
||||
sleep(10)
|
||||
|
||||
|
||||
@app.task
|
||||
|
||||
@@ -46,11 +46,9 @@ logger.configure(**settings.LOG_CONFIG)
|
||||
@api_view()
|
||||
def get_agent_versions(request):
|
||||
agents = Agent.objects.only("pk")
|
||||
ret = Agent.get_github_versions()
|
||||
return Response(
|
||||
{
|
||||
"versions": ret["versions"],
|
||||
"github": ret["data"],
|
||||
"versions": [settings.LATEST_AGENT_VER],
|
||||
"agents": AgentHostnameSerializer(agents, many=True).data,
|
||||
}
|
||||
)
|
||||
@@ -325,9 +323,7 @@ def install_agent(request):
|
||||
inno = (
|
||||
f"winagent-v{version}.exe" if arch == "64" else f"winagent-v{version}-x86.exe"
|
||||
)
|
||||
download_url = (
|
||||
f"https://github.com/wh1te909/winagent/releases/download/v{version}/{inno}"
|
||||
)
|
||||
download_url = settings.DL_64 if arch == "64" else settings.DL_32
|
||||
|
||||
_, token = AuthToken.objects.create(
|
||||
user=request.user, expiry=dt.timedelta(hours=request.data["expires"])
|
||||
|
||||
@@ -59,26 +59,13 @@ func main() {
|
||||
localMesh := flag.String("local-mesh", "", "Use local mesh agent")
|
||||
flag.Parse()
|
||||
|
||||
var debug bool = false
|
||||
|
||||
if strings.TrimSpace(*debugLog) == "DEBUG" {
|
||||
debug = true
|
||||
}
|
||||
|
||||
agentBinary := filepath.Join(os.Getenv("windir"), "Temp", Inno)
|
||||
|
||||
fmt.Println("Downloading agent...")
|
||||
dl := downloadAgent(agentBinary)
|
||||
if dl != nil {
|
||||
fmt.Println("ERROR: unable to download agent from", DownloadUrl)
|
||||
fmt.Println(dl)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
fmt.Println("Extracting files...")
|
||||
winagentCmd := exec.Command(agentBinary, "/VERYSILENT", "/SUPPRESSMSGBOXES")
|
||||
err := winagentCmd.Run()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
time.Sleep(20 * time.Second)
|
||||
|
||||
tacrmm := filepath.Join(os.Getenv("PROGRAMFILES"), "TacticalAgent", "tacticalrmm.exe")
|
||||
|
||||
cmdArgs := []string{
|
||||
@@ -88,7 +75,7 @@ func main() {
|
||||
"--auth", Token,
|
||||
}
|
||||
|
||||
if strings.TrimSpace(*debugLog) == "DEBUG" {
|
||||
if debug {
|
||||
cmdArgs = append(cmdArgs, "--log", "DEBUG")
|
||||
}
|
||||
|
||||
@@ -112,6 +99,31 @@ func main() {
|
||||
cmdArgs = append(cmdArgs, "--power")
|
||||
}
|
||||
|
||||
if debug {
|
||||
fmt.Println("Installer:", agentBinary)
|
||||
fmt.Println("Tactical Agent:", tacrmm)
|
||||
fmt.Println("Download URL:", DownloadUrl)
|
||||
fmt.Println("Install command:", "cmd.exe", strings.Join(cmdArgs, " "))
|
||||
}
|
||||
|
||||
fmt.Println("Downloading agent...")
|
||||
dl := downloadAgent(agentBinary)
|
||||
if dl != nil {
|
||||
fmt.Println("ERROR: unable to download agent from", DownloadUrl)
|
||||
fmt.Println(dl)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
fmt.Println("Extracting files...")
|
||||
winagentCmd := exec.Command(agentBinary, "/VERYSILENT", "/SUPPRESSMSGBOXES")
|
||||
err := winagentCmd.Run()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
time.Sleep(20 * time.Second)
|
||||
|
||||
fmt.Println("Installation starting.")
|
||||
cmd := exec.Command("cmd.exe", cmdArgs...)
|
||||
|
||||
|
||||
@@ -11,12 +11,15 @@ AUTH_USER_MODEL = "accounts.User"
|
||||
|
||||
# bump this version everytime vue code is changed
|
||||
# to alert user they need to manually refresh their browser
|
||||
APP_VER = "0.0.47"
|
||||
APP_VER = "0.0.48"
|
||||
|
||||
# https://github.com/wh1te909/salt
|
||||
LATEST_SALT_VER = "1.1.0"
|
||||
|
||||
LATEST_AGENT_VER = "0.11.0"
|
||||
LATEST_AGENT_VER = "0.11.1"
|
||||
|
||||
DL_64 = f"https://github.com/wh1te909/winagent/releases/download/v{LATEST_AGENT_VER}/winagent-v{LATEST_AGENT_VER}.exe"
|
||||
DL_32 = f"https://github.com/wh1te909/winagent/releases/download/v{LATEST_AGENT_VER}/winagent-v{LATEST_AGENT_VER}-x86.exe"
|
||||
|
||||
try:
|
||||
from .local_settings import *
|
||||
|
||||
@@ -10,14 +10,7 @@
|
||||
<q-separator />
|
||||
<q-card-section>
|
||||
Select Version
|
||||
<q-select
|
||||
square
|
||||
dense
|
||||
options-dense
|
||||
outlined
|
||||
v-model="version"
|
||||
:options="Object.values(versions)"
|
||||
/>
|
||||
<q-select square disable dense options-dense outlined v-model="version" :options="versions" />
|
||||
</q-card-section>
|
||||
<q-card-section v-show="version !== null">
|
||||
Select Agent
|
||||
@@ -41,7 +34,7 @@ export default {
|
||||
mixins: [mixins],
|
||||
data() {
|
||||
return {
|
||||
versions: {},
|
||||
versions: [],
|
||||
version: null,
|
||||
agents: [],
|
||||
group: [],
|
||||
@@ -58,6 +51,7 @@ export default {
|
||||
.get("/agents/getagentversions/")
|
||||
.then(r => {
|
||||
this.versions = r.data.versions;
|
||||
this.version = r.data.versions[0];
|
||||
this.agents = r.data.agents;
|
||||
this.$q.loading.hide();
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user